aethex-forge/client/pages/staff/StaffAnnouncements.tsx
2025-11-10 20:15:49 +00:00

283 lines
9.8 KiB
TypeScript

import { useState } from "react";
import Layout from "@/components/Layout";
import SEO from "@/components/SEO";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Bell, Star, Archive, Pin } from "lucide-react";
interface Announcement {
id: string;
title: string;
content: string;
category: string;
author: string;
date: string;
isPinned: boolean;
isArchived: boolean;
priority: "High" | "Normal" | "Low";
}
const announcements: Announcement[] = [
{
id: "1",
title: "Q1 2025 All-Hands Meeting Rescheduled",
content:
"The all-hands meeting has been moved to Friday at 2 PM PST. Please mark your calendars and join us for company updates.",
category: "Company News",
author: "Sarah Chen",
date: "Today",
isPinned: true,
isArchived: false,
priority: "High",
},
{
id: "2",
title: "New Benefits Portal is Live",
content:
"Welcome to our upgraded benefits portal! You can now view and manage your health insurance, retirement plans, and more.",
category: "Benefits",
author: "HR Team",
date: "2 days ago",
isPinned: true,
isArchived: false,
priority: "High",
},
{
id: "3",
title: "Summer Internship Program Open for Applications",
content:
"We're hiring summer interns across all departments. If you know someone talented, send them our way!",
category: "Hiring",
author: "Talent Team",
date: "3 days ago",
isPinned: false,
isArchived: false,
priority: "Normal",
},
{
id: "4",
title: "Server Maintenance Window This Weekend",
content:
"We'll be performing scheduled maintenance on Saturday evening. Services may be temporarily unavailable.",
category: "Technical",
author: "DevOps Team",
date: "4 days ago",
isPinned: false,
isArchived: false,
priority: "Normal",
},
{
id: "5",
title: "Welcome New Team Members!",
content:
"Please join us in welcoming 5 amazing new colleagues who started this week. Check out their profiles in the directory.",
category: "Team",
author: "HR Team",
date: "1 week ago",
isPinned: false,
isArchived: false,
priority: "Low",
},
];
const getPriorityColor = (priority: string) => {
switch (priority) {
case "High":
return "bg-red-500/20 text-red-300 border-red-500/30";
case "Normal":
return "bg-blue-500/20 text-blue-300 border-blue-500/30";
case "Low":
return "bg-slate-500/20 text-slate-300 border-slate-500/30";
default:
return "bg-slate-500/20 text-slate-300";
}
};
const categories = [
"All",
"Company News",
"Benefits",
"Hiring",
"Technical",
"Team",
];
export default function StaffAnnouncements() {
const [selectedCategory, setSelectedCategory] = useState("All");
const [showArchived, setShowArchived] = useState(false);
const filtered = announcements.filter((ann) => {
const matchesCategory =
selectedCategory === "All" || ann.category === selectedCategory;
const matchesArchived = showArchived ? ann.isArchived : !ann.isArchived;
return matchesCategory && matchesArchived;
});
const pinnedAnnouncements = filtered.filter((a) => a.isPinned);
const unpinnedAnnouncements = filtered.filter((a) => !a.isPinned);
return (
<Layout>
<SEO title="Announcements" description="Company news and updates" />
<div className="min-h-screen bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900">
{/* Background effects */}
<div className="absolute inset-0 opacity-30">
<div className="absolute top-20 left-10 w-96 h-96 bg-rose-600 rounded-full mix-blend-multiply filter blur-3xl animate-pulse" />
<div className="absolute bottom-20 right-10 w-96 h-96 bg-pink-600 rounded-full mix-blend-multiply filter blur-3xl animate-pulse" />
</div>
<div className="relative z-10">
{/* Header */}
<div className="container mx-auto max-w-4xl px-4 py-16">
<div className="flex items-center gap-3 mb-6">
<div className="p-3 rounded-lg bg-rose-500/20 border border-rose-500/30">
<Bell className="h-6 w-6 text-rose-400" />
</div>
<div>
<h1 className="text-4xl font-bold text-rose-100">
Announcements
</h1>
<p className="text-rose-200/70">
Company news, updates, and important information
</p>
</div>
</div>
{/* Category Filter */}
<div className="mb-8 space-y-4">
<div className="flex gap-2 flex-wrap">
{categories.map((category) => (
<Button
key={category}
variant={
selectedCategory === category ? "default" : "outline"
}
size="sm"
onClick={() => setSelectedCategory(category)}
className={
selectedCategory === category
? "bg-rose-600 hover:bg-rose-700"
: "border-rose-500/30 text-rose-300 hover:bg-rose-500/10"
}
>
{category}
</Button>
))}
</div>
<Button
variant="outline"
size="sm"
onClick={() => setShowArchived(!showArchived)}
className="border-rose-500/30 text-rose-300 hover:bg-rose-500/10"
>
<Archive className="h-4 w-4 mr-2" />
{showArchived ? "Show Active" : "Show Archived"}
</Button>
</div>
{/* Pinned Announcements */}
{pinnedAnnouncements.length > 0 && (
<div className="mb-12">
<h2 className="text-lg font-semibold text-rose-100 mb-4 flex items-center gap-2">
<Pin className="h-5 w-5" />
Pinned
</h2>
<div className="space-y-4">
{pinnedAnnouncements.map((announcement) => (
<Card
key={announcement.id}
className="bg-slate-800/50 border-rose-500/50 hover:border-rose-400/80 transition-all"
>
<CardHeader>
<div className="flex items-start justify-between">
<div className="flex-1">
<CardTitle className="text-rose-100">
{announcement.title}
</CardTitle>
<CardDescription className="text-slate-400">
by {announcement.author} {announcement.date}
</CardDescription>
</div>
<Badge
className={`border ${getPriorityColor(announcement.priority)}`}
>
{announcement.priority}
</Badge>
</div>
</CardHeader>
<CardContent>
<p className="text-slate-300 mb-3">
{announcement.content}
</p>
<Badge className="bg-slate-700 text-slate-300">
{announcement.category}
</Badge>
</CardContent>
</Card>
))}
</div>
</div>
)}
{/* Regular Announcements */}
{unpinnedAnnouncements.length > 0 && (
<div>
<h2 className="text-lg font-semibold text-rose-100 mb-4">
Recent Announcements
</h2>
<div className="space-y-4">
{unpinnedAnnouncements.map((announcement) => (
<Card
key={announcement.id}
className="bg-slate-800/50 border-slate-700/50 hover:border-rose-500/50 transition-all"
>
<CardHeader>
<div className="flex items-start justify-between">
<div className="flex-1">
<CardTitle className="text-rose-100">
{announcement.title}
</CardTitle>
<CardDescription className="text-slate-400">
by {announcement.author} {announcement.date}
</CardDescription>
</div>
<Badge
className={`border ${getPriorityColor(announcement.priority)}`}
>
{announcement.priority}
</Badge>
</div>
</CardHeader>
<CardContent>
<p className="text-slate-300 mb-3">
{announcement.content}
</p>
<Badge className="bg-slate-700 text-slate-300">
{announcement.category}
</Badge>
</CardContent>
</Card>
))}
</div>
</div>
)}
{filtered.length === 0 && (
<div className="text-center py-12">
<p className="text-slate-400">No announcements found</p>
</div>
)}
</div>
</div>
</div>
</Layout>
);
}