separate Admin/Settings Nav and add to MobileNav

This commit is contained in:
Francis Cao 2025-10-29 11:32:52 -07:00
parent ef55b63a3b
commit 72fba187db
5 changed files with 121 additions and 97 deletions

View file

@ -1,15 +1,19 @@
import { Row, NavMenu, NavMenuItem, IconLabel, Text, Grid } from '@umami/react-zen';
import { Globe, Grid2x2, LinkIcon } from '@/components/icons';
import { useMessages, useNavigation } from '@/components/hooks';
import Link from 'next/link';
import { WebsiteNav } from '@/app/(main)/websites/[websiteId]/WebsiteNav';
import { Logo } from '@/components/svg';
import { NavButton } from '@/components/input/NavButton';
import { useMessages, useNavigation } from '@/components/hooks';
import { Globe, Grid2x2, LinkIcon } from '@/components/icons';
import { MobileMenuButton } from '@/components/input/MobileMenuButton';
import { NavButton } from '@/components/input/NavButton';
import { Logo } from '@/components/svg';
import { Grid, IconLabel, NavMenu, NavMenuItem, Row, Text } from '@umami/react-zen';
import Link from 'next/link';
import { AdminNav } from './admin/AdminNav';
import { SettingsNav } from './settings/SettingsNav';
export function MobileNav() {
const { formatMessage, labels } = useMessages();
const { websiteId, renderUrl } = useNavigation();
const { pathname, websiteId, renderUrl } = useNavigation();
const isAdmin = pathname.includes('/admin');
const isSettings = pathname.includes('/settings');
const links = [
{
@ -51,6 +55,8 @@ export function MobileNav() {
})}
</NavMenu>
{websiteId && <WebsiteNav websiteId={websiteId} onItemClick={close} />}
{isAdmin && <AdminNav onItemClick={close} />}
{isSettings && <SettingsNav onItemClick={close} />}
</>
);
}}

View file

@ -1,50 +1,17 @@
'use client';
import { ReactNode } from 'react';
import { Grid, Column } from '@umami/react-zen';
import { useLoginQuery, useMessages, useNavigation } from '@/components/hooks';
import { User, Users, Globe } from '@/components/icons';
import { SideMenu } from '@/components/common/SideMenu';
import { PageBody } from '@/components/common/PageBody';
import { useLoginQuery } from '@/components/hooks';
import { Column, Grid } from '@umami/react-zen';
import { ReactNode } from 'react';
import { AdminNav } from './AdminNav';
export function AdminLayout({ children }: { children: ReactNode }) {
const { user } = useLoginQuery();
const { formatMessage, labels } = useMessages();
const { pathname } = useNavigation();
if (!user.isAdmin || process.env.cloudMode) {
return null;
}
const items = [
{
label: formatMessage(labels.manage),
items: [
{
id: 'users',
label: formatMessage(labels.users),
path: '/admin/users',
icon: <User />,
},
{
id: 'websites',
label: formatMessage(labels.websites),
path: '/admin/websites',
icon: <Globe />,
},
{
id: 'teams',
label: formatMessage(labels.teams),
path: '/admin/teams',
icon: <Users />,
},
],
},
];
const selectedKey = items
.flatMap(e => e.items)
?.find(({ path }) => path && pathname.startsWith(path))?.id;
return (
<Grid columns={{ xs: '1fr', lg: 'auto 1fr' }} width="100%" height="100%">
<Column
@ -55,12 +22,7 @@ export function AdminLayout({ children }: { children: ReactNode }) {
backgroundColor
marginRight="2"
>
<SideMenu
items={items}
title={formatMessage(labels.admin)}
selectedKey={selectedKey}
allowMinimize={false}
/>
<AdminNav />
</Column>
<Column gap="6" margin="2">
<PageBody>{children}</PageBody>

View file

@ -0,0 +1,48 @@
import { SideMenu } from '@/components/common/SideMenu';
import { useMessages, useNavigation } from '@/components/hooks';
import { Globe, User, Users } from '@/components/icons';
export function AdminNav({ onItemClick }: { onItemClick?: () => void }) {
const { formatMessage, labels } = useMessages();
const { pathname } = useNavigation();
const items = [
{
label: formatMessage(labels.manage),
items: [
{
id: 'users',
label: formatMessage(labels.users),
path: '/admin/users',
icon: <User />,
},
{
id: 'websites',
label: formatMessage(labels.websites),
path: '/admin/websites',
icon: <Globe />,
},
{
id: 'teams',
label: formatMessage(labels.teams),
path: '/admin/teams',
icon: <Users />,
},
],
},
];
const selectedKey = items
.flatMap(e => e.items)
?.find(({ path }) => path && pathname.startsWith(path))?.id;
return (
<SideMenu
items={items}
title={formatMessage(labels.admin)}
selectedKey={selectedKey}
allowMinimize={false}
onItemClick={onItemClick}
/>
);
}

View file

@ -1,50 +1,10 @@
'use client';
import { PageBody } from '@/components/common/PageBody';
import { SideMenu } from '@/components/common/SideMenu';
import { useMessages, useNavigation } from '@/components/hooks';
import { Settings2, UserCircle, Users } from '@/components/icons';
import { Column, Grid } from '@umami/react-zen';
import { ReactNode } from 'react';
import { SettingsNav } from './SettingsNav';
export function SettingsLayout({ children }: { children: ReactNode }) {
const { formatMessage, labels } = useMessages();
const { renderUrl, pathname } = useNavigation();
const items = [
{
label: formatMessage(labels.application),
items: [
{
id: 'preferences',
label: formatMessage(labels.preferences),
path: renderUrl('/settings/preferences'),
icon: <Settings2 />,
},
],
},
{
label: formatMessage(labels.account),
items: [
{
id: 'profile',
label: formatMessage(labels.profile),
path: renderUrl('/settings/profile'),
icon: <UserCircle />,
},
{
id: 'teams',
label: formatMessage(labels.teams),
path: renderUrl('/settings/teams'),
icon: <Users />,
},
],
},
];
const selectedKey = items
.flatMap(e => e.items)
.find(({ path }) => path && pathname.includes(path.split('?')[0]))?.id;
return (
<Grid columns={{ xs: '1fr', lg: 'auto 1fr' }} width="100%" height="100%">
<Column
@ -55,12 +15,7 @@ export function SettingsLayout({ children }: { children: ReactNode }) {
backgroundColor
marginRight="2"
>
<SideMenu
items={items}
title={formatMessage(labels.settings)}
selectedKey={selectedKey}
allowMinimize={false}
/>
<SettingsNav />
</Column>
<Column gap="6" margin="2">
<PageBody>{children}</PageBody>

View file

@ -0,0 +1,53 @@
import { SideMenu } from '@/components/common/SideMenu';
import { useMessages, useNavigation } from '@/components/hooks';
import { Settings2, UserCircle, Users } from '@/components/icons';
export function SettingsNav({ onItemClick }: { onItemClick?: () => void }) {
const { formatMessage, labels } = useMessages();
const { renderUrl, pathname } = useNavigation();
const items = [
{
label: formatMessage(labels.application),
items: [
{
id: 'preferences',
label: formatMessage(labels.preferences),
path: renderUrl('/settings/preferences'),
icon: <Settings2 />,
},
],
},
{
label: formatMessage(labels.account),
items: [
{
id: 'profile',
label: formatMessage(labels.profile),
path: renderUrl('/settings/profile'),
icon: <UserCircle />,
},
{
id: 'teams',
label: formatMessage(labels.teams),
path: renderUrl('/settings/teams'),
icon: <Users />,
},
],
},
];
const selectedKey = items
.flatMap(e => e.items)
.find(({ path }) => path && pathname.includes(path.split('?')[0]))?.id;
return (
<SideMenu
items={items}
title={formatMessage(labels.settings)}
selectedKey={selectedKey}
allowMinimize={false}
onItemClick={onItemClick}
/>
);
}