Add dashboard quick access cards for commerce routes

Link cards for invoices, proforma, proforma requests, payments, and payment requests above metrics; show loading state below quick access.

Made-with: Cursor
This commit is contained in:
“kirukib” 2026-04-15 10:24:56 +03:00
parent ae7a366e2f
commit 4795822065

View File

@ -1,11 +1,59 @@
import { useQuery } from "@tanstack/react-query";
import { Link } from "react-router-dom";
import {
Receipt,
FileSearch,
ClipboardList,
CreditCard,
FileClock,
ChevronRight,
} from "lucide-react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { dashboardService, invoiceService } from "@/services";
import { Badge } from "@/components/ui/badge";
import { format } from "date-fns";
import { cn } from "@/lib/utils";
const COLORS = ["#10b981", "#f59e0b", "#ef4444", "#3b82f6", "#8b5cf6"];
const COMMERCE_QUICK_LINKS = [
{
label: "Invoices",
description: "Browse, search, and manage issued invoices.",
path: "/admin/invoices",
icon: Receipt,
color: "text-slate-700",
},
{
label: "Proforma",
description: "View and manage proforma invoices and drafts.",
path: "/admin/proforma",
icon: FileSearch,
color: "text-blue-600",
},
{
label: "Proforma requests",
description: "Review and process incoming proforma requests.",
path: "/admin/proforma-requests",
icon: ClipboardList,
color: "text-violet-600",
},
{
label: "Payments",
description: "Recorded payments and transaction history.",
path: "/admin/payments",
icon: CreditCard,
color: "text-emerald-600",
},
{
label: "Payment requests",
description: "Pending and processed payment requests.",
path: "/admin/payment-requests",
icon: FileClock,
color: "text-amber-600",
},
] as const;
export default function DashboardPage() {
const { data: metrics, isLoading: metricsLoading } = useQuery({
queryKey: ["admin", "dashboard", "metrics"],
@ -35,13 +83,8 @@ export default function DashboardPage() {
}).format(amount);
};
if (metricsLoading || scannedLoading || statusLoading || requestsLoading) {
return (
<div className="p-8 text-center text-gray-500 font-medium">
Loading dashboard...
</div>
);
}
const dataLoading =
metricsLoading || scannedLoading || statusLoading || requestsLoading;
return (
<div className="p-8 space-y-12 max-w-7xl mx-auto bg-white min-h-screen">
@ -54,6 +97,50 @@ export default function DashboardPage() {
</p>
</header>
{/* Quick access — invoices, proforma, payments */}
<section className="space-y-4">
<h2 className="text-sm font-bold text-gray-400 uppercase tracking-widest">
Quick access
</h2>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 gap-4">
{COMMERCE_QUICK_LINKS.map((item) => (
<Link
key={item.path}
to={item.path}
className="group block rounded-none outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
>
<Card className="h-full cursor-pointer border-slate-200/60 shadow-sm hover:shadow-md transition-all rounded-none bg-white overflow-hidden">
<CardHeader className="pb-2 space-y-0 border-b border-slate-50 bg-slate-50/30">
<div className="flex items-center justify-between">
<span className="text-[10px] font-bold uppercase tracking-widest text-slate-400">
{item.label}
</span>
<item.icon
className={cn(
"w-4 h-4 shrink-0 transition-colors",
item.color,
)}
/>
</div>
</CardHeader>
<CardContent className="pt-3 pb-4 flex items-end justify-between gap-2">
<p className="text-xs text-muted-foreground leading-relaxed line-clamp-3">
{item.description}
</p>
<ChevronRight className="w-4 h-4 shrink-0 text-slate-300 group-hover:translate-x-0.5 transition-transform" />
</CardContent>
</Card>
</Link>
))}
</div>
</section>
{dataLoading ? (
<div className="py-16 text-center text-gray-500 font-medium border border-dashed border-gray-200 rounded-none">
Loading dashboard data
</div>
) : (
<>
{/* Top Metrics Cards */}
<section className="grid grid-cols-1 md:grid-cols-3 gap-6">
<Card className="border-none bg-gray-50 shadow-none rounded-none">
@ -284,6 +371,8 @@ export default function DashboardPage() {
</table>
</div>
</section>
</>
)}
</div>
);
}