mirror of
https://github.com/umami-software/umami.git
synced 2026-02-10 23:57:12 +01:00
Updated navigation.
This commit is contained in:
parent
611169c65f
commit
fc2a8f3d9f
13 changed files with 156 additions and 123 deletions
|
|
@ -1,15 +1,21 @@
|
|||
.layout {
|
||||
display: grid;
|
||||
grid-template-rows: 1fr;
|
||||
grid-template-columns: max-content 1fr;
|
||||
grid-template-rows: max-content 1fr;
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.nav {
|
||||
grid-row: 1 / 3;
|
||||
height: 60px;
|
||||
width: 100vw;
|
||||
z-index: 100;
|
||||
grid-column: 1;
|
||||
grid-row: 1 / 2;
|
||||
}
|
||||
|
||||
.body {
|
||||
grid-area: 1 / 2;
|
||||
overflow: auto;
|
||||
height: 100vh;
|
||||
grid-column: 1;
|
||||
grid-row: 2 / 3;
|
||||
min-height: 0;
|
||||
max-height: calc(100vh - 60px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,69 +1,50 @@
|
|||
import { useState } from 'react';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { Icon, Text } from 'react-basics';
|
||||
import Link from 'next/link';
|
||||
import classNames from 'classnames';
|
||||
import Icons from 'components/icons';
|
||||
import ThemeButton from 'components/input/ThemeButton';
|
||||
import LanguageButton from 'components/input/LanguageButton';
|
||||
import LogoutButton from 'components/input/LogoutButton';
|
||||
import { labels } from 'components/messages';
|
||||
import useUser from 'hooks/useUser';
|
||||
import NavGroup from './NavGroup';
|
||||
import ProfileButton from 'components/input/ProfileButton';
|
||||
import styles from './NavBar.module.css';
|
||||
import useConfig from 'hooks/useConfig';
|
||||
import useMessages from 'hooks/useMessages';
|
||||
|
||||
export default function NavBar() {
|
||||
const { user } = useUser();
|
||||
const { cloudMode } = useConfig();
|
||||
const { formatMessage } = useIntl();
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const [minimized, setMinimized] = useState(false);
|
||||
const tooltipPosition = minimized ? 'right' : 'top';
|
||||
|
||||
const analytics = [
|
||||
const links = [
|
||||
{ label: formatMessage(labels.dashboard), url: '/dashboard', icon: <Icons.Dashboard /> },
|
||||
{ label: formatMessage(labels.realtime), url: '/realtime', icon: <Icons.Clock /> },
|
||||
];
|
||||
|
||||
const settings = [
|
||||
!cloudMode && {
|
||||
label: formatMessage(labels.websites),
|
||||
url: '/settings/websites',
|
||||
icon: <Icons.Globe />,
|
||||
},
|
||||
user?.isAdmin && {
|
||||
label: formatMessage(labels.users),
|
||||
url: '/settings/users',
|
||||
icon: <Icons.User />,
|
||||
},
|
||||
!cloudMode && {
|
||||
label: formatMessage(labels.teams),
|
||||
url: '/settings/teams',
|
||||
icon: <Icons.Users />,
|
||||
},
|
||||
{ label: formatMessage(labels.profile), url: '/settings/profile', icon: <Icons.Profile /> },
|
||||
!cloudMode && { label: formatMessage(labels.settings), url: '/settings', icon: <Icons.Gear /> },
|
||||
].filter(n => n);
|
||||
|
||||
const handleMinimize = () => setMinimized(state => !state);
|
||||
|
||||
return (
|
||||
<div className={classNames(styles.navbar, { [styles.minimized]: minimized })}>
|
||||
<div className={styles.header} onClick={handleMinimize}>
|
||||
<div className={styles.logo} onClick={handleMinimize}>
|
||||
<Icon size="lg">
|
||||
<Icons.Logo />
|
||||
</Icon>
|
||||
<Text className={styles.text}>umami</Text>
|
||||
<Icon size="sm" rotate={minimized ? -90 : 90} className={styles.icon}>
|
||||
<Icons.ChevronDown />
|
||||
</Icon>
|
||||
</div>
|
||||
<NavGroup title={formatMessage(labels.analytics)} items={analytics} minimized={minimized} />
|
||||
<NavGroup title={formatMessage(labels.settings)} items={settings} minimized={minimized} />
|
||||
<div className={styles.footer}>
|
||||
<div className={styles.buttons}>
|
||||
<ThemeButton tooltipPosition={tooltipPosition} />
|
||||
<LanguageButton tooltipPosition={tooltipPosition} />
|
||||
{!cloudMode && <LogoutButton tooltipPosition={tooltipPosition} />}
|
||||
</div>
|
||||
<div className={styles.links}>
|
||||
{links.map(({ url, icon, label }) => {
|
||||
return (
|
||||
<Link key={url} href={url}>
|
||||
<Icon>{icon}</Icon>
|
||||
<Text>{label}</Text>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className={styles.actions}>
|
||||
<ThemeButton />
|
||||
<LanguageButton />
|
||||
{!cloudMode && <ProfileButton />}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,62 +1,49 @@
|
|||
.navbar {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
height: 60px;
|
||||
background: var(--base75);
|
||||
height: 100%;
|
||||
width: 200px;
|
||||
border-right: 2px solid var(--base200);
|
||||
border-bottom: 1px solid var(--base200);
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.header {
|
||||
.logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
padding: 20px 0;
|
||||
cursor: pointer;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.header:hover .icon {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.icon {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
right: -10px;
|
||||
border-radius: 100%;
|
||||
color: var(--base50);
|
||||
background: var(--base800);
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.minimized.navbar {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.minimized .text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.footer {
|
||||
flex: 1;
|
||||
.links {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
padding: 20px;
|
||||
flex-direction: row;
|
||||
gap: 20px;
|
||||
padding: 0 40px;
|
||||
flex: 1;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
.links a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
color: var(--font-color100);
|
||||
}
|
||||
|
||||
.minimized .buttons {
|
||||
flex-direction: column;
|
||||
.links a:hover {
|
||||
color: var(--primary400);
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
min-width: 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import classNames from 'classnames';
|
||||
import styles from './Page.module.css';
|
||||
import { Banner, Loading } from 'react-basics';
|
||||
import styles from './Page.module.css';
|
||||
|
||||
export default function Page({ className, error, loading, children }) {
|
||||
if (error) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue