Upgraded next to 13. Fixed date filter for websites.

This commit is contained in:
Mike Cao 2023-03-08 20:23:32 -08:00
parent 9b90036401
commit 0607e9f442
19 changed files with 201 additions and 296 deletions

View file

@ -12,15 +12,15 @@ export default function FilterLink({ id, value, label, externalUrl }) {
return (
<div className={styles.row}>
<Link href={resolveUrl({ [id]: value })} replace>
<a
className={classNames(styles.label, {
[styles.inactive]: active && !selected,
[styles.active]: active && selected,
})}
>
{safeDecodeURI(label || value)}
</a>
<Link
href={resolveUrl({ [id]: value })}
className={classNames(styles.label, {
[styles.inactive]: active && !selected,
[styles.active]: active && selected,
})}
replace
>
{safeDecodeURI(label || value)}
</Link>
{externalUrl && (
<a className={styles.link} href={externalUrl} target="_blank" rel="noreferrer noopener">

View file

@ -16,10 +16,8 @@ export default function MobileMenu({ items = [], onClose }) {
</div>
<div className={styles.items}>
{items.map(({ label, value }) => (
<Link key={value} href={value}>
<a className={styles.item} onClick={onClose}>
{label}
</a>
<Link key={value} href={value} className={styles.item} onClick={onClose}>
{label}
</Link>
))}
</div>

View file

@ -7,15 +7,13 @@ export default function LogoutButton({ tooltipPosition = 'top' }) {
const { formatMessage } = useIntl();
return (
<Link href="/logout">
<a>
<Tooltip label={formatMessage(labels.logout)} position={tooltipPosition}>
<Button variant="quiet">
<Icon>
<Icons.Logout />
</Icon>
</Button>
</Tooltip>
</a>
<Tooltip label={formatMessage(labels.logout)} position={tooltipPosition}>
<Button variant="quiet">
<Icon>
<Icons.Logout />
</Icon>
</Button>
</Tooltip>
</Link>
);
}

View file

@ -11,13 +11,11 @@ export default function Header() {
<header className={styles.header}>
<Row>
<Column>
<Link href="https://umami.is" target="_blank">
<a className={styles.title}>
<Icon size="lg">
<Icons.Logo />
</Icon>
<Text>umami</Text>
</a>
<Link href="https://umami.is" target="_blank" className={styles.title}>
<Icon size="lg">
<Icons.Logo />
</Icon>
<Text>umami</Text>
</Link>
</Column>
<Column className={styles.buttons}>

View file

@ -1,38 +0,0 @@
import { useRouter } from 'next/router';
import classNames from 'classnames';
import NavMenu from 'components/common/NavMenu';
import styles from './MenuLayout.module.css';
export default function MenuLayout({
menu,
selectedOption,
className,
menuClassName,
contentClassName,
children,
replace = false,
}) {
const router = useRouter();
function handleSelect(url) {
if (replace) {
router.replace(url, undefined, { shallow: true });
} else {
router.push(url, undefined, { shallow: true });
}
}
return (
<div className={classNames(styles.container, className, 'row')}>
<NavMenu
options={menu}
selectedOption={selectedOption}
className={classNames(styles.menu, menuClassName, 'col-12 col-lg-2')}
onSelect={handleSelect}
/>
<div className={classNames(styles.content, contentClassName, 'col-12 col-lg-10')}>
{children}
</div>
</div>
);
}

View file

@ -1,38 +0,0 @@
.container {
display: flex;
flex: 1;
height: 100%;
}
.container .menu {
padding: 30px 0;
border: 0;
}
.container .content {
flex: 1;
position: relative;
border-left: 1px solid var(--base300);
padding-left: 30px;
margin-left: 30px;
}
@media only screen and (max-width: 992px) {
.container {
flex-direction: column;
height: auto;
}
.container .menu {
display: flex;
justify-content: space-around;
align-items: flex-start;
}
.container .content {
border-top: 1px solid var(--base300);
border-left: 0;
padding-left: 0;
margin-left: 0;
}
}

View file

@ -102,6 +102,8 @@ export const labels = defineMessages({
poweredBy: { id: 'label.powered-by', defaultMessage: 'Powered by {name}' },
pageViews: { id: 'label.page-views', defaultMessage: 'Page views' },
uniqueVisitors: { id: 'label.unique-visitors', defaultMessage: 'Unique visitors' },
bounceRate: { id: 'label.bounce-rate', defaultMessage: 'Bounce rate' },
averageVisitTime: { id: 'label.average-visit-time', defaultMessage: 'Average visit time' },
});
export const messages = defineMessages({

View file

@ -1,16 +1,17 @@
import { useState } from 'react';
import { Loading } from 'react-basics';
import { FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import { useIntl } from 'react-intl';
import ErrorMessage from 'components/common/ErrorMessage';
import useApi from 'hooks/useApi';
import useDateRange from 'hooks/useDateRange';
import usePageQuery from 'hooks/usePageQuery';
import { formatShortTime, formatNumber, formatLongNumber } from 'lib/format';
import MetricCard from './MetricCard';
import { labels } from 'components/messages';
import styles from './MetricsBar.module.css';
export default function MetricsBar({ websiteId, className }) {
export default function MetricsBar({ websiteId }) {
const { formatMessage } = useIntl();
const { get, useQuery } = useApi();
const [dateRange] = useDateRange(websiteId);
const { startDate, endDate, modified } = dateRange;
@ -52,25 +53,25 @@ export default function MetricsBar({ websiteId, className }) {
};
return (
<div className={classNames(styles.bar, className)} onClick={handleSetFormat}>
<div className={styles.bar} onClick={handleSetFormat}>
{isLoading && !isFetched && <Loading icon="dots" />}
{error && <ErrorMessage />}
{data && !error && isFetched && (
<>
<MetricCard
label={<FormattedMessage id="metrics.views" defaultMessage="Views" />}
label={formatMessage(labels.views)}
value={pageviews.value}
change={pageviews.change}
format={formatFunc}
/>
<MetricCard
label={<FormattedMessage id="metrics.visitors" defaultMessage="Visitors" />}
label={formatMessage(labels.visitors)}
value={uniques.value}
change={uniques.change}
format={formatFunc}
/>
<MetricCard
label={<FormattedMessage id="metrics.bounce-rate" defaultMessage="Bounce rate" />}
label={formatMessage(labels.bounceRate)}
value={uniques.value ? (num / uniques.value) * 100 : 0}
change={
uniques.value && uniques.change
@ -82,12 +83,7 @@ export default function MetricsBar({ websiteId, className }) {
reverseColors
/>
<MetricCard
label={
<FormattedMessage
id="metrics.average-visit-time"
defaultMessage="Average visit time"
/>
}
label={formatMessage(labels.averageVisitTime)}
value={
totaltime.value && pageviews.value
? totaltime.value / (pageviews.value - bounces.value)

View file

@ -80,14 +80,12 @@ export default function MetricsTable({
<div className={styles.footer}>
{data && !error && limit && (
<Link href={router.pathname} as={resolveUrl({ view: type })}>
<a>
<Button variant="quiet">
<Text>{formatMessage(messages.more)}</Text>
<Icon size="sm">
<Icons.ArrowRight />
</Icon>
</Button>
</a>
<Button variant="quiet">
<Text>{formatMessage(messages.more)}</Text>
<Icon size="sm">
<Icons.ArrowRight />
</Icon>
</Button>
</Link>
)}
</div>

View file

@ -71,14 +71,12 @@ export default function WebsiteChart({
<WebsiteHeader websiteId={websiteId} title={title} domain={domain}>
{showDetailsButton && (
<Link href={`/websites/${websiteId}`}>
<a>
<Button>
<Text>{formatMessage(labels.viewDetails)}</Text>
<Icon>
<Icons.ArrowRight />
</Icon>
</Button>
</a>
<Button>
<Text>{formatMessage(labels.viewDetails)}</Text>
<Icon>
<Icons.ArrowRight />
</Icon>
</Button>
</Link>
)}
</WebsiteHeader>

View file

@ -59,26 +59,25 @@ export default function TestConsole() {
<Column xs="4">
<div className={styles.header}>Page links</div>
<div>
<Link href={`/console/${websiteId}?page=1`}>
<a>page one</a>
</Link>
<Link href={`/console/${websiteId}?page=1`}>page one</Link>
</div>
<div>
<Link href={`/console/${websiteId}?page=2`}>
<a>page two</a>
</Link>
<Link href={`/console/${websiteId}?page=2`}>page two</Link>
</div>
<div>
<Link href={`https://www.google.com`}>
<a className="umami--click--external-link-direct">external link (direct)</a>
</Link>
<a href="https://www.google.com" className="umami--click--external-link-direct">
external link (direct)
</a>
</div>
<div>
<Link href={`https://www.google.com`}>
<a className="umami--click--external-link-tab" target="_blank">
external link (tab)
</a>
</Link>
<a
href="https://www.google.com"
className="umami--click--external-link-tab"
target="_blank"
rel="noreferrer"
>
external link (tab)
</a>
</div>
</Column>
<Column xs="4">

View file

@ -49,14 +49,12 @@ export default function TeamsTable({ data = [], onDelete }) {
action: (
<Flexbox flex={1} gap={10} justifyContent="end">
<Link href={`/settings/teams/${id}`}>
<a>
<Button>
<Icon>
<Icons.Edit />
</Icon>
<Text>{formatMessage(labels.edit)}</Text>
</Button>
</a>
<Button>
<Icon>
<Icons.Edit />
</Icon>
<Text>{formatMessage(labels.edit)}</Text>
</Button>
</Link>
<ModalTrigger>
<Button>

View file

@ -59,15 +59,13 @@ export default function WebsiteSettings({ websiteId }) {
</Breadcrumbs>
}
>
<Link href={`/analytics/websites/${websiteId}`}>
<a target="_blank">
<Button variant="primary">
<Icon>
<Icons.External />
</Icon>
<Text>{formatMessage(labels.view)}</Text>
</Button>
</a>
<Link href={`/analytics/websites/${websiteId}`} target="_blank">
<Button variant="primary">
<Icon>
<Icons.External />
</Icon>
<Text>{formatMessage(labels.view)}</Text>
</Button>
</Link>
</PageHeader>
<Tabs selectedKey={tab} onSelect={setTab} style={{ marginBottom: 30 }}>

View file

@ -42,24 +42,20 @@ export default function WebsitesTable({ data = [] }) {
row.action = (
<Flexbox flex={1} justifyContent="end" gap={10}>
<Link href={`/settings/websites/${id}`}>
<a>
<Button>
<Icon>
<Icons.Edit />
</Icon>
<Text>{formatMessage(labels.edit)}</Text>
</Button>
</a>
<Button>
<Icon>
<Icons.Edit />
</Icon>
<Text>{formatMessage(labels.edit)}</Text>
</Button>
</Link>
<Link href={`/websites/${id}`}>
<a>
<Button>
<Icon>
<Icons.External />
</Icon>
<Text>{formatMessage(labels.view)}</Text>
</Button>
</a>
<Button>
<Icon>
<Icons.External />
</Icon>
<Text>{formatMessage(labels.view)}</Text>
</Button>
</Link>
</Flexbox>
);

View file

@ -86,22 +86,20 @@ export default function WebsiteMenuView({ websiteId, websiteDomain }) {
<GridRow>
<GridColumn xs={12} sm={12} md={12} defaultSize={3} className={styles.menu}>
<Link href={resolveUrl({ view: undefined })}>
<a>
<Flexbox justifyContent="center">
<Button variant="quiet">
<Icon rotate={180}>
<Icons.ArrowRight />
</Icon>
<Text>{formatMessage(labels.back)}</Text>
</Button>
</Flexbox>
</a>
<Flexbox justifyContent="center">
<Button variant="quiet">
<Icon rotate={180}>
<Icons.ArrowRight />
</Icon>
<Text>{formatMessage(labels.back)}</Text>
</Button>
</Flexbox>
</Link>
<Menu items={items} selectedKey={view}>
{({ key, label }) => (
<Item key={key} className={styles.item}>
<Link href={resolveUrl({ view: key })} shallow={true}>
<a>{label}</a>
{label}
</Link>
</Item>
)}