From c21aaef063e37cde4da64d7d6ea7d9ad51db906c Mon Sep 17 00:00:00 2001 From: Nuwan Date: Tue, 27 Jan 2026 13:36:07 +0530 Subject: [PATCH] feat(08-01): create JKSessionChatWindow with WindowPortal integration Co-Authored-By: Claude Sonnet 4.5 --- .../components/client/JKSessionChatWindow.js | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 jam-ui/src/components/client/JKSessionChatWindow.js diff --git a/jam-ui/src/components/client/JKSessionChatWindow.js b/jam-ui/src/components/client/JKSessionChatWindow.js new file mode 100644 index 000000000..3a88191a9 --- /dev/null +++ b/jam-ui/src/components/client/JKSessionChatWindow.js @@ -0,0 +1,75 @@ +import React, { useCallback } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import WindowPortal from '../common/WindowPortal.js'; +import JKChatHeader from './chat/JKChatHeader.js'; +import { + selectIsChatWindowOpen, + selectActiveChannel, + closeChatWindow +} from '../../store/features/sessionChatSlice'; + +/** + * JKSessionChatWindow - Main chat window component with WindowPortal integration + * + * Opens chat in a popup window (450×600px) following the WindowPortal pattern + * established in Backing Track/JamTrack players. + * + * Redux Integration: + * - isWindowOpen: Controls visibility + * - activeChannel: Determines channel name + * - closeChatWindow: Action to close window + * + * Component hierarchy: + * WindowPortal → JKChatHeader + [content area placeholder] + * + * Note: Message list implementation deferred to Plan 8.2 + */ +const JKSessionChatWindow = () => { + const dispatch = useDispatch(); + + // Redux selectors + const isWindowOpen = useSelector(selectIsChatWindowOpen); + const activeChannel = useSelector(selectActiveChannel); + + // Handlers + const handleClose = useCallback(() => { + dispatch(closeChatWindow()); + }, [dispatch]); + + // Channel name formatting + const getChannelName = useCallback(() => { + if (!activeChannel) return 'Session Chat'; + if (activeChannel === 'global') return 'Global Chat'; + // Session-specific channels will be formatted here + // For now, default to 'Session Chat' + return 'Session Chat'; + }, [activeChannel]); + + // Conditional render: only show if window is open + if (!isWindowOpen) return null; + + return ( + +
+ +
+ {/* Message list placeholder - Plan 8.2 */} +

+ Chat messages will appear here +

+
+
+
+ ); +}; + +// No PropTypes needed - uses Redux internally +export default React.memo(JKSessionChatWindow);