Update Retention report.

This commit is contained in:
Mike Cao 2025-06-28 21:16:50 -07:00
parent 184a387ecd
commit ee8750d9df
22 changed files with 214 additions and 280 deletions

View file

@ -62,7 +62,7 @@ export function Panel({
<Button variant="quiet" onPress={handleFullscreen}>
<Icon>{isFullscreen ? <Close /> : <Maximize />}</Icon>
</Button>
<Tooltip>{formatMessage(labels.expand)}</Tooltip>
<Tooltip>{formatMessage(labels.maximize)}</Tooltip>
</TooltipTrigger>
</Row>
)}

View file

@ -22,7 +22,7 @@ export function useDateRange(websiteId?: string) {
);
const dateRange = useMemo(
() => (offset ? getOffsetDateRange(dateRangeObject, +offset) : dateRangeObject),
[date, offset],
[date, offset, websiteConfig],
);
const dateCompare = useWebsites(state => state[websiteId]?.dateCompare || DEFAULT_DATE_COMPARE);

View file

@ -8,7 +8,7 @@ export function useFilterParams(websiteId: string) {
const { timezone, toUtc } = useTimezone();
const {
query: {
url,
path,
referrer,
title,
query,
@ -29,7 +29,7 @@ export function useFilterParams(websiteId: string) {
endAt: +toUtc(endDate),
unit,
timezone,
url,
path,
referrer,
title,
query,

View file

@ -99,7 +99,7 @@ export function DateFilter({
};
return (
<Row width="280px">
<Row minWidth="200px">
<Select
value={value}
placeholder={formatMessage(labels.selectDate)}

View file

@ -1,70 +1,47 @@
import { Row, Text, Icon, Button, MenuTrigger, Popover, Menu, MenuItem } from '@umami/react-zen';
import { startOfMonth, endOfMonth, startOfYear, addMonths, subYears } from 'date-fns';
import { Chevron } from '@/components/icons';
import { Row, Select, ListItem } from '@umami/react-zen';
import { useLocale } from '@/components/hooks';
import { formatDate } from '@/lib/date';
export function MonthSelect({ date = new Date(), onChange }) {
const { locale } = useLocale();
const month = formatDate(date, 'MMMM', locale);
const month = date.getMonth();
const year = date.getFullYear();
const currentYear = new Date().getFullYear();
// eslint-disable-next-line
const handleChange = (close: () => void, date: Date) => {
onChange(`range:${startOfMonth(date).getTime()}:${endOfMonth(date).getTime()}`);
close();
const months = [...Array(12)].map((_, i) => i);
const years = [...Array(10)].map((_, i) => currentYear - i);
const handleMonthChange = (month: number) => {
const d = new Date(date);
d.setMonth(month);
onChange?.(d);
};
const handleYearChange = (year: number) => {
const d = new Date(date);
d.setFullYear(year);
onChange?.(d);
};
const start = startOfYear(date);
const months: Date[] = [];
for (let i = 0; i < 12; i++) {
months.push(addMonths(start, i));
}
const years: number[] = [];
for (let i = 0; i < 10; i++) {
years.push(subYears(start, 10 - i).getFullYear());
}
return (
<Row>
<MenuTrigger>
<Button variant="quiet">
<Text>{month}</Text>
<Icon size="sm">
<Chevron />
</Icon>
</Button>
<Popover>
<Menu>
{months.map(month => {
return (
<MenuItem key={month.toString()} id={month.toString()}>
{month.getDay()}
</MenuItem>
);
})}
</Menu>
</Popover>
</MenuTrigger>
<MenuTrigger>
<Button variant="quiet">
<Text>{year}</Text>
<Icon size="sm">
<Chevron />
</Icon>
</Button>
<Popover>
<Menu>
{years.map(year => {
return (
<MenuItem key={year} id={year}>
{year}
</MenuItem>
);
})}
</Menu>
</Popover>
</MenuTrigger>
<Row gap>
<Select value={month} onChange={handleMonthChange}>
{months.map(m => {
return (
<ListItem id={m} key={m}>
{formatDate(new Date(year, m, 1), 'MMMM', locale)}
</ListItem>
);
})}
</Select>
<Select value={year} onChange={handleYearChange}>
{years.map(y => {
return (
<ListItem id={y} key={y}>
{y}
</ListItem>
);
})}
</Select>
</Row>
);
}

View file

@ -55,7 +55,7 @@ export function WebsiteDateFilter({
};
return (
<Row gap="3">
<Row gap>
{showButtons && !isAllTime && !isCustomRange && (
<Row gap="1">
<Button onPress={() => handleIncrement(-1)} variant="outline">

View file

@ -0,0 +1,17 @@
import { useDateRange } from '@/components/hooks';
import { dateToRangeValue } from '@/lib/date';
import { MonthSelect } from './MonthSelect';
export function WebsiteMonthSelect({ websiteId }: { websiteId: string }) {
const {
dateRange: { startDate },
saveDateRange,
} = useDateRange(websiteId);
const handleMonthSelect = (date: Date) => {
const range = dateToRangeValue(date);
saveDateRange(range);
};
return <MonthSelect date={startDate} onChange={handleMonthSelect} />;
}

View file

@ -271,7 +271,7 @@ export const labels = defineMessages({
defaultMessage: 'Track your campaigns through UTM parameters.',
},
conversionStep: { id: 'label.conversion-step', defaultMessage: 'Conversion step' },
conversionRate: { id: 'label.conversion-ratep', defaultMessage: 'Conversion rate' },
conversionRate: { id: 'label.conversion-rate', defaultMessage: 'Conversion rate' },
steps: { id: 'label.steps', defaultMessage: 'Steps' },
startStep: { id: 'label.start-step', defaultMessage: 'Start Step' },
endStep: { id: 'label.end-step', defaultMessage: 'End Step' },
@ -325,7 +325,7 @@ export const labels = defineMessages({
pixels: { id: 'label.pixels', defaultMessage: 'Pixels' },
addBoard: { id: 'label.add-board', defaultMessage: 'Add board' },
cohort: { id: 'label.cohort', defaultMessage: 'Cohort' },
expand: { id: 'label.expand', defaultMessage: 'Expand' },
maximize: { id: 'label.maximize', defaultMessage: 'Maximize' },
remaining: { id: 'label.remaining', defaultMessage: 'Remaining' },
conversion: { id: 'label.conversion', defaultMessage: 'Conversion' },
firstClick: { id: 'label.first-click', defaultMessage: 'First click' },