import { useState, useEffect } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { ArrowLeft, Globe, ExternalLink, Trash2, Hash, Users, Video, VideoOff, Loader2, Link2, AlertTriangle, } from 'lucide-react'; import api from '../services/api'; import { useLanguage } from '../contexts/LanguageContext'; import toast from 'react-hot-toast'; export default function FederatedRoomDetail() { const { id } = useParams(); const navigate = useNavigate(); const { t } = useLanguage(); const [room, setRoom] = useState(null); const [loading, setLoading] = useState(true); const [removing, setRemoving] = useState(false); useEffect(() => { const fetch = async () => { try { const res = await api.get('/federation/federated-rooms'); const found = (res.data.rooms || []).find(r => String(r.id) === String(id)); if (!found) { toast.error(t('room.notFound')); navigate('/dashboard'); return; } setRoom(found); } catch { toast.error(t('room.notFound')); navigate('/dashboard'); } finally { setLoading(false); } }; fetch(); }, [id]); const handleJoin = () => { // Validate URL scheme to prevent javascript: or other malicious URIs try { const url = new URL(room.join_url); if (url.protocol !== 'https:' && url.protocol !== 'http:') { toast.error(t('federation.invalidJoinUrl')); return; } window.open(room.join_url, '_blank'); } catch { toast.error(t('federation.invalidJoinUrl')); } }; const handleRemove = async () => { if (!confirm(t('federation.removeRoomConfirm'))) return; setRemoving(true); try { await api.delete(`/federation/federated-rooms/${room.id}`); toast.success(t('federation.roomRemoved')); navigate('/dashboard'); } catch { toast.error(t('federation.roomRemoveFailed')); setRemoving(false); } }; if (loading) { return (
{t('federation.roomDeleted')}
{t('federation.roomDeletedNotice')}
{t('federation.from')}: {room.from_user}
{room.max_participants > 0 ? room.max_participants : '∞'}
{room.max_participants > 0 ? t('federation.participantLimit') : t('federation.unlimited')}
{recordingOn ? t('federation.recordingOn') : t('federation.recordingOff')}
{recordingOn ? t('federation.recordingOnHint') : t('federation.recordingOffHint')}
{t('federation.meetingId')}
{room.meet_id}
{t('federation.joinUrl')}
{room.join_url}
{isDeleted ? t('federation.roomDeletedNotice') : t('federation.readOnlyNotice')}