Files
Client_Fe/src/hooks/use-nav-items.ts
T
HarithaRandunu 4a9ebe07b8 feat: add inventory management components and API integration
- Implemented InventorySalesTab for recording and viewing sales.
- Created InventorySuppliersTab for managing suppliers.
- Developed InventoryView to consolidate inventory-related tabs.
- Added API functions for handling products, suppliers, sales, and GRNs.
- Defined necessary TypeScript models for inventory entities.
- Updated navigation to include an Inventory section.
2026-10-07 15:43:17 +05:30

100 lines
2.4 KiB
TypeScript

"use client"
import * as React from "react"
import type { LucideIcon } from "lucide-react"
import {
Activity,
BarChart3,
CalendarCheck,
CalendarClock,
CreditCard,
LayoutDashboard,
Package,
Receipt,
Rss,
Settings,
TicketIcon,
Users,
UsersRound,
Utensils,
} from "lucide-react"
import { getNav } from "@/lib/api/nav"
import type { DashboardNavItem } from "@/lib/nav"
const ICON_MAP: Record<string, LucideIcon> = {
Activity,
BarChart3,
CalendarCheck,
CalendarClock,
CreditCard,
LayoutDashboard,
Package,
Receipt,
Rss,
Settings,
TicketIcon,
Users,
UsersRound,
Utensils,
}
interface NavState {
isOwner: boolean
items: DashboardNavItem[]
}
// Module-level cache: the nav call happens once per dashboard session — app-sidebar.tsx
// and mobile-nav.tsx both mount together and both need this, so a plain cache avoids
// wrapping DashboardShell in a second context provider just for this.
let cache: NavState | null = null
/** Clears the per-session nav cache when a user signs in or out. */
function resetNavItemsCache() {
cache = null
}
/**
* Live, permission-filtered sidebar nav for the current caller.
*
* Sandbox components pass `false` because they use the static demo navigation
* and must never make an authenticated permission request.
*/
function useNavItems(enabled = true) {
const [state, setState] = React.useState<NavState>(cache ?? { isOwner: false, items: [] })
const [loading, setLoading] = React.useState(enabled && !cache)
React.useEffect(() => {
if (!enabled || cache) return
let cancelled = false
getNav()
.then((res) => {
if (cancelled) return
const items = res.items.map((i) => ({
key: i.key,
label: i.label,
shortLabel: i.shortLabel,
href: i.href,
icon: ICON_MAP[i.icon] ?? LayoutDashboard,
}))
cache = { isOwner: res.isOwner, items }
setState(cache)
})
.catch(() => {
// Leave state empty — the sidebar/mobile-nav will just show nothing until a retry
// (e.g. navigating away and back re-mounts the hook, since cache stays null).
})
.finally(() => {
if (!cancelled) setLoading(false)
})
return () => {
cancelled = true
}
}, [enabled])
return { ...state, loading: enabled && loading }
}
export { resetNavItemsCache, useNavItems }