import { useState, useEffect } from 'react'; import { Globe, Mail, Check, X, ExternalLink, Loader2, Inbox, Calendar, Trash2 } from 'lucide-react'; import api from '../services/api'; import { useLanguage } from '../contexts/LanguageContext'; import toast from 'react-hot-toast'; export default function FederationInbox() { const { t } = useLanguage(); const [invitations, setInvitations] = useState([]); const [calendarInvitations, setCalendarInvitations] = useState([]); const [localCalInvitations, setLocalCalInvitations] = useState([]); const [loading, setLoading] = useState(true); const fetchInvitations = async () => { try { const [roomRes, calRes, localCalRes] = await Promise.all([ api.get('/federation/invitations'), api.get('/federation/calendar-invitations').catch(() => ({ data: { invitations: [] } })), api.get('/calendar/local-invitations').catch(() => ({ data: { invitations: [] } })), ]); setInvitations(roomRes.data.invitations || []); setCalendarInvitations(calRes.data.invitations || []); setLocalCalInvitations(localCalRes.data.invitations || []); } catch { toast.error(t('federation.loadFailed')); } finally { setLoading(false); } }; useEffect(() => { fetchInvitations(); }, []); // ── Room invitation actions ────────────────────────────────────────────── const handleAccept = async (id) => { try { await api.post(`/federation/invitations/${id}/accept`); toast.success(t('federation.acceptedSaved')); fetchInvitations(); } catch { toast.error(t('federation.acceptFailed')); } }; const handleDecline = async (id) => { try { await api.delete(`/federation/invitations/${id}`); toast.success(t('federation.declined')); fetchInvitations(); } catch { toast.error(t('federation.declineFailed')); } }; const handleDeleteInvitation = async (id) => { try { await api.delete(`/federation/invitations/${id}`); toast.success(t('federation.invitationRemoved')); fetchInvitations(); } catch { toast.error(t('federation.declineFailed')); } }; // ── Calendar invitation actions ────────────────────────────────────────── const handleCalAccept = async (id) => { try { await api.post(`/federation/calendar-invitations/${id}/accept`); toast.success(t('federation.calendarAccepted')); fetchInvitations(); } catch { toast.error(t('federation.acceptFailed')); } }; const handleCalDecline = async (id) => { try { await api.delete(`/federation/calendar-invitations/${id}`); toast.success(t('federation.declined')); fetchInvitations(); } catch { toast.error(t('federation.declineFailed')); } }; const handleCalDelete = async (id) => { try { await api.delete(`/federation/calendar-invitations/${id}`); toast.success(t('federation.invitationRemoved')); fetchInvitations(); } catch { toast.error(t('federation.declineFailed')); } }; // ── Local calendar invitation actions ─────────────────────────────────── const handleLocalCalAccept = async (id) => { try { await api.post(`/calendar/local-invitations/${id}/accept`); toast.success(t('federation.calendarLocalAccepted')); fetchInvitations(); } catch { toast.error(t('federation.acceptFailed')); } }; const handleLocalCalDecline = async (id) => { try { await api.delete(`/calendar/local-invitations/${id}`); toast.success(t('federation.declined')); fetchInvitations(); } catch { toast.error(t('federation.declineFailed')); } }; const handleLocalCalDelete = async (id) => { try { await api.delete(`/calendar/local-invitations/${id}`); toast.success(t('federation.invitationRemoved')); fetchInvitations(); } catch { toast.error(t('federation.declineFailed')); } }; if (loading) { return (
); } const pendingRooms = invitations.filter(i => i.status === 'pending'); const pastRooms = invitations.filter(i => i.status !== 'pending'); const pendingCal = calendarInvitations.filter(i => i.status === 'pending'); const pastCal = calendarInvitations.filter(i => i.status !== 'pending'); const pendingLocalCal = localCalInvitations.filter(i => i.status === 'pending'); const pastLocalCal = localCalInvitations.filter(i => i.status !== 'pending'); const totalPending = pendingRooms.length + pendingCal.length + pendingLocalCal.length; const totalPast = pastRooms.length + pastCal.length + pastLocalCal.length; return (
{/* Header */}

{t('federation.inbox')}

{t('federation.inboxSubtitle')}

{/* Pending invitations */} {totalPending > 0 && (

{t('federation.pending')} ({totalPending})

{/* Pending room invitations */} {pendingRooms.map(inv => (

{inv.room_name}

{t('federation.from')}: {inv.from_user}

{inv.message && (

"{inv.message}"

)}

{new Date(inv.created_at).toLocaleString()}

))} {/* Pending calendar invitations */} {pendingCal.map(inv => (
{t('federation.calendarEvent')}

{inv.title}

{t('federation.from')}: {inv.from_user}

{new Date(inv.start_time).toLocaleString()} - {new Date(inv.end_time).toLocaleString()}

{inv.description && (

"{inv.description}"

)}

{new Date(inv.created_at).toLocaleString()}

))} {/* Pending local calendar invitations */} {pendingLocalCal.map(inv => (
{t('federation.localCalendarEvent')}

{inv.title}

{t('federation.from')}: {inv.from_name}

{new Date(inv.start_time).toLocaleString()} - {new Date(inv.end_time).toLocaleString()}

{inv.description && (

"{inv.description}"

)}

{new Date(inv.created_at).toLocaleString()}

))}
)} {/* Past invitations */} {totalPast > 0 && (

{t('federation.previousInvites')}

{/* Past room invitations */} {pastRooms.map(inv => (

{inv.room_name}

{inv.from_user}

{inv.status === 'accepted' ? t('federation.statusAccepted') : t('federation.statusDeclined')} {inv.status === 'accepted' && ( )}
))} {/* Past calendar invitations */} {pastCal.map(inv => (

{inv.title}

{inv.from_user} · {new Date(inv.start_time).toLocaleDateString()}

{inv.status === 'accepted' ? t('federation.statusAccepted') : t('federation.statusDeclined')} {inv.status === 'accepted' && inv.join_url && ( )}
))} {/* Past local calendar invitations */} {pastLocalCal.map(inv => (

{inv.title}

{inv.from_name} · {new Date(inv.start_time).toLocaleDateString()}

{inv.status === 'accepted' ? t('federation.statusAccepted') : t('federation.statusDeclined')}
))}
)} {/* Empty state */} {totalPending === 0 && totalPast === 0 && (

{t('federation.noInvitations')}

{t('federation.noInvitationsSubtitle')}

)}
); }