mega-plant/components/ClockBottomNav.tsx
David 1ec52961ee Cash float card, Office role + Slips tab, job card PDF, manual close/delete
- Cash Floats: ledger card (opening balance, top-ups, slips), manual entries, slip photos
- Office access level; clock app Slips tab (photograph a slip, popup for supplier/cost
  code/comments/amount); only Office sees it; per-role route table in lib/clock-access
- Job cards: Machine Service PDF (with Oil block), JC numbers, manual Close job, Delete
- Hide Expenses > Vehicle Costs and Finance (Bastion) from the menu

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 15:09:57 +02:00

32 lines
1.9 KiB
TypeScript

'use client';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { useEffect, useState } from 'react';
import { ClipboardList, Droplets, Receipt, Users, type LucideIcon } from 'lucide-react';
import { CLOCK_TABS } from '@/lib/clock-access';
import type { UserAccess } from '@/lib/auth-policy';
const ICONS: Record<string, LucideIcon> = { '/clock': Users, '/clock/stock': Droplets, '/clock/job-cards': ClipboardList, '/clock/slips': Receipt };
/** Mobile-app style tab bar. Each access level sees only its own tabs. Hidden on sign-in / password screens. */
export function ClockBottomNav({ access = 'full' }: { access?: UserAccess }) {
const path = usePathname();
// Highlight the tapped tab at once: the next page takes a moment to load and an
// unchanged bar reads as "the tap did not register".
const [tapped, setTapped] = useState<string | null>(null);
useEffect(() => setTapped(null), [path]);
if (path.startsWith('/clock/login') || path.startsWith('/clock/change-password')) return null;
const tabs = CLOCK_TABS[access];
return <nav aria-label="Plant app" className="fixed inset-x-0 bottom-0 z-40 border-t border-border bg-surface pb-[env(safe-area-inset-bottom)]">
<ul className="mx-auto max-w-3xl grid" style={{ gridTemplateColumns: `repeat(${tabs.length}, minmax(0, 1fr))` }}>
{tabs.map(({ href, label }) => {
const Icon = ICONS[href] ?? Users;
const here = tapped ?? path;
const active = href === '/clock' ? here === '/clock' : here.startsWith(href);
return <li key={href}><Link href={href} onClick={() => setTapped(href)} aria-current={active ? 'page' : undefined}
className={`flex min-h-[56px] flex-col items-center justify-center gap-0.5 text-xs font-medium ${active ? 'text-[#30638E]' : 'text-text-muted'}`}>
<Icon size={22} strokeWidth={active ? 2.4 : 1.8}/>{label}</Link></li>;
})}
</ul>
</nav>;
}