New overview layout.
Some checks failed
Node.js CI / build (postgresql, 18.18) (push) Has been cancelled

This commit is contained in:
Mike Cao 2025-08-29 00:17:59 -07:00
parent bab4f8ebcc
commit 5f27ba149b
5 changed files with 45 additions and 42 deletions

View file

@ -52,12 +52,12 @@ export function WebsiteExpandedView({
items: [
{
id: 'referrer',
label: formatMessage(labels.referrers),
label: formatMessage(labels.referrer),
path: updateParams({ view: 'referrer' }),
},
{
id: 'channel',
label: formatMessage(labels.channels),
label: formatMessage(labels.channel),
path: updateParams({ view: 'channel' }),
},
{
@ -72,17 +72,17 @@ export function WebsiteExpandedView({
items: [
{
id: 'country',
label: formatMessage(labels.countries),
label: formatMessage(labels.country),
path: updateParams({ view: 'country' }),
},
{
id: 'region',
label: formatMessage(labels.regions),
label: formatMessage(labels.region),
path: updateParams({ view: 'region' }),
},
{
id: 'city',
label: formatMessage(labels.cities),
label: formatMessage(labels.city),
path: updateParams({ view: 'city' }),
},
],
@ -92,7 +92,7 @@ export function WebsiteExpandedView({
items: [
{
id: 'browser',
label: formatMessage(labels.browsers),
label: formatMessage(labels.browser),
path: updateParams({ view: 'browser' }),
},
{
@ -102,17 +102,17 @@ export function WebsiteExpandedView({
},
{
id: 'device',
label: formatMessage(labels.devices),
label: formatMessage(labels.device),
path: updateParams({ view: 'device' }),
},
{
id: 'language',
label: formatMessage(labels.languages),
label: formatMessage(labels.language),
path: updateParams({ view: 'language' }),
},
{
id: 'screen',
label: formatMessage(labels.screens),
label: formatMessage(labels.screen),
path: updateParams({ view: 'screen' }),
},
],
@ -122,7 +122,7 @@ export function WebsiteExpandedView({
items: [
{
id: 'event',
label: formatMessage(labels.events),
label: formatMessage(labels.event),
path: updateParams({ view: 'event' }),
},
{
@ -132,7 +132,7 @@ export function WebsiteExpandedView({
},
{
id: 'tag',
label: formatMessage(labels.tags),
label: formatMessage(labels.tag),
path: updateParams({ view: 'tag' }),
},
],

View file

@ -59,30 +59,7 @@ export function WebsitePanels({ websiteId }: { websiteId: string }) {
</Tabs>
</Panel>
</GridRow>
<GridRow layout="two-one" {...rowProps}>
<Panel gridColumn="span 2" noPadding>
<WorldMap websiteId={websiteId} />
</Panel>
<Panel>
<Heading size="2">{formatMessage(labels.location)}</Heading>
<Tabs>
<TabList>
<Tab id="country">{formatMessage(labels.countries)}</Tab>
<Tab id="region">{formatMessage(labels.regions)}</Tab>
<Tab id="city">{formatMessage(labels.cities)}</Tab>
</TabList>
<TabPanel id="country">
<MetricsTable type="country" title={formatMessage(labels.country)} {...tableProps} />
</TabPanel>
<TabPanel id="region">
<MetricsTable type="region" title={formatMessage(labels.region)} {...tableProps} />
</TabPanel>
<TabPanel id="city">
<MetricsTable type="city" title={formatMessage(labels.city)} {...tableProps} />
</TabPanel>
</Tabs>
</Panel>
</GridRow>
<GridRow layout="two" {...rowProps}>
<Panel>
<Heading size="2">{formatMessage(labels.environment)}</Heading>
@ -103,6 +80,33 @@ export function WebsitePanels({ websiteId }: { websiteId: string }) {
</TabPanel>
</Tabs>
</Panel>
<Panel>
<Heading size="2">{formatMessage(labels.location)}</Heading>
<Tabs>
<TabList>
<Tab id="country">{formatMessage(labels.countries)}</Tab>
<Tab id="region">{formatMessage(labels.regions)}</Tab>
<Tab id="city">{formatMessage(labels.cities)}</Tab>
</TabList>
<TabPanel id="country">
<MetricsTable type="country" title={formatMessage(labels.country)} {...tableProps} />
</TabPanel>
<TabPanel id="region">
<MetricsTable type="region" title={formatMessage(labels.region)} {...tableProps} />
</TabPanel>
<TabPanel id="city">
<MetricsTable type="city" title={formatMessage(labels.city)} {...tableProps} />
</TabPanel>
</Tabs>
</Panel>
</GridRow>
<GridRow layout="two-one" {...rowProps}>
<Panel gridColumn="span 2" noPadding>
<WorldMap websiteId={websiteId} />
</Panel>
<Panel>
<Heading size="2">{formatMessage(labels.traffic)}</Heading>
<Row border="bottom" marginBottom="4" />

View file

@ -10,6 +10,7 @@ export interface LoadingPanelProps extends ColumnProps {
isLoading?: boolean;
isFetching?: boolean;
loadingIcon?: 'dots' | 'spinner';
loadingPosition?: 'center' | 'page' | 'inline';
renderEmpty?: () => ReactNode;
children: ReactNode;
}
@ -21,6 +22,7 @@ export function LoadingPanel({
isLoading,
isFetching,
loadingIcon = 'dots',
loadingPosition = 'page',
renderEmpty = () => <Empty />,
children,
...props
@ -32,7 +34,7 @@ export function LoadingPanel({
{/* Show loading spinner only if no data exists */}
{(isLoading || isFetching) && (
<Column position="relative" height="100%" {...props}>
<Loading icon={loadingIcon} position="page" />
<Loading icon={loadingIcon} position={loadingPosition} />
</Column>
)}

View file

@ -67,6 +67,7 @@ export function MetricsExpandedTable({
isLoading={isLoading}
error={error}
height="100%"
loadingIcon="spinner"
>
<Column overflowY="auto" minHeight="0" height="100%" paddingRight="3" overflow="hidden">
{items && (

View file

@ -5,7 +5,6 @@ import classNames from 'classnames';
import { colord } from 'colord';
import { ISO_COUNTRIES, MAP_FILE } from '@/lib/constants';
import {
useDateRange,
useWebsiteMetricsQuery,
useCountryNames,
useLocale,
@ -30,14 +29,11 @@ export function WorldMap({ websiteId, data, className, ...props }: WorldMapProps
const { countryNames } = useCountryNames(locale);
const visitorsLabel = formatMessage(labels.visitors).toLocaleLowerCase(locale);
const unknownLabel = formatMessage(labels.unknown);
const {
dateRange: { startDate, endDate },
} = useDateRange(websiteId);
const { data: mapData } = useWebsiteMetricsQuery(websiteId, {
type: 'country',
startAt: +startDate,
endAt: +endDate,
});
const metrics = useMemo(
() => (data || mapData ? percentFilter((data || mapData) as any[]) : []),
[data, mapData],