diff --git a/frontend/app/admin/announcements/page.tsx b/frontend/app/admin/announcements/page.tsx new file mode 100644 index 00000000..9e725210 --- /dev/null +++ b/frontend/app/admin/announcements/page.tsx @@ -0,0 +1,105 @@ +"use client"; + +import { useState } from "react"; +import DashboardLayout from "@/components/dashboard/DashboardLayout"; +import { useGetAnnouncements } from "@/lib/react-query/hooks/admin/announcements/useGetAnnouncements"; +import { useSendAnnouncement } from "@/lib/react-query/hooks/admin/announcements/useSendAnnouncement"; +import { Megaphone, Plus, X } from "lucide-react"; + +const AUDIENCES = ["ALL_MEMBERS", "ACTIVE_MEMBERS", "STAFF"]; +const CHANNELS = ["IN_APP", "EMAIL", "BOTH"]; + +export default function AdminAnnouncementsPage() { + const [showModal, setShowModal] = useState(false); + const [form, setForm] = useState({ title: "", content: "", audience: "ALL_MEMBERS", channel: "IN_APP" }); + + const { data, isLoading } = useGetAnnouncements(); + const send = useSendAnnouncement(); + const announcements = (data as any)?.items ?? (data as any)?.data ?? []; + + const handleSend = async (e: React.FormEvent) => { + e.preventDefault(); + await send.mutateAsync({ title: form.title, content: form.content }); + setShowModal(false); + setForm({ title: "", content: "", audience: "ALL_MEMBERS", channel: "IN_APP" }); + }; + + return ( + +
+
+

Announcements

+

Broadcast messages to member segments.

+
+ +
+ + {isLoading ? ( +
Loading...
+ ) : (Array.isArray(announcements) ? announcements : []).length === 0 ? ( +
+ +

No announcements yet.

+
+ ) : ( +
+ {(Array.isArray(announcements) ? announcements : []).map((ann: any) => ( +
+
+
+

{ann.title}

+

{ann.content}

+
+ {new Date(ann.createdAt).toLocaleDateString()} +
+
+ ))} +
+ )} + + {showModal && ( +
+
+
+

New Announcement

+ +
+
+
+ + setForm({ ...form, title: e.target.value })} required className="w-full border border-gray-200 rounded-lg px-3 py-2 text-sm" /> +
+
+ + +
+
+ + +
+
+ +