init
This commit is contained in:
commit
c19b910c36
80 changed files with 16134 additions and 0 deletions
36
app/components/Navbar.tsx
Normal file
36
app/components/Navbar.tsx
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
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>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue