- Extract views to src/components/views/ (Overview, Logbook, Trends, Settings, Auth) - Extract standalone components (EntryModal, ImportPreviewModal, ConfirmDialog, Sidebar, TopBar, MobileNav, EntryLedger, FiltersPanel, QuickAddPanel, etc.) - Move shared helpers to src/lib (dashboard, filters, userDisplay) and static data to src/data (accents, quickAdds) - App.tsx now orchestration-only (2971 -> 777 lines); no behavior change
62 lines
1.9 KiB
TypeScript
62 lines
1.9 KiB
TypeScript
import { Camera, Plus } from "lucide-react";
|
|
import { NAV_ITEMS } from "./navItems";
|
|
import type { AppView } from "../types";
|
|
|
|
type TopBarProps = {
|
|
activeView: AppView;
|
|
busyAction: string | null;
|
|
onAdd: () => void;
|
|
onScan: () => void;
|
|
className?: string;
|
|
};
|
|
|
|
export function TopBar({ activeView, busyAction, onAdd, onScan, className = "" }: TopBarProps) {
|
|
const activeItem = NAV_ITEMS.find((item) => item.id === activeView) ?? NAV_ITEMS[0];
|
|
const ActiveIcon = activeItem.icon;
|
|
const title = activeItem.label;
|
|
const subtitle = new Intl.DateTimeFormat("en-GB", {
|
|
weekday: "long",
|
|
day: "numeric",
|
|
month: "long",
|
|
}).format(new Date());
|
|
|
|
return (
|
|
<header className={`top-app-bar ${className}`.trim()} data-view={activeView}>
|
|
<div className="top-app-bar-main">
|
|
<div className="top-title-cluster">
|
|
<span className="top-app-icon">
|
|
<ActiveIcon size={24} aria-hidden="true" />
|
|
</span>
|
|
<div className="min-w-0">
|
|
<p className="top-kicker">{subtitle}</p>
|
|
<h1 className="top-title">{title}</h1>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="top-action-row">
|
|
<button
|
|
className="secondary-button top-action-button justify-center active:scale-95"
|
|
type="button"
|
|
onClick={onScan}
|
|
disabled={Boolean(busyAction)}
|
|
aria-label="Scan barcode"
|
|
>
|
|
<Camera size={18} aria-hidden="true" />
|
|
<span className="top-action-label">Scan</span>
|
|
</button>
|
|
<button
|
|
className="primary-button top-action-button justify-center active:scale-95"
|
|
type="button"
|
|
onClick={onAdd}
|
|
disabled={Boolean(busyAction)}
|
|
aria-label="Add intake"
|
|
>
|
|
<Plus size={18} aria-hidden="true" />
|
|
<span className="top-action-label">Add intake</span>
|
|
</button>
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|