import { useEffect, useState, useCallback } from 'react'; import { LocalDB, Group, TranscriptionSegment } from '../lib/localdb'; import { getSegmentsForViewer } from '../lib/localdb'; import { useAuth } from '../contexts/useAuth'; import { useNavigate } from './NavigationHooks'; import { Radio, Users, ArrowLeft } from 'lucide-react'; interface ViewerViewProps { groupId: string; } export function ViewerView({ groupId }: ViewerViewProps) { // Responsive design improvements applied; no unused code remains // Investor Mode state const [investorMode, setInvestorMode] = useState(false); const [supportedPairs, setSupportedPairs] = useState([]); const [backendHealth, setBackendHealth] = useState(''); // Fetch supported pairs and backend health for investor mode useEffect(() => { if (investorMode) { fetch('/models') .then(res => res.json()) .then(data => setSupportedPairs(data.models || [])); fetch('/health') .then(res => res.json()) .then(data => setBackendHealth(data.device || 'unknown')); } }, [investorMode]); // Target language selection removed for reliability // Target language state (persist per viewer) const viewerId = 'viewer_' + (window.navigator.userAgent || 'default'); // Replace with real viewer ID if available const { user } = useAuth(); const navigate = useNavigate(); const [group, setGroup] = useState(null); const [segments, setSegments] = useState([]); const [memberCount, setMemberCount] = useState(0); const [isActive, setIsActive] = useState(true); const loadGroup = useCallback(async () => { const data = LocalDB.getGroupById(groupId); if (data) { setGroup(data); setIsActive(data.is_active); } else { navigate('/'); } }, [groupId, navigate]); const loadSegments = useCallback(async () => { const data = getSegmentsForViewer(groupId, viewerId); setSegments(data); setTimeout(() => { const container = document.getElementById('transcription-container'); if (container) { container.scrollTop = container.scrollHeight; } }, 100); }, [groupId]); const loadMemberCount = useCallback(async () => { setMemberCount(LocalDB.getMemberCount(groupId)); }, [groupId]); useEffect(() => { if (!user) return; loadGroup(); loadSegments(); loadMemberCount(); const unsubSeg = LocalDB.onSegmentsInserted(groupId, (_) => { loadSegments(); setTimeout(() => { const container = document.getElementById('transcription-container'); if (container) { container.scrollTop = container.scrollHeight; } }, 100); }); const unsubGroup = LocalDB.onGroupUpdated(groupId, (updated) => { setGroup(updated); setIsActive(updated.is_active); }); const unsubMembers = LocalDB.onMembersChanged(groupId, () => { loadMemberCount(); }); return () => { unsubSeg(); unsubGroup(); unsubMembers(); }; }, [groupId, user, loadGroup, loadSegments, loadMemberCount]); // ...existing code... const leaveSession = async () => { if (user) { LocalDB.removeMember(groupId, user.id); } navigate('/'); }; if (!group) { return ( <> {/* Branding & Value Proposition Overlay */}
Brand Logo Live Multilingual Demo
Break language barriers instantly in meetings, events, and broadcasts.
{investorMode && (

Investor Pitch Mode

Break language barriers instantly in meetings, events, and broadcasts. Scalable, real-time, multilingual translation for global impact.

Supported Language Pairs:
    {supportedPairs.map(pair => (
  • {pair}
  • ))}
Backend Device: {backendHealth}
Live Analytics:
  • Instant transcription and translation
  • Real-time error handling and retry
  • Mobile & desktop friendly
  • Cloud-ready, scalable backend
Backend is cloud-ready and can scale to millions of users.
)}
); } return (

{group.name}

Viewer Mode

{memberCount}
{isActive ? (
Live
) : (
Ended
)}
{/* Target language selection removed for reliability */}

Live Transcription

{isActive && (
Receiving updates
)}
{segments .slice() .sort((a, b) => a.sequence_number - b.sequence_number) .map((segment) => (

{segment.original_text}

{segment.translated_text === undefined ? (
Processing…
) : segment.translated_text && segment.translated_text !== segment.original_text ? (

{segment.translated_text}

) : (
Translation failed or unavailable.
)} {new Date(segment.created_at).toLocaleTimeString()}
))} {segments.length === 0 && (

Waiting for transcription to start...

The host will begin broadcasting shortly

)}
{!isActive && segments.length > 0 && (

This session has ended

You can still view the transcription above

)}
); }