diff --git a/src/app/(user)/notification/page.tsx b/src/app/(user)/notification/page.tsx index 13ae687..fb74212 100644 --- a/src/app/(user)/notification/page.tsx +++ b/src/app/(user)/notification/page.tsx @@ -1,46 +1,114 @@ "use client"; +import { useState } from "react"; +import { useQuery } from "@supabase-cache-helpers/postgrest-react-query"; import { Card, CardContent } from "@/components/ui/card"; import { BellIcon } from "lucide-react"; +import { createSupabaseClient } from "@/lib/supabase/clientComponentClient"; +import { getNotificationByUserId } from "@/lib/data/norificationQuery"; +import { Button } from "@/components/ui/button"; +import { useRouter } from "next/navigation"; +import useSession from "@/lib/supabase/useSession"; +import { LegacyLoader } from "@/components/loading/LegacyLoader"; + +const formatDate = (dateString: string) => { + const date = new Date(dateString); + return new Intl.DateTimeFormat("en-US", { + month: "short", + day: "numeric", + year: "numeric", + hour: "numeric", + minute: "numeric", + hour12: true, + }).format(date); +}; export default function Notification() { - const sampleNotifications = [ - { id: 1, message: "New message from John Doe", time: "5 minutes ago" }, - { id: 2, message: "Your order has been shipped", time: "2 hours ago" }, - { id: 3, message: "Meeting reminder: Team sync at 3 PM", time: "1 day ago" }, - ]; + const supabase = createSupabaseClient(); + const router = useRouter(); + const { session, loading } = useSession(); + + const [showUnreadOnly, setShowUnreadOnly] = useState(false); + + const { + data: notifications, + error, + isLoading, + refetch, + } = useQuery(getNotificationByUserId(supabase, session?.user.id), { enabled: !!session }); + + if (loading) { + return ; + } + + if (!session) { + return ( +
+

Error fetching data. Please try again.

={" "} + +
+ ); + } + + const filteredNotifications = showUnreadOnly + ? notifications?.filter((notification) => !notification.is_read) + : notifications; + + const markAsRead = async (id: number) => { + const { error } = await supabase.from("notification").update({ is_read: true }).eq("id", id); + if (!error) { + refetch(); + } + }; + + if (isLoading) return ; + if (error) return

Error loading notifications: {error.message}

; return ( -
-
-

Notifications

-
- {/* Cards */} - - - - - {sampleNotifications.map((notification) => ( -
-
- -
-

{notification.message}

-

{notification.time}

-
-
- -
- ))} -
-
-
-
-
+
+

Notifications

+ +
+ + setShowUnreadOnly((prev) => !prev)} + className="cursor-pointer" + />
+ + + + {filteredNotifications?.map((notification) => ( +
+
+ +
+

{notification.message}

+

{formatDate(notification.created_at)}

+
+
+ + {!notification.is_read && ( + + )} +
+ ))} +
+
); } diff --git a/src/lib/data/norificationQuery.ts b/src/lib/data/norificationQuery.ts new file mode 100644 index 0000000..a457107 --- /dev/null +++ b/src/lib/data/norificationQuery.ts @@ -0,0 +1,41 @@ +import { SupabaseClient } from "@supabase/supabase-js"; + +interface NotificationData { + count: number; + status: number; + statusText: string; +} + +export async function getUnreadNotificationCountByUserId(client: SupabaseClient, userId: string) { + const { data, error } = await client + .from("notification") + .select("*", { count: "exact", head: true }) + .eq("receiver_id", userId) + .eq("is_read", false); + + if (error) { + return { data: null, error: error }; + } + + if (data === null) { + return { data: null, error: error }; + } else { + const notiData = data as unknown as NotificationData; + return { data: notiData, error: error }; + } +} + +export function getNotificationByUserId(client: SupabaseClient, userId: string | undefined) { + return client + .from("notification") + .select( + ` + id, + receiver_id, + message, + created_at, + is_read + ` + ) + .eq("receiver_id", userId); +} diff --git a/src/lib/data/query.ts b/src/lib/data/query.ts deleted file mode 100644 index e69de29..0000000