dashboard fix

This commit is contained in:
root
2026-05-19 21:25:38 -04:00
parent 7ac0098c7f
commit d4f7de5762
27 changed files with 705 additions and 336 deletions
@@ -39,6 +39,7 @@ interface EmployeeProfile {
firstName: string
lastName: string
role: string
preferredLanguage?: string
}
function computeInitials(name: string): string {
@@ -59,23 +60,29 @@ function toSidebarUser(profile: Partial<EmployeeProfile>, fallbackName: string,
}
const NAV_ITEMS = [
{ href: '/dashboard', key: 'dashboard', icon: LayoutDashboard, exact: true },
{ href: '/dashboard/fleet', key: 'fleet', icon: Car },
{ href: '/dashboard/reservations', key: 'reservations', icon: Calendar },
{ href: '/dashboard/online-reservations', key: 'onlineReservations', icon: Globe },
{ href: '/dashboard/customers', key: 'customers', icon: Users },
{ href: '/dashboard/offers', key: 'offers', icon: Tag },
{ href: '/dashboard/team', key: 'team', icon: UserPlus },
{ href: '/dashboard/reports', key: 'reports', icon: BarChart2 },
{ href: '/dashboard/subscription', key: 'subscription', icon: CreditCard },
{ href: '/dashboard/billing', key: 'billing', icon: CreditCard },
{ href: '/dashboard/contracts', key: 'contracts', icon: FileText },
{ href: '/dashboard/notifications', key: 'notifications', icon: Bell },
{ href: '/dashboard/settings', key: 'settings', icon: Settings },
{ href: '/dashboard', key: 'dashboard', icon: LayoutDashboard, exact: true, minRole: 'AGENT' },
{ href: '/dashboard/fleet', key: 'fleet', icon: Car, minRole: 'AGENT' },
{ href: '/dashboard/reservations', key: 'reservations', icon: Calendar, minRole: 'AGENT' },
{ href: '/dashboard/online-reservations', key: 'onlineReservations', icon: Globe, minRole: 'AGENT' },
{ href: '/dashboard/customers', key: 'customers', icon: Users, minRole: 'AGENT' },
{ href: '/dashboard/offers', key: 'offers', icon: Tag, minRole: 'MANAGER' },
{ href: '/dashboard/team', key: 'team', icon: UserPlus, minRole: 'AGENT' },
{ href: '/dashboard/reports', key: 'reports', icon: BarChart2, minRole: 'MANAGER' },
{ href: '/dashboard/subscription', key: 'subscription', icon: CreditCard, minRole: 'OWNER' },
{ href: '/dashboard/billing', key: 'billing', icon: CreditCard, minRole: 'MANAGER' },
{ href: '/dashboard/contracts', key: 'contracts', icon: FileText, minRole: 'AGENT' },
{ href: '/dashboard/notifications', key: 'notifications', icon: Bell, minRole: 'AGENT' },
{ href: '/dashboard/settings', key: 'settings', icon: Settings, minRole: 'OWNER' },
] as const
const ROLE_RANK: Record<string, number> = { OWNER: 3, MANAGER: 2, AGENT: 1 }
function hasMinRole(employeeRole: string, minRole: string): boolean {
return (ROLE_RANK[employeeRole] ?? 0) >= (ROLE_RANK[minRole] ?? 0)
}
export default function Sidebar() {
const { dict, language } = useDashboardI18n()
const { dict, language, setLanguage } = useDashboardI18n()
const isRtl = language === 'ar'
const pathname = usePathname()
const router = useRouter()
@@ -85,7 +92,11 @@ export default function Sidebar() {
subtitle: dict.localAuth,
initials: 'W',
})
const [role, setRole] = useState<string>('AGENT')
const [open, setOpen] = useState(false)
const [mounted, setMounted] = useState(false)
useEffect(() => { setMounted(true) }, [])
useEffect(() => {
apiFetch<BrandSettings>('/companies/me/brand').then(setBrand).catch(() => {})
@@ -107,6 +118,7 @@ export default function Sidebar() {
try {
const profile = JSON.parse(cached) as Partial<EmployeeProfile>
setUser(toSidebarUser(profile, dict.workspaceUser, dict.localAuth))
if (profile.role) setRole(profile.role)
} catch {}
}
@@ -117,6 +129,11 @@ export default function Sidebar() {
if (cancelled) return
window.localStorage.setItem(EMPLOYEE_PROFILE_KEY, JSON.stringify(employee))
setUser(toSidebarUser(employee, dict.workspaceUser, dict.localAuth))
if (employee.role) setRole(employee.role)
if (employee.preferredLanguage === 'en' || employee.preferredLanguage === 'fr' || employee.preferredLanguage === 'ar') {
setLanguage(employee.preferredLanguage)
document.cookie = `rentaldrivego-language=${employee.preferredLanguage}; path=/; max-age=31536000; samesite=lax`
}
})
.catch(() => {
if (cancelled) return
@@ -188,9 +205,9 @@ export default function Sidebar() {
</a>
<nav className="flex-1 space-y-0.5 overflow-y-auto px-3 py-4">
{NAV_ITEMS.map((item) => {
{NAV_ITEMS.filter((item) => !mounted || hasMinRole(role, item.minRole)).map((item) => {
const Icon = item.icon
const active = isActive(item)
const active = mounted && isActive(item)
return (
<Link
key={item.href}