Adds MobileHeader with hamburger button (left-aligned) that opens a slide-in sidebar drawer on mobile. Desktop layout is unchanged. All hardcoded multi-column grids updated with responsive Tailwind breakpoints. Co-Authored-By: Jack Levy
90 lines
3.3 KiB
TypeScript
90 lines
3.3 KiB
TypeScript
"use client";
|
|
|
|
import { TrendingUp, BookOpen, RefreshCw } from "lucide-react";
|
|
import { useDashboard } from "@/lib/hooks/useDashboard";
|
|
import { BillCard } from "@/components/shared/BillCard";
|
|
import { adminAPI } from "@/lib/api";
|
|
import { useState } from "react";
|
|
|
|
export default function DashboardPage() {
|
|
const { data, isLoading, refetch } = useDashboard();
|
|
const [polling, setPolling] = useState(false);
|
|
|
|
const triggerPoll = async () => {
|
|
setPolling(true);
|
|
try {
|
|
await adminAPI.triggerPoll();
|
|
setTimeout(() => { refetch(); setPolling(false); }, 3000);
|
|
} catch { setPolling(false); }
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-8">
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<h1 className="text-2xl font-bold">Dashboard</h1>
|
|
<p className="text-muted-foreground text-sm mt-1">
|
|
Your personalized Congressional activity feed
|
|
</p>
|
|
</div>
|
|
<button
|
|
onClick={triggerPoll}
|
|
disabled={polling}
|
|
className="flex items-center gap-2 px-4 py-2 text-sm bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors disabled:opacity-50"
|
|
>
|
|
<RefreshCw className={`w-4 h-4 ${polling ? "animate-spin" : ""}`} />
|
|
{polling ? "Polling..." : "Poll Now"}
|
|
</button>
|
|
</div>
|
|
|
|
{isLoading ? (
|
|
<div className="text-center py-20 text-muted-foreground">Loading dashboard...</div>
|
|
) : (
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 md:gap-8">
|
|
<div className="md:col-span-2 space-y-4">
|
|
<h2 className="font-semibold flex items-center gap-2">
|
|
<BookOpen className="w-4 h-4" />
|
|
Your Feed
|
|
{data?.follows && (
|
|
<span className="text-xs text-muted-foreground font-normal">
|
|
({data.follows.bills} bills · {data.follows.members} members · {data.follows.topics} topics)
|
|
</span>
|
|
)}
|
|
</h2>
|
|
{!data?.feed?.length ? (
|
|
<div className="bg-card border border-border rounded-lg p-8 text-center text-muted-foreground">
|
|
<p className="text-sm">Your feed is empty.</p>
|
|
<p className="text-xs mt-1">Follow bills, members, or topics to see activity here.</p>
|
|
</div>
|
|
) : (
|
|
<div className="space-y-3">
|
|
{data.feed.map((bill) => (
|
|
<BillCard key={bill.bill_id} bill={bill} />
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div className="space-y-4">
|
|
<h2 className="font-semibold flex items-center gap-2">
|
|
<TrendingUp className="w-4 h-4" />
|
|
Trending
|
|
</h2>
|
|
{!data?.trending?.length ? (
|
|
<div className="bg-card border border-border rounded-lg p-6 text-center text-muted-foreground text-xs">
|
|
No trend data yet. Run a poll to populate.
|
|
</div>
|
|
) : (
|
|
<div className="space-y-2">
|
|
{data.trending.map((bill) => (
|
|
<BillCard key={bill.bill_id} bill={bill} compact />
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|