mirror of
https://github.com/umami-software/umami.git
synced 2026-02-04 04:37:11 +01:00
New mobile menu.
This commit is contained in:
parent
be5f0494cc
commit
10bc2895eb
6 changed files with 90 additions and 32 deletions
|
|
@ -1,10 +1,10 @@
|
||||||
'use client';
|
'use client';
|
||||||
import { Grid, Loading, Column, Row, List, ListItem } from '@umami/react-zen';
|
import { Grid, Loading, Column, Row } from '@umami/react-zen';
|
||||||
import Script from 'next/script';
|
import Script from 'next/script';
|
||||||
import { UpdateNotice } from './UpdateNotice';
|
import { UpdateNotice } from './UpdateNotice';
|
||||||
import { SideNav } from '@/app/(main)/SideNav';
|
import { SideNav } from '@/app/(main)/SideNav';
|
||||||
import { useLoginQuery, useConfig, useNavigation } from '@/components/hooks';
|
import { useLoginQuery, useConfig, useNavigation } from '@/components/hooks';
|
||||||
import { MobileMenuButton } from '@/components/input/MobileMenuButton';
|
import { MobileNav } from '@/app/(main)/MobileNav';
|
||||||
|
|
||||||
export function App({ children }) {
|
export function App({ children }) {
|
||||||
const { user, isLoading, error } = useLoginQuery();
|
const { user, isLoading, error } = useLoginQuery();
|
||||||
|
|
@ -29,15 +29,9 @@ export function App({ children }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid columns={{ xs: '1fr', lg: 'auto 1fr' }} height="100vh" width="100%" backgroundColor="2">
|
<Grid columns={{ xs: '1fr', lg: 'auto 1fr' }} height="100vh" width="100%">
|
||||||
<Row display={{ xs: 'flex', lg: 'none' }} alignItems="center" gap padding>
|
<Row display={{ xs: 'flex', lg: 'none' }} alignItems="center" gap padding="3">
|
||||||
<MobileMenuButton>
|
<MobileNav />
|
||||||
<List>
|
|
||||||
<ListItem>Websites</ListItem>
|
|
||||||
<ListItem>Links</ListItem>
|
|
||||||
<ListItem>Pixels</ListItem>
|
|
||||||
</List>
|
|
||||||
</MobileMenuButton>
|
|
||||||
</Row>
|
</Row>
|
||||||
<Column display={{ xs: 'none', lg: 'flex' }}>
|
<Column display={{ xs: 'none', lg: 'flex' }}>
|
||||||
<SideNav />
|
<SideNav />
|
||||||
|
|
|
||||||
77
src/app/(main)/MobileNav.tsx
Normal file
77
src/app/(main)/MobileNav.tsx
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
import {
|
||||||
|
Row,
|
||||||
|
Dialog,
|
||||||
|
DialogTrigger,
|
||||||
|
Button,
|
||||||
|
Icon,
|
||||||
|
Modal,
|
||||||
|
NavMenu,
|
||||||
|
NavMenuItem,
|
||||||
|
IconLabel,
|
||||||
|
Text,
|
||||||
|
Grid,
|
||||||
|
} from '@umami/react-zen';
|
||||||
|
import { Globe, Grid2x2, LinkIcon, Menu } 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';
|
||||||
|
|
||||||
|
export function MobileNav() {
|
||||||
|
const { formatMessage, labels } = useMessages();
|
||||||
|
const { websiteId } = useNavigation();
|
||||||
|
|
||||||
|
const links = [
|
||||||
|
{
|
||||||
|
id: 'websites',
|
||||||
|
label: formatMessage(labels.websites),
|
||||||
|
path: '/websites',
|
||||||
|
icon: <Globe />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'links',
|
||||||
|
label: formatMessage(labels.links),
|
||||||
|
path: '/links',
|
||||||
|
icon: <LinkIcon />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'pixels',
|
||||||
|
label: formatMessage(labels.pixels),
|
||||||
|
path: '/pixels',
|
||||||
|
icon: <Grid2x2 />,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Grid columns="auto 1fr" flexGrow={1}>
|
||||||
|
<DialogTrigger>
|
||||||
|
<Button>
|
||||||
|
<Icon>
|
||||||
|
<Menu />
|
||||||
|
</Icon>
|
||||||
|
</Button>
|
||||||
|
<Modal position="left" offset="80px">
|
||||||
|
<Dialog variant="sheet">
|
||||||
|
<NavMenu padding="3">
|
||||||
|
{links.map(link => {
|
||||||
|
return (
|
||||||
|
<Link key={link.id} href={link.path}>
|
||||||
|
<NavMenuItem>
|
||||||
|
<IconLabel icon={link.icon} label={link.label} />
|
||||||
|
</NavMenuItem>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</NavMenu>
|
||||||
|
{websiteId && <WebsiteNav websiteId={websiteId} />}
|
||||||
|
</Dialog>
|
||||||
|
</Modal>
|
||||||
|
</DialogTrigger>
|
||||||
|
<Row alignItems="center" justifyContent="center" flexGrow={1}>
|
||||||
|
<IconLabel icon={<Logo />} style={{ width: 'auto' }}>
|
||||||
|
<Text weight="bold">umami</Text>
|
||||||
|
</IconLabel>
|
||||||
|
</Row>
|
||||||
|
</Grid>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -12,6 +12,7 @@ export function WebsiteLayout({ websiteId, children }: { websiteId: string; chil
|
||||||
<Grid columns={{ xs: '1fr', lg: 'auto 1fr' }} width="100%" height="100%">
|
<Grid columns={{ xs: '1fr', lg: 'auto 1fr' }} width="100%" height="100%">
|
||||||
<Column
|
<Column
|
||||||
display={{ xs: 'none', lg: 'flex' }}
|
display={{ xs: 'none', lg: 'flex' }}
|
||||||
|
width="240px"
|
||||||
height="100%"
|
height="100%"
|
||||||
border="right"
|
border="right"
|
||||||
backgroundColor
|
backgroundColor
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,6 @@ export function SideMenu({
|
||||||
<Column
|
<Column
|
||||||
gap
|
gap
|
||||||
padding
|
padding
|
||||||
width="240px"
|
|
||||||
overflowY="auto"
|
overflowY="auto"
|
||||||
justifyContent="space-between"
|
justifyContent="space-between"
|
||||||
position="sticky"
|
position="sticky"
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
import { Button, Icon, DialogTrigger, Dialog, Modal } from '@umami/react-zen';
|
|
||||||
import { Menu } from '@/components/icons';
|
|
||||||
import { ReactNode } from 'react';
|
|
||||||
|
|
||||||
export function MobileMenuButton({ children }: { children: ReactNode }) {
|
|
||||||
return (
|
|
||||||
<DialogTrigger>
|
|
||||||
<Button>
|
|
||||||
<Icon>
|
|
||||||
<Menu />
|
|
||||||
</Icon>
|
|
||||||
</Button>
|
|
||||||
<Modal position="left" offset="20px">
|
|
||||||
<Dialog variant="sheet">{children}</Dialog>
|
|
||||||
</Modal>
|
|
||||||
</DialogTrigger>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Select, SelectProps, ListItem, Text, Row } from '@umami/react-zen';
|
import { Select, SelectProps, ListItem, Text, Row } from '@umami/react-zen';
|
||||||
import { useUserWebsitesQuery, useMessages, useLoginQuery, useWebsite } from '@/components/hooks';
|
import {
|
||||||
|
useUserWebsitesQuery,
|
||||||
|
useMessages,
|
||||||
|
useLoginQuery,
|
||||||
|
useWebsiteQuery,
|
||||||
|
} from '@/components/hooks';
|
||||||
import { Empty } from '@/components/common/Empty';
|
import { Empty } from '@/components/common/Empty';
|
||||||
|
|
||||||
export function WebsiteSelect({
|
export function WebsiteSelect({
|
||||||
|
|
@ -15,7 +20,7 @@ export function WebsiteSelect({
|
||||||
includeTeams?: boolean;
|
includeTeams?: boolean;
|
||||||
} & SelectProps) {
|
} & SelectProps) {
|
||||||
const { formatMessage, messages } = useMessages();
|
const { formatMessage, messages } = useMessages();
|
||||||
const website = useWebsite();
|
const { data: website } = useWebsiteQuery(websiteId);
|
||||||
const [name, setName] = useState<string>(website?.name);
|
const [name, setName] = useState<string>(website?.name);
|
||||||
const [search, setSearch] = useState('');
|
const [search, setSearch] = useState('');
|
||||||
const { user } = useLoginQuery();
|
const { user } = useLoginQuery();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue