- Shared src/lib/api.ts fetch wrapper -> /api with Cache-Control: no-store - Storefront: home hero, shop grid (category filter + search), product detail, cart, checkout (POST /api/orders -> confirmation + order number), order tracking - Admin: JWT login, today KPI dashboard (revenue/orders/gross/net/margin/aov/refunds), top products, supplier performance, product import, lifecycle view, order list with tracking simulation - Multi-stage Dockerfile (Vite build -> nginx static + /api proxy -> api:8000) - nginx.conf with SPA fallback and no-store HTML caching - mock/mock_api.py for local verification (excluded from image)
18 lines
703 B
TypeScript
18 lines
703 B
TypeScript
export function Spinner({ className = 'h-5 w-5' }: { className?: string }) {
|
|
return (
|
|
<svg className={`animate-spin ${className}`} viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
|
<circle cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="3" className="opacity-20" />
|
|
<path d="M22 12a10 10 0 0 1-10 10" stroke="currentColor" strokeWidth="3" strokeLinecap="round" />
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
export function PageLoader({ label = 'Loading…' }: { label?: string }) {
|
|
return (
|
|
<div className="flex flex-col items-center justify-center gap-3 py-24 text-slate-400">
|
|
<Spinner className="h-7 w-7 text-indigo-400" />
|
|
<p className="text-sm">{label}</p>
|
|
</div>
|
|
);
|
|
}
|