import React, { useState, useEffect } from 'react'; import { supabase } from '../supabase'; import { Announcement } from '../types'; const FacultyNotifications: React.FC = () => { const [announcements, setAnnouncements] = useState([]); const [isLoading, setIsLoading] = useState(true); const [now, setNow] = useState(new Date()); useEffect(() => { const timer = setInterval(() => setNow(new Date()), 30000); return () => clearInterval(timer); }, []); // Fetch announcements directly from Supabase — no prop dependency useEffect(() => { const fetchAnnouncements = async () => { setIsLoading(true); const { data, error } = await supabase .from('announcements') .select('*') .order('timestamp', { ascending: false }); if (data && !error) { setAnnouncements(data.map(ann => ({ id: String(ann.id), title: ann.title, message: ann.message, type: ann.type, eventId: ann.event_id ? String(ann.event_id) : undefined, timestamp: ann.timestamp || ann.created_at || new Date().toISOString(), expiresAt: ann.expires_at }))); } setIsLoading(false); }; fetchAnnouncements(); // Subscribe to realtime changes on announcements const channel = supabase .channel('announcements-faculty') .on('postgres_changes', { event: '*', schema: 'public', table: 'announcements' }, () => { fetchAnnouncements(); }) .subscribe(); return () => { supabase.removeChannel(channel); }; }, []); const getTypeIcon = (type: string) => { switch (type) { case 'URGENT': return 'fa-triangle-exclamation text-rose-500'; case 'DELAY': return 'fa-clock text-amber-500'; case 'INFO': return 'fa-info-circle text-blue-500'; case 'ENDED': return 'fa-flag-checkered text-purple-500'; case 'ONGOING': return 'fa-play-circle text-emerald-500'; default: return 'fa-bullhorn text-[#f97316]'; } }; const formatTime = (timestamp: any): string => { if (!timestamp) return 'Now'; try { // Supabase returns ISO strings — parse directly const date = new Date(timestamp); if (isNaN(date.getTime())) return 'Now'; return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); } catch { return 'Now'; } }; const formatDate = (timestamp: any): string => { if (!timestamp) return ''; try { const date = new Date(timestamp); if (isNaN(date.getTime())) return ''; const today = new Date(); const isToday = date.toDateString() === today.toDateString(); if (isToday) return 'Today'; return date.toLocaleDateString([], { day: 'numeric', month: 'short' }); } catch { return ''; } }; const isExpired = (expiresAt: any): boolean => { if (!expiresAt) return false; try { return new Date(expiresAt) < now; } catch { return false; } }; const activeAnnouncements = announcements.filter(ann => !isExpired(ann.expiresAt)); return (

Notice Board

Administrative Updates & Alerts

{isLoading ? (

Syncing Notices...

) : (
{activeAnnouncements.length > 0 ? activeAnnouncements.map((n) => (

{n.title}

{n.message}

{n.type === 'ENDED' ? 'Status: Concluded' : n.type === 'ONGOING' ? 'Status: Live' : `Priority ${n.type === 'URGENT' ? 'Critical' : 'Regular'}`}
{n.expiresAt && (
Temporal Notice
)}
{formatTime(n.timestamp)} {formatDate(n.timestamp)}
)) : (

No active notices

)}
)}
); }; export default FacultyNotifications;