feat(08-03): create JKSessionChatButton with unread badge
- Displays chat icon from assets - Badge shows unread count (1-99) or "99+" for 100+ - Badge hidden when count = 0 - Reduced opacity when window already open - Click handler opens chat window and sets active channel - useCallback for handleClick optimization
This commit is contained in:
parent
6b687315ce
commit
1230448d96
|
|
@ -0,0 +1,78 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import {
|
||||
openChatWindow,
|
||||
setActiveChannel,
|
||||
selectTotalUnreadCount,
|
||||
selectIsChatWindowOpen
|
||||
} from '../../store/features/sessionChatSlice';
|
||||
import chatIcon from '../../assets/img/client/chat.svg';
|
||||
|
||||
const JKSessionChatButton = ({ sessionId }) => {
|
||||
const dispatch = useDispatch();
|
||||
const unreadCount = useSelector(selectTotalUnreadCount);
|
||||
const isWindowOpen = useSelector(selectIsChatWindowOpen);
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
if (isWindowOpen) {
|
||||
// Window already open - do nothing (or focus window if possible)
|
||||
return;
|
||||
}
|
||||
|
||||
// Set active channel to session chat
|
||||
dispatch(setActiveChannel({
|
||||
channel: sessionId,
|
||||
channelType: 'session'
|
||||
}));
|
||||
|
||||
// Open chat window
|
||||
dispatch(openChatWindow());
|
||||
}, [dispatch, sessionId, isWindowOpen]);
|
||||
|
||||
// Format badge text
|
||||
const getBadgeText = () => {
|
||||
if (unreadCount === 0) return '';
|
||||
if (unreadCount >= 100) return '99+';
|
||||
return String(unreadCount);
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ position: 'relative', display: 'inline-block' }}>
|
||||
<img
|
||||
src={chatIcon}
|
||||
alt="Chat"
|
||||
onClick={handleClick}
|
||||
style={{
|
||||
cursor: 'pointer',
|
||||
width: '24px',
|
||||
height: '24px',
|
||||
opacity: isWindowOpen ? 0.6 : 1
|
||||
}}
|
||||
title="Open session chat"
|
||||
/>
|
||||
{unreadCount > 0 && (
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '-6px',
|
||||
right: '-6px',
|
||||
backgroundColor: '#dc3545', // Bootstrap danger red
|
||||
color: 'white',
|
||||
borderRadius: '10px',
|
||||
padding: '2px 6px',
|
||||
fontSize: '11px',
|
||||
fontWeight: 'bold',
|
||||
lineHeight: '1',
|
||||
minWidth: '18px',
|
||||
textAlign: 'center',
|
||||
boxShadow: '0 1px 3px rgba(0,0,0,0.3)'
|
||||
}}
|
||||
>
|
||||
{getBadgeText()}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default JKSessionChatButton;
|
||||
Loading…
Reference in New Issue