"use client"; import { useState, useEffect, useCallback } from "react"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Trash2, Eye, AlertTriangle } from "lucide-react"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogFooter, DialogTrigger } from "@/components/ui/dialog"; import { Announcement } from "@/app/types/announcement"; import { useToast } from "@/components/ui/use-toast"; import { useUnreadAnnouncements } from '@/hooks/use-unread-announcements'; interface AnnouncementsListProps { userRole: string[]; } export function AnnouncementsList({ userRole }: AnnouncementsListProps) { const [selectedAnnouncement, setSelectedAnnouncement] = useState(null); const [isViewDialogOpen, setIsViewDialogOpen] = useState(false); const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false); const [error, setError] = useState(null); const { toast } = useToast(); // Use the updated hook which provides announcements data and loading state const { announcements, isLoading: loading, checkForUnreadAnnouncements: fetchAnnouncements, markAsRead } = useUnreadAnnouncements(); useEffect(() => { // Use the fetch function from the hook fetchAnnouncements(); }, [fetchAnnouncements]); // Handle viewing an announcement const handleViewAnnouncement = useCallback((announcement: Announcement) => { setSelectedAnnouncement(announcement); setIsViewDialogOpen(true); // Use setTimeout to separate the state updates setTimeout(() => { markAsRead(announcement.id); }, 0); }, [markAsRead]); // Handle deleting an announcement const handleDeleteClick = useCallback((announcement: Announcement) => { setSelectedAnnouncement(announcement); setIsDeleteDialogOpen(true); }, []); const confirmDelete = useCallback(async () => { if (!selectedAnnouncement) return; try { const response = await fetch(`/api/announcements/${selectedAnnouncement.id}`, { method: 'DELETE', }); if (!response.ok) { throw new Error('Failed to delete announcement'); } // Close dialog first setIsDeleteDialogOpen(false); // Then refresh data using the hook setTimeout(() => { fetchAnnouncements(); }, 0); toast({ title: "Announcement deleted", description: "The announcement has been deleted successfully.", }); } catch (err) { console.error('Error deleting announcement:', err); toast({ title: "Error", description: "Failed to delete the announcement. Please try again.", variant: "destructive", }); } }, [selectedAnnouncement, fetchAnnouncements, toast]); // Format roles for display const formatRoles = useCallback((roles: string[]) => { return roles.map(role => { const roleName = role === "all" ? "All Users" : role.charAt(0).toUpperCase() + role.slice(1); return ( {roleName} ); }); }, []); return (
All Announcements Manage announcements for different user roles
{/* Announcements table with scroll */} {loading ? (
) : error ? (
{error}
) : announcements.length === 0 ? (
No announcements found
) : (
Title Created Author Target Roles Actions {announcements.map((announcement) => ( {announcement.title} {new Date(announcement.createdAt).toLocaleDateString()} {announcement.author.email} {formatRoles(announcement.targetRoles)}
))}
)} {/* View Announcement Dialog */} {selectedAnnouncement?.title} Posted by {selectedAnnouncement?.author.email} on {selectedAnnouncement && new Date(selectedAnnouncement.createdAt).toLocaleDateString()}
Target Audience:{" "} {selectedAnnouncement && formatRoles(selectedAnnouncement.targetRoles)}

{selectedAnnouncement?.content}

{/* Delete Confirmation Dialog */} Confirm Deletion Are you sure you want to delete the announcement "{selectedAnnouncement?.title}"? This action cannot be undone.
); }