feat(03-02): navigation restructure, TotalsBar refactor, and setup hooks
- Move collection view from / to /collection with gear/planning tabs - Rewrite / as dashboard with three summary cards (Collection, Planning, Setups) - Refactor TotalsBar to accept optional stats/linkTo/title props - Create DashboardCard component for dashboard summary cards - Create useSetups hooks (CRUD + sync/remove item mutations) - Update __root.tsx with route-aware TotalsBar, FAB visibility, resolve navigation - Add item picker and setup delete UI state to uiStore - Invalidate setups queries on item update/delete for stale data prevention - Update routeTree.gen.ts with new collection/setups routes Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
50
src/client/components/DashboardCard.tsx
Normal file
50
src/client/components/DashboardCard.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import { Link } from "@tanstack/react-router";
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
interface DashboardCardProps {
|
||||
to: string;
|
||||
search?: Record<string, string>;
|
||||
title: string;
|
||||
icon: ReactNode;
|
||||
stats: Array<{ label: string; value: string }>;
|
||||
emptyText?: string;
|
||||
}
|
||||
|
||||
export function DashboardCard({
|
||||
to,
|
||||
search,
|
||||
title,
|
||||
icon,
|
||||
stats,
|
||||
emptyText,
|
||||
}: DashboardCardProps) {
|
||||
const allZero = stats.every(
|
||||
(s) => s.value === "0" || s.value === "$0.00" || s.value === "0g",
|
||||
);
|
||||
|
||||
return (
|
||||
<Link
|
||||
to={to}
|
||||
search={search}
|
||||
className="block bg-white rounded-xl border border-gray-100 hover:border-gray-200 hover:shadow-md transition-all p-6"
|
||||
>
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<span className="text-2xl">{icon}</span>
|
||||
<h2 className="text-lg font-semibold text-gray-900">{title}</h2>
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
{stats.map((stat) => (
|
||||
<div key={stat.label} className="flex items-center justify-between">
|
||||
<span className="text-sm text-gray-500">{stat.label}</span>
|
||||
<span className="text-sm font-medium text-gray-700">
|
||||
{stat.value}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{allZero && emptyText && (
|
||||
<p className="mt-4 text-sm text-blue-600 font-medium">{emptyText}</p>
|
||||
)}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user