planmymeal/app/components/Navbar.tsx

37 lines
1.2 KiB
TypeScript
Raw Normal View History

2026-10-31 20:44:29 -05:00
import type { SyncStatus } from "@/app/lib/usePlanState";
import { BudgetMeter } from "./BudgetMeter";
import { SiteHeader } from "./SiteHeader";
interface NavbarProps {
checkoutTotal: number;
budget: number;
syncStatus: SyncStatus;
isGenerating: boolean;
}
const SYNC_LABEL: Record<SyncStatus, { text: string; dot: string }> = {
saved: { text: "Saved on device", dot: "bg-status-ok" },
error: { text: "Storage blocked", dot: "bg-status-danger" },
};
export function Navbar({ checkoutTotal, budget, syncStatus, isGenerating }: NavbarProps) {
const sync = isGenerating ? { text: "Building plan…", dot: "bg-status-warn animate-pulse" } : SYNC_LABEL[syncStatus];
return (
<SiteHeader
active="plan"
subtitle={
<span className="inline-flex items-center gap-1.5 text-xs text-ink-muted" aria-live="polite" title={sync.text}>
<span className={`size-1.5 rounded-full ${sync.dot}`} />
<span className="sr-only sm:not-sr-only">{sync.text}</span>
</span>
}
rightSlot={
<div className="hidden w-60 border-l border-line pl-4 sm:block lg:w-68">
<BudgetMeter spent={checkoutTotal} budget={budget} />
</div>
}
/>
);
}