feat(mobile): add MoreSheet (3-column grid of long-tail nav items in a bottom drawer)
This commit is contained in:
85
src/components/layout/mobile/more-sheet.tsx
Normal file
85
src/components/layout/mobile/more-sheet.tsx
Normal file
@@ -0,0 +1,85 @@
|
||||
'use client';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import {
|
||||
Building2,
|
||||
Bookmark,
|
||||
Receipt,
|
||||
FileText,
|
||||
FolderOpen,
|
||||
Mail,
|
||||
Bell,
|
||||
ShieldAlert,
|
||||
BarChart3,
|
||||
Settings,
|
||||
Shield,
|
||||
} from 'lucide-react';
|
||||
|
||||
import {
|
||||
Drawer,
|
||||
DrawerContent,
|
||||
DrawerHeader,
|
||||
DrawerTitle,
|
||||
DrawerClose,
|
||||
} from '@/components/shared/drawer';
|
||||
|
||||
type MoreItem = {
|
||||
label: string;
|
||||
icon: typeof Building2;
|
||||
segment: string;
|
||||
};
|
||||
|
||||
const MORE_ITEMS: MoreItem[] = [
|
||||
{ label: 'Companies', icon: Building2, segment: 'companies' },
|
||||
{ label: 'Interests', icon: Bookmark, segment: 'interests' },
|
||||
{ label: 'Invoices', icon: FileText, segment: 'invoices' },
|
||||
{ label: 'Expenses', icon: Receipt, segment: 'expenses' },
|
||||
{ label: 'Documents', icon: FolderOpen, segment: 'documents' },
|
||||
{ label: 'Email', icon: Mail, segment: 'email' },
|
||||
{ label: 'Alerts', icon: ShieldAlert, segment: 'alerts' },
|
||||
{ label: 'Reports', icon: BarChart3, segment: 'reports' },
|
||||
{ label: 'Reminders', icon: Bell, segment: 'reminders' },
|
||||
{ label: 'Settings', icon: Settings, segment: 'settings' },
|
||||
{ label: 'Admin', icon: Shield, segment: 'admin' },
|
||||
];
|
||||
|
||||
export function MoreSheet({
|
||||
open,
|
||||
onOpenChange,
|
||||
}: {
|
||||
open: boolean;
|
||||
onOpenChange: (next: boolean) => void;
|
||||
}) {
|
||||
const pathname = usePathname();
|
||||
const portSlug = pathname.split('/').filter(Boolean)[0] ?? 'port-nimara';
|
||||
|
||||
return (
|
||||
<Drawer open={open} onOpenChange={onOpenChange}>
|
||||
<DrawerContent>
|
||||
<DrawerHeader>
|
||||
<DrawerTitle>More</DrawerTitle>
|
||||
</DrawerHeader>
|
||||
<ul className="grid grid-cols-3 gap-1 px-3 pb-4">
|
||||
{MORE_ITEMS.map((item) => {
|
||||
const Icon = item.icon;
|
||||
return (
|
||||
<li key={item.segment}>
|
||||
<DrawerClose asChild>
|
||||
<Link
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
href={`/${portSlug}/${item.segment}` as any}
|
||||
className="flex flex-col items-center justify-center gap-1.5 rounded-md py-4 text-xs text-foreground hover:bg-accent"
|
||||
>
|
||||
<Icon className="size-6 text-muted-foreground" aria-hidden />
|
||||
<span className="font-medium">{item.label}</span>
|
||||
</Link>
|
||||
</DrawerClose>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user