mirror of
https://github.com/umami-software/umami.git
synced 2026-02-05 21:27:20 +01:00
Added side nav.
This commit is contained in:
parent
a8a1ccce18
commit
b53606d497
13 changed files with 239 additions and 202 deletions
|
|
@ -6,6 +6,7 @@ import { UpdateNotice } from './UpdateNotice';
|
|||
import { NavBar } from '@/app/(main)/NavBar';
|
||||
import { Page } from '@/components/layout/Page';
|
||||
import { useLogin, useConfig } from '@/components/hooks';
|
||||
import { SideNav } from '@/app/(main)/SideNav';
|
||||
|
||||
export function App({ children }) {
|
||||
const { user, isLoading, error } = useLogin();
|
||||
|
|
@ -29,15 +30,18 @@ export function App({ children }) {
|
|||
}
|
||||
|
||||
return (
|
||||
<Grid rows="auto 1fr">
|
||||
<NavBar />
|
||||
<Page>
|
||||
<UpdateNotice user={user} config={config} />
|
||||
{children}
|
||||
{process.env.NODE_ENV === 'production' && !pathname.includes('/share/') && (
|
||||
<Script src={`${process.env.basePath || ''}/telemetry.js`} />
|
||||
)}
|
||||
</Page>
|
||||
<Grid>
|
||||
<SideNav />
|
||||
<Grid rows="auto 1fr">
|
||||
<NavBar />
|
||||
<Page>
|
||||
<UpdateNotice user={user} config={config} />
|
||||
{children}
|
||||
{process.env.NODE_ENV === 'production' && !pathname.includes('/share/') && (
|
||||
<Script src={`${process.env.basePath || ''}/telemetry.js`} />
|
||||
)}
|
||||
</Page>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,42 +1,13 @@
|
|||
'use client';
|
||||
import { Icon, Text, ThemeButton, Row } from '@umami/react-zen';
|
||||
import Link from 'next/link';
|
||||
import { ThemeButton, Row } from '@umami/react-zen';
|
||||
import { LanguageButton } from '@/components/input/LanguageButton';
|
||||
import { ProfileButton } from '@/components/input/ProfileButton';
|
||||
import { TeamsButton } from '@/components/input/TeamsButton';
|
||||
import { Icons } from '@/components/icons';
|
||||
import { useMessages, useTeamUrl } from '@/components/hooks';
|
||||
|
||||
export function NavBar() {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { renderTeamUrl } = useTeamUrl();
|
||||
|
||||
const links = [
|
||||
{ label: formatMessage(labels.dashboard), url: renderTeamUrl('/dashboard') },
|
||||
{ label: formatMessage(labels.websites), url: renderTeamUrl('/websites') },
|
||||
{ label: formatMessage(labels.reports), url: renderTeamUrl('/reports') },
|
||||
{ label: formatMessage(labels.settings), url: renderTeamUrl('/settings') },
|
||||
].filter(n => n);
|
||||
|
||||
return (
|
||||
<Row justifyContent="space-between" alignItems="center" paddingX="4" paddingY="3">
|
||||
<Row alignItems="center" gap="3">
|
||||
<Icon size="md">
|
||||
<Icons.Logo />
|
||||
</Icon>
|
||||
<Text size="3" weight="bold">
|
||||
umami
|
||||
</Text>
|
||||
</Row>
|
||||
<Row gap="4">
|
||||
{links.map(({ url, label }) => {
|
||||
return (
|
||||
<Link key={url} href={url} prefetch={url !== '/settings'}>
|
||||
<Text>{label}</Text>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</Row>
|
||||
<div></div>
|
||||
<Row justifyContent="flex-end">
|
||||
<TeamsButton />
|
||||
<ThemeButton />
|
||||
|
|
|
|||
46
src/app/(main)/SideNav.module.css
Normal file
46
src/app/(main)/SideNav.module.css
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
.sidenav {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 200px;
|
||||
height: 100vh;
|
||||
background-color: var(--layer-color-1);
|
||||
border-right: 1px solid var(--layer-color-2);
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--gap);
|
||||
padding: var(--padding);
|
||||
}
|
||||
|
||||
.name {
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
|
||||
.section {
|
||||
padding: var(--spacing-3);
|
||||
gap: var(--spacing-9);
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
|
||||
.items {
|
||||
display: grid;
|
||||
gap: var(--gap);
|
||||
}
|
||||
|
||||
.item {
|
||||
color: var(--font-color-muted) !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--gap);
|
||||
padding: var(--padding);
|
||||
}
|
||||
|
||||
.item:hover {
|
||||
color: var(--font-color) !important;
|
||||
background-color: var(--layer-color-2);
|
||||
}
|
||||
81
src/app/(main)/SideNav.tsx
Normal file
81
src/app/(main)/SideNav.tsx
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import { ReactNode } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { Icon } from '@umami/react-zen';
|
||||
import { Icons } from '@/components/icons';
|
||||
import { useMessages, useTeamUrl } from '@/components/hooks';
|
||||
import styles from './SideNav.module.css';
|
||||
|
||||
export function SideNav() {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { renderTeamUrl } = useTeamUrl();
|
||||
|
||||
const links = [
|
||||
{
|
||||
label: formatMessage(labels.boards),
|
||||
href: renderTeamUrl('/boards'),
|
||||
icon: <Icons.Dashboard />,
|
||||
},
|
||||
{
|
||||
label: formatMessage(labels.dashboard),
|
||||
href: renderTeamUrl('/dashboard'),
|
||||
icon: <Icons.BarChart />,
|
||||
},
|
||||
{
|
||||
label: formatMessage(labels.websites),
|
||||
href: renderTeamUrl('/websites'),
|
||||
icon: <Icons.Globe />,
|
||||
},
|
||||
{
|
||||
label: formatMessage(labels.reports),
|
||||
href: renderTeamUrl('/reports'),
|
||||
icon: <Icons.Reports />,
|
||||
},
|
||||
{
|
||||
label: formatMessage(labels.settings),
|
||||
href: renderTeamUrl('/settings'),
|
||||
icon: <Icons.Gear />,
|
||||
},
|
||||
].filter(n => n);
|
||||
|
||||
return (
|
||||
<div className={styles.sidenav}>
|
||||
<SideNavSection>
|
||||
<SideNavHeader />
|
||||
</SideNavSection>
|
||||
<SideNavSection>
|
||||
{links.map(props => {
|
||||
return <SideNavItem key={props.href} {...props} />;
|
||||
})}
|
||||
</SideNavSection>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const SideNavHeader = () => {
|
||||
return (
|
||||
<div className={styles.header}>
|
||||
<Icon size="sm">
|
||||
<Icons.Logo />
|
||||
</Icon>
|
||||
<div className={styles.name}>umami</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const SideNavSection = ({ title, children }: { title?: string; children: ReactNode }) => {
|
||||
return (
|
||||
<div className={styles.section}>
|
||||
{title && <div className={styles.title}>{title}</div>}
|
||||
<div className={styles.items}>{children}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const SideNavItem = ({ href, label, icon }: { href: string; label: string; icon: ReactNode }) => {
|
||||
return (
|
||||
<Link href={href} className={styles.item}>
|
||||
<Icon size="sm">{icon}</Icon>
|
||||
{label}
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
9
src/app/(main)/boards/Board.tsx
Normal file
9
src/app/(main)/boards/Board.tsx
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import { Column, Heading } from '@umami/react-zen';
|
||||
|
||||
export function Board() {
|
||||
return (
|
||||
<Column>
|
||||
<Heading>Board title</Heading>
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
import { Board } from './Board';
|
||||
|
||||
export function BoardsPage() {
|
||||
return <h1>hi.</h1>;
|
||||
return <Board />;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import '@/styles/variables.css';
|
|||
|
||||
export default function ({ children }) {
|
||||
return (
|
||||
<html lang="en" data-scroll="0">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||
|
|
|
|||
|
|
@ -297,6 +297,7 @@ export const labels = defineMessages({
|
|||
paidVideo: { id: 'label.paid-video', defaultMessage: 'Paid video' },
|
||||
grouped: { id: 'label.grouped', defaultMessage: 'Grouped' },
|
||||
other: { id: 'label.other', defaultMessage: 'Other' },
|
||||
boards: { id: 'label.boards', defaultMessage: 'Boards' },
|
||||
});
|
||||
|
||||
export const messages = defineMessages({
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ body {
|
|||
color: var(--font-color);
|
||||
font-size: var(--font-size);
|
||||
background-color: var(--background-color);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
a,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue