From de275976ed73da21305334945e5ae9eb16b685ae Mon Sep 17 00:00:00 2001 From: hobokenchicken Date: Wed, 22 Apr 2026 13:50:41 -0400 Subject: [PATCH] feat: add dashboard request panels --- .../app/dashboard/components/ActivityFeed.tsx | 31 ++++++++- .../dashboard/components/RequestHistory.tsx | 69 ++++++++++++++++++- frontend/src/app/dashboard/page.tsx | 35 ++++++++-- 3 files changed, 129 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/dashboard/components/ActivityFeed.tsx b/frontend/src/app/dashboard/components/ActivityFeed.tsx index c809dcb..07ebbc2 100644 --- a/frontend/src/app/dashboard/components/ActivityFeed.tsx +++ b/frontend/src/app/dashboard/components/ActivityFeed.tsx @@ -1 +1,30 @@ -export function ActivityFeed() { return null; } +"use client"; + +import { useEffect, useState } from "react"; +import { Card, CardContent } from "@/components/ui/card"; +import { transactionApi } from "@/lib/api"; + +export function ActivityFeed() { + const [items, setItems] = useState([]); + useEffect(() => { + transactionApi + .getRecentActivity() + .then((r) => setItems(r.data.transactions || [])); + }, []); + return ( +
+
Recent activity
+ {items.map((t) => ( + + + + {t.user?.plexUsername || "You"} • {t.type} •{" "} + {t.contentTitle || t.description || "Activity"} + + {t.amount} $COOP + + + ))} +
+ ); +} diff --git a/frontend/src/app/dashboard/components/RequestHistory.tsx b/frontend/src/app/dashboard/components/RequestHistory.tsx index 0977934..979e5fe 100644 --- a/frontend/src/app/dashboard/components/RequestHistory.tsx +++ b/frontend/src/app/dashboard/components/RequestHistory.tsx @@ -1 +1,68 @@ -export function RequestHistory() { return null; } +"use client"; + +import { useEffect, useState } from "react"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { userApi } from "@/lib/api"; + +export function RequestHistory() { + const [requests, setRequests] = useState([]); + const [status, setStatus] = useState(""); + const [query, setQuery] = useState(""); + + const load = async () => { + const res = await userApi.getRequests(1, 50, status || undefined); + setRequests(res.data.requests || []); + }; + + useEffect(() => { + load(); + }, [status]); + + const filtered = requests.filter( + (r) => + !query || + `${r.title} ${r.mediaType}`.toLowerCase().includes(query.toLowerCase()), + ); + + return ( +
+
+ setQuery(e.target.value)} + placeholder="Filter requests" + /> + + + + +
+
+ {filtered.map((r) => ( + + +
+
{r.title}
+
+ {r.mediaType} • {r.creditsCost} $COOP +
+
+ {r.status} +
+
+ ))} +
+
+ ); +} diff --git a/frontend/src/app/dashboard/page.tsx b/frontend/src/app/dashboard/page.tsx index 085ef9c..5de0eb5 100644 --- a/frontend/src/app/dashboard/page.tsx +++ b/frontend/src/app/dashboard/page.tsx @@ -12,7 +12,7 @@ import { } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; -import { api, overseerApi } from "@/lib/api"; +import { api, overseerApi, userApi } from "@/lib/api"; import { useSocket } from "@/lib/socket"; import { useStore } from "@/lib/store"; import { formatNumber } from "@/lib/utils"; @@ -33,6 +33,7 @@ export default function DashboardPage() { const { isAuthenticated } = useStore(); const [wallet, setWallet] = useState(null); const [requestCosts, setRequestCosts] = useState({ movie: 500, tv: 1000 }); + const [pendingRequests, setPendingRequests] = useState([]); const [isLoading, setIsLoading] = useState(true); const [isSearchModalOpen, setIsSearchModalOpen] = useState(false); const socket = useSocket(); @@ -59,12 +60,14 @@ export default function DashboardPage() { const loadData = async () => { try { - const [walletRes, costsRes] = await Promise.all([ + const [walletRes, costsRes, reqRes] = await Promise.all([ api.get("/wallet"), overseerApi.getCosts(), + userApi.getRequests(1, 10, "PENDING"), ]); setWallet(walletRes.data); setRequestCosts(costsRes.data); + setPendingRequests(reqRes.data.requests || []); } catch { toast.error("Failed to load dashboard"); } finally { @@ -111,8 +114,32 @@ export default function DashboardPage() { -
- Request costs: movie {requestCosts.movie}, tv {requestCosts.tv} +
+ + + Pending requests + My requests waiting + + + {pendingRequests.length} + + + + + Movie cost + + + {requestCosts.movie} + + + + + TV cost + + + {requestCosts.tv} + +