"use client"; import { Bell, BellOff, ExternalLink, Info, type Megaphone, Rocket, Wrench, Zap, } from "lucide-react"; import Link from "next/link"; import { useEffect } from "react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from "@/components/ui/card"; import type { AnnouncementCategory } from "@/contracts/types/announcement.types"; import { type AnnouncementWithState, useAnnouncements } from "@/hooks/use-announcements"; import { formatRelativeDate } from "@/lib/format-date"; // --------------------------------------------------------------------------- // Category configuration // --------------------------------------------------------------------------- const categoryConfig: Record< AnnouncementCategory, { label: string; icon: typeof Megaphone; color: string; badgeVariant: "default" | "secondary" | "destructive" | "outline"; } > = { feature: { label: "Feature", icon: Rocket, color: "text-emerald-500", badgeVariant: "default", }, update: { label: "Update", icon: Zap, color: "text-blue-500", badgeVariant: "secondary", }, maintenance: { label: "Maintenance", icon: Wrench, color: "text-amber-500", badgeVariant: "outline", }, info: { label: "Info", icon: Info, color: "text-muted-foreground", badgeVariant: "secondary", }, }; // --------------------------------------------------------------------------- // Announcement card // --------------------------------------------------------------------------- function AnnouncementCard({ announcement, }: { announcement: AnnouncementWithState; }) { const config = categoryConfig[announcement.category] ?? categoryConfig.info; const Icon = config.icon; return (
{announcement.title} {config.label} {announcement.isImportant && ( Important )}
{formatRelativeDate(announcement.date)}

{announcement.description}

{announcement.link && ( )}
); } // --------------------------------------------------------------------------- // Empty state // --------------------------------------------------------------------------- function EmptyState() { return (

No announcements

You're all caught up! New announcements will appear here.

); } // --------------------------------------------------------------------------- // Page // --------------------------------------------------------------------------- export default function AnnouncementsPage() { const { announcements, markAllRead } = useAnnouncements(); // Auto-mark all visible announcements as read when the page is opened useEffect(() => { markAllRead(); }, [markAllRead]); return (
{/* Header */}

Announcements

{/* Content */}
{announcements.length === 0 ? ( ) : (
{announcements.map((announcement) => ( ))}
)}
); }