feat(01-03): add data hooks, utilities, UI store, and foundational components

- API fetch wrapper with error handling and multipart upload
- Weight/price formatters for display
- TanStack Query hooks for items, categories, and totals with cache invalidation
- Zustand UI store for panel and confirm dialog state
- TotalsBar, CategoryHeader, ItemCard, ConfirmDialog, ImageUpload components

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-14 22:44:48 +01:00
parent a5df33a2d8
commit b099a47eb4
11 changed files with 647 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
import { useTotals } from "../hooks/useTotals";
import { formatWeight, formatPrice } from "../lib/formatters";
export function TotalsBar() {
const { data } = useTotals();
const global = data?.global;
return (
<div className="sticky top-0 z-10 bg-white border-b border-gray-100">
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="flex items-center justify-between h-14">
<h1 className="text-lg font-semibold text-gray-900">GearBox</h1>
<div className="flex items-center gap-6 text-sm text-gray-500">
<span>
<span className="font-medium text-gray-700">
{global?.itemCount ?? 0}
</span>{" "}
items
</span>
<span>
<span className="font-medium text-gray-700">
{formatWeight(global?.totalWeight ?? null)}
</span>{" "}
total
</span>
<span>
<span className="font-medium text-gray-700">
{formatPrice(global?.totalCost ?? null)}
</span>{" "}
spent
</span>
</div>
</div>
</div>
</div>
);
}