mirror of
https://github.com/kremalicious/umami.git
synced 2024-11-22 09:57:00 +01:00
Add breadcrumb.
This commit is contained in:
parent
c807c3a8e9
commit
fa2cc5dbbd
@ -4,6 +4,7 @@ import { useMessages, useApi, useNavigation, useTeamUrl } from 'components/hooks
|
|||||||
import { ReportContext } from './Report';
|
import { ReportContext } from './Report';
|
||||||
import styles from './ReportHeader.module.css';
|
import styles from './ReportHeader.module.css';
|
||||||
import { REPORT_TYPES } from 'lib/constants';
|
import { REPORT_TYPES } from 'lib/constants';
|
||||||
|
import Breadcrumb from 'components/common/Breadcrumb';
|
||||||
|
|
||||||
export function ReportHeader({ icon }) {
|
export function ReportHeader({ icon }) {
|
||||||
const { report, updateReport } = useContext(ReportContext);
|
const { report, updateReport } = useContext(ReportContext);
|
||||||
@ -57,9 +58,16 @@ export function ReportHeader({ icon }) {
|
|||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<div>
|
<div>
|
||||||
<div className={styles.type}>
|
<div className={styles.type}>
|
||||||
{formatMessage(
|
<Breadcrumb
|
||||||
|
data={[
|
||||||
|
{ label: formatMessage(labels.reports), url: '/reports' },
|
||||||
|
{
|
||||||
|
label: formatMessage(
|
||||||
labels[Object.keys(REPORT_TYPES).find(key => REPORT_TYPES[key] === report?.type)],
|
labels[Object.keys(REPORT_TYPES).find(key => REPORT_TYPES[key] === report?.type)],
|
||||||
)}
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.title}>
|
<div className={styles.title}>
|
||||||
<Icon size="lg">{icon}</Icon>
|
<Icon size="lg">{icon}</Icon>
|
||||||
|
@ -6,6 +6,7 @@ import PageHeader from 'components/layout/PageHeader';
|
|||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from 'components/hooks';
|
||||||
import UserWebsites from './UserWebsites';
|
import UserWebsites from './UserWebsites';
|
||||||
import { UserContext } from './UserProvider';
|
import { UserContext } from './UserProvider';
|
||||||
|
import Breadcrumb from 'components/common/Breadcrumb';
|
||||||
|
|
||||||
export function UserSettings({ userId }: { userId: string }) {
|
export function UserSettings({ userId }: { userId: string }) {
|
||||||
const { formatMessage, labels, messages } = useMessages();
|
const { formatMessage, labels, messages } = useMessages();
|
||||||
@ -17,9 +18,23 @@ export function UserSettings({ userId }: { userId: string }) {
|
|||||||
showToast({ message: formatMessage(messages.saved), variant: 'success' });
|
showToast({ message: formatMessage(messages.saved), variant: 'success' });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const breadcrumb = (
|
||||||
|
<Breadcrumb
|
||||||
|
data={[
|
||||||
|
{
|
||||||
|
label: formatMessage(labels.users),
|
||||||
|
url: '/settings/users',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: user.username,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageHeader title={user?.username} icon={<Icons.User />} />
|
<PageHeader title={user?.username} icon={<Icons.User />} breadcrumb={breadcrumb} />
|
||||||
<Tabs selectedKey={tab} onSelect={setTab} style={{ marginBottom: 30, fontSize: 14 }}>
|
<Tabs selectedKey={tab} onSelect={setTab} style={{ marginBottom: 30, fontSize: 14 }}>
|
||||||
<Item key="details">{formatMessage(labels.details)}</Item>
|
<Item key="details">{formatMessage(labels.details)}</Item>
|
||||||
<Item key="websites">{formatMessage(labels.websites)}</Item>
|
<Item key="websites">{formatMessage(labels.websites)}</Item>
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
import { useState, Key, useContext } from 'react';
|
import { WebsiteContext } from 'app/(main)/websites/[websiteId]/WebsiteProvider';
|
||||||
import { Item, Tabs, Button, Text, Icon, useToasts } from 'react-basics';
|
import Breadcrumb from 'components/common/Breadcrumb';
|
||||||
import Link from 'next/link';
|
import { useMessages } from 'components/hooks';
|
||||||
import Icons from 'components/icons';
|
import Icons from 'components/icons';
|
||||||
import PageHeader from 'components/layout/PageHeader';
|
import PageHeader from 'components/layout/PageHeader';
|
||||||
import WebsiteEditForm from './WebsiteEditForm';
|
import Link from 'next/link';
|
||||||
import WebsiteData from './WebsiteData';
|
import { Key, useContext, useState } from 'react';
|
||||||
import TrackingCode from './TrackingCode';
|
import { Button, Icon, Item, Tabs, Text, useToasts } from 'react-basics';
|
||||||
import ShareUrl from './ShareUrl';
|
import ShareUrl from './ShareUrl';
|
||||||
import { useMessages } from 'components/hooks';
|
import TrackingCode from './TrackingCode';
|
||||||
import { WebsiteContext } from 'app/(main)/websites/[websiteId]/WebsiteProvider';
|
import WebsiteData from './WebsiteData';
|
||||||
|
import WebsiteEditForm from './WebsiteEditForm';
|
||||||
|
|
||||||
export function WebsiteSettings({
|
export function WebsiteSettings({
|
||||||
websiteId,
|
websiteId,
|
||||||
@ -28,9 +29,23 @@ export function WebsiteSettings({
|
|||||||
showToast({ message: formatMessage(messages.saved), variant: 'success' });
|
showToast({ message: formatMessage(messages.saved), variant: 'success' });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const breadcrumb = (
|
||||||
|
<Breadcrumb
|
||||||
|
data={[
|
||||||
|
{
|
||||||
|
label: formatMessage(labels.websites),
|
||||||
|
url: website.teamId ? `/teams/${website.teamId}/settings/websites` : '/settings/websites',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: website.name,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageHeader title={website?.name} icon={<Icons.Globe />}>
|
<PageHeader title={website?.name} icon={<Icons.Globe />} breadcrumb={breadcrumb}>
|
||||||
<Link href={`/websites/${websiteId}`} target={openExternal ? '_blank' : null}>
|
<Link href={`/websites/${websiteId}`} target={openExternal ? '_blank' : null}>
|
||||||
<Button variant="primary">
|
<Button variant="primary">
|
||||||
<Icon>
|
<Icon>
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { ReactNode } from 'react';
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Text, Button, Icon } from 'react-basics';
|
import Favicon from 'components/common/Favicon';
|
||||||
|
import { useMessages, useWebsite } from 'components/hooks';
|
||||||
|
import Icons from 'components/icons';
|
||||||
|
import ActiveUsers from 'components/metrics/ActiveUsers';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { usePathname } from 'next/navigation';
|
import { usePathname } from 'next/navigation';
|
||||||
import Favicon from 'components/common/Favicon';
|
import { ReactNode } from 'react';
|
||||||
import ActiveUsers from 'components/metrics/ActiveUsers';
|
import { Button, Icon, Text } from 'react-basics';
|
||||||
import Icons from 'components/icons';
|
|
||||||
import { useMessages, useWebsite } from 'components/hooks';
|
|
||||||
import styles from './WebsiteHeader.module.css';
|
import styles from './WebsiteHeader.module.css';
|
||||||
|
|
||||||
export function WebsiteHeader({
|
export function WebsiteHeader({
|
||||||
|
10
src/components/common/Breadcrumb.module.css
Normal file
10
src/components/common/Breadcrumb.module.css
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
.bar {
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--base600);
|
||||||
|
}
|
||||||
|
|
||||||
|
.link span {
|
||||||
|
color: var(--base700) !important;
|
||||||
|
}
|
37
src/components/common/Breadcrumb.tsx
Normal file
37
src/components/common/Breadcrumb.tsx
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import Link from 'next/link';
|
||||||
|
import { Flexbox, Icon, Icons, Text } from 'react-basics';
|
||||||
|
import styles from './Breadcrumb.module.css';
|
||||||
|
|
||||||
|
export interface BreadcrumbProps {
|
||||||
|
data: {
|
||||||
|
url?: string;
|
||||||
|
label: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Breadcrumb({ data }: BreadcrumbProps) {
|
||||||
|
return (
|
||||||
|
<Flexbox alignItems="center" gap={3} className={styles.bar}>
|
||||||
|
{data.map((a, i) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{a.url ? (
|
||||||
|
<Link href={a.url} className={styles.link}>
|
||||||
|
<Text>{a.label}</Text>
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
<Text>{a.label}</Text>
|
||||||
|
)}
|
||||||
|
{i !== data.length - 1 ? (
|
||||||
|
<Icon rotate={270}>
|
||||||
|
<Icons.ChevronDown />
|
||||||
|
</Icon>
|
||||||
|
) : null}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Flexbox>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Breadcrumb;
|
@ -27,6 +27,10 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.breadcrumb {
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
color: var(--base700);
|
color: var(--base700);
|
||||||
margin-inline-end: 1rem;
|
margin-inline-end: 1rem;
|
||||||
|
@ -7,23 +7,29 @@ export function PageHeader({
|
|||||||
title,
|
title,
|
||||||
icon,
|
icon,
|
||||||
className,
|
className,
|
||||||
|
breadcrumb,
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
title?: ReactNode;
|
title?: ReactNode;
|
||||||
icon?: ReactNode;
|
icon?: ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
breadcrumb?: ReactNode;
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
<div className={styles.breadcrumb}>{breadcrumb}</div>
|
||||||
<div className={classNames(styles.header, className)}>
|
<div className={classNames(styles.header, className)}>
|
||||||
{icon && (
|
{icon && (
|
||||||
<Icon size="lg" className={styles.icon}>
|
<Icon size="lg" className={styles.icon}>
|
||||||
{icon}
|
{icon}
|
||||||
</Icon>
|
</Icon>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{title && <div className={styles.title}>{title}</div>}
|
{title && <div className={styles.title}>{title}</div>}
|
||||||
<div className={styles.actions}>{children}</div>
|
<div className={styles.actions}>{children}</div>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user