diff --git a/src/components/dashboard/recent-activity.tsx b/src/components/dashboard/recent-activity.tsx index 0359b55..77652c2 100644 --- a/src/components/dashboard/recent-activity.tsx +++ b/src/components/dashboard/recent-activity.tsx @@ -1,178 +1,51 @@ -"use client"; - -import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; +import { useQuery } from "@tanstack/react-query"; import { formatDistanceToNow } from "date-fns"; -import { CheckCheck, Wallet, DollarSign, CreditCard, ThumbsUp, Send } from "lucide-react"; -import { clsx } from "clsx"; -import { useWallet } from "@/hooks/use-wallet"; -import type { Notification } from "@/types"; - -// TODO: Replace with real API responses once backend is ready -const MOCK_NOTIFICATIONS: Notification[] = [ - { - id: "mock-1", - recipient: "", - type: "contribution", - description: "Adaeze contributed 50 USDC to Eko Savings", - read: false, - createdAt: new Date(Date.now() - 1000 * 60 * 5).toISOString(), - }, - { - id: "mock-2", - recipient: "", - type: "loan", - description: "Chidi applied for a 200 USDC loan", - read: true, - createdAt: new Date(Date.now() - 1000 * 60 * 60 * 2).toISOString(), - }, - { - id: "mock-3", - recipient: "", - type: "vote", - description: "Voting ended for Proposal #12", - read: false, - createdAt: new Date(Date.now() - 1000 * 60 * 60 * 24).toISOString(), - }, - { - id: "mock-4", - recipient: "", - type: "distribution", - description: "50 USDC distributed to your account", - read: true, - createdAt: new Date(Date.now() - 1000 * 60 * 60 * 48).toISOString(), - }, -]; +import { useWallet } from "@solana/wallet-adapter-react"; + +type Activity = { + type: "contribution" | "loan" | "vote" | "distribution"; + actor: string; + amount: string; + timestamp: number; + note?: string; +}; -async function fetchNotifications(recipient: string): Promise { - // TODO: connect to API - if (!recipient) return MOCK_NOTIFICATIONS; - try { - const res = await fetch( - `${process.env.NEXT_PUBLIC_API_URL}/api/notifications?recipient=${encodeURIComponent(recipient)}` - ); - if (!res.ok) throw new Error("Failed to fetch notifications"); - const data: unknown = await res.json(); - if (!Array.isArray(data) || data.length === 0) return []; - return data as Notification[]; - } catch { - // TODO: connect to API — returning mock data on error - return MOCK_NOTIFICATIONS; - } -} +const ICONS: Record = { + contribution: "\u{1F4B0}", + loan: "\u{1F3E7}", + vote: "\u{1F5F3}", + distribution: "\u{1F4E4}", +}; -async function markNotificationAsRead(id: string): Promise { - const res = await fetch( - `${process.env.NEXT_PUBLIC_API_URL}/api/notifications/${encodeURIComponent(id)}/read`, - { method: "PATCH" } - ); - if (!res.ok) throw new Error("Failed to mark notification as read"); +async function fetchActivity(wallet: string) { + const res = await fetch(`/api/notifications?recipient=${wallet}`); + if (!res.ok) throw new Error("Failed to load activity"); + return (await res.json()) as Activity[]; } -const ACTIVITY_CONFIG: Record = { - contribution: { icon: DollarSign, color: "text-green-600", bg: "bg-green-50" }, - loan: { icon: CreditCard, color: "text-amber-600", bg: "bg-amber-50" }, - vote: { icon: ThumbsUp, color: "text-blue-600", bg: "bg-blue-50" }, - distribution: { icon: Send, color: "text-purple-600", bg: "bg-purple-50" }, -}; - export function RecentActivity() { - const { address, connect } = useWallet(); - const queryClient = useQueryClient(); - - const { data = [], isLoading } = useQuery({ - queryKey: ["notifications", address], - queryFn: () => fetchNotifications(address ?? ""), - enabled: !!address, - staleTime: 30_000, - }); + const { connected, publicKey } = useWallet(); + const wallet = publicKey?.toBase58() ?? ""; - const mutation = useMutation({ - mutationFn: markNotificationAsRead, - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["notifications"] }); - }, + const { data, isLoading } = useQuery({ + queryKey: ["activity", wallet], + queryFn: () => fetchActivity(wallet), + enabled: connected, }); - const hasUnread = data.some((n) => !n.read); - - if (!address) { - return ( -
- -

Connect your wallet to see activity

- -
- ); - } - - if (isLoading) { - return ( -
-
- {[...Array(4)].map((_, i) => ( -
-
-
-
-
-
-
- ))} -
- ); - } + if (!connected) return
Connect wallet to see activity.
; + if (isLoading) return
Loading…
; return ( -
-
-

Recent Activity

- {hasUnread && ( - - )} -
-
- {data.length === 0 ? ( -
-

No recent activity

-
- ) : ( -
- {data.map((notification) => { - const config = ACTIVITY_CONFIG[notification.type] || ACTIVITY_CONFIG.contribution; - const Icon = config.icon; - return ( -
-
- -
-
-

{notification.description}

-

- {formatDistanceToNow(new Date(notification.createdAt), { addSuffix: true })} -

-
-
- ); - })} -
- )} -
+
+ {data?.map((a, i) => ( +
+ {ICONS[a.type]} + {a.actor} + {a.note ?? a.type} + {formatDistanceToNow(a.timestamp * 1000, { addSuffix: true })} +
+ ))}
); }