← back to Dw Boardroom V2
frontend/src/components/LiveFeed.tsx
78 lines
import { useEffect, useRef } from 'react';
import type { MeetingMessage } from '../types';
const TYPE_COLORS: Record<string, string> = {
dialogue: '#e8eaf0',
phase: '#8b5cf6',
system: '#7a7f96',
action: '#f59e0b',
decision: '#22c55e',
};
interface Props {
messages: MeetingMessage[];
meetingActive: boolean;
}
export default function LiveFeed({ messages, meetingActive }: Props) {
const feedRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (feedRef.current) {
feedRef.current.scrollTop = feedRef.current.scrollHeight;
}
}, [messages]);
return (
<div style={styles.card}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 10 }}>
<h3 style={{ margin: 0, fontSize: 14, fontWeight: 700 }}>Live Feed</h3>
<span style={{ fontSize: 11, color: '#7a7f96' }}>
{messages.length} message{messages.length !== 1 ? 's' : ''}
</span>
</div>
<div ref={feedRef} style={styles.feed}>
{messages.length === 0 && (
<div style={styles.empty}>
{meetingActive ? 'Waiting for dialogue...' : 'No active meeting. Start one above.'}
</div>
)}
{messages.map((msg) => (
<div key={msg.id} style={styles.message}>
<div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 2 }}>
<span style={{ fontWeight: 700, fontSize: 12, color: TYPE_COLORS[msg.message_type] || '#e8eaf0' }}>
{msg.agent_name}
</span>
{msg.message_type !== 'dialogue' && (
<span style={{
padding: '1px 6px', borderRadius: 3, fontSize: 9, fontWeight: 600,
background: (TYPE_COLORS[msg.message_type] || '#7a7f96') + '22',
color: TYPE_COLORS[msg.message_type] || '#7a7f96',
}}>
{msg.message_type}
</span>
)}
<span style={{ fontSize: 9, color: '#555', marginLeft: 'auto' }}>
{msg.phase}
</span>
</div>
<div style={{ fontSize: 12, color: '#b0b3c0', lineHeight: 1.5 }}>{msg.message}</div>
</div>
))}
</div>
</div>
);
}
const styles: Record<string, React.CSSProperties> = {
card: { background: '#1a1a2e', borderRadius: 12, padding: 16, border: '1px solid #252540' },
feed: {
maxHeight: 500, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: 8,
},
message: {
padding: '8px 12px', background: '#12121f', borderRadius: 8, borderLeft: '3px solid #252540',
},
empty: { color: '#7a7f96', fontSize: 13, textAlign: 'center' as const, padding: 40 },
};