Progress check-in for date compare.

This commit is contained in:
Mike Cao 2024-05-23 19:35:29 -07:00
parent 24af06f3aa
commit 8cf7985dac
25 changed files with 181 additions and 61 deletions

View file

@ -26,7 +26,7 @@ export function BarChart(props: BarChartProps) {
stacked = false,
} = props;
const options = useMemo(() => {
const options: any = useMemo(() => {
return {
scales: {
x: {

View file

@ -79,15 +79,19 @@ export function Chart({
};
const updateChart = (data: any) => {
chart.current.data.datasets.forEach((dataset: { data: any }, index: string | number) => {
if (data?.datasets[index]) {
dataset.data = data?.datasets[index]?.data;
if (data.datasets.length === chart.current.data.datasets.length) {
chart.current.data.datasets.forEach((dataset: { data: any }, index: string | number) => {
if (data?.datasets[index]) {
dataset.data = data?.datasets[index]?.data;
if (chart.current.legend.legendItems[index]) {
chart.current.legend.legendItems[index].text = data?.datasets[index]?.label;
if (chart.current.legend.legendItems[index]) {
chart.current.legend.legendItems[index].text = data?.datasets[index]?.label;
}
}
}
});
});
} else {
chart.current.data.datasets = data.datasets;
}
chart.current.options = options;

View file

@ -4,14 +4,15 @@ import { useFilterParams } from '..//useFilterParams';
export function useWebsitePageviews(
websiteId: string,
compare?: string,
options?: Omit<UseQueryOptions, 'queryKey' | 'queryFn'>,
) {
const { get, useQuery } = useApi();
const params = useFilterParams(websiteId);
return useQuery({
queryKey: ['websites:pageviews', { websiteId, ...params }],
queryFn: () => get(`/websites/${websiteId}/pageviews`, params),
queryKey: ['websites:pageviews', { websiteId, ...params, compare }],
queryFn: () => get(`/websites/${websiteId}/pageviews`, { ...params, compare }),
enabled: !!websiteId,
...options,
});

View file

@ -1,19 +1,25 @@
import { getMinimumUnit, parseDateRange } from 'lib/date';
import { setItem } from 'next-basics';
import { DATE_RANGE_CONFIG, DEFAULT_DATE_RANGE } from 'lib/constants';
import websiteStore, { setWebsiteDateRange } from 'store/websites';
import { DATE_RANGE_CONFIG, DEFAULT_DATE_COMPARE, DEFAULT_DATE_RANGE } from 'lib/constants';
import websiteStore, { setWebsiteDateRange, setWebsiteDateCompare } from 'store/websites';
import appStore, { setDateRange } from 'store/app';
import { DateRange } from 'lib/types';
import { useLocale } from './useLocale';
import { useApi } from './queries/useApi';
export function useDateRange(websiteId?: string): [DateRange, (value: string | DateRange) => void] {
export function useDateRange(websiteId?: string): {
dateRange: DateRange;
saveDateRange: (value: string | DateRange) => void;
dateCompare: string;
saveDateCompare: (value: string) => void;
} {
const { get } = useApi();
const { locale } = useLocale();
const websiteConfig = websiteStore(state => state[websiteId]?.dateRange);
const defaultConfig = DEFAULT_DATE_RANGE;
const globalConfig = appStore(state => state.dateRange);
const dateRange = parseDateRange(websiteConfig || globalConfig || defaultConfig, locale);
const dateCompare = websiteStore(state => state[websiteId]?.dateCompare || DEFAULT_DATE_COMPARE);
const saveDateRange = async (value: DateRange | string) => {
if (websiteId) {
@ -45,7 +51,11 @@ export function useDateRange(websiteId?: string): [DateRange, (value: string | D
}
};
return [dateRange, saveDateRange];
const saveDateCompare = (value: string) => {
setWebsiteDateCompare(websiteId, value);
};
return { dateRange, saveDateRange, dateCompare, saveDateCompare };
}
export default useDateRange;

View file

@ -4,7 +4,7 @@ import { useTimezone } from './useTimezone';
import { zonedTimeToUtc } from 'date-fns-tz';
export function useFilterParams(websiteId: string) {
const [dateRange] = useDateRange(websiteId);
const { dateRange } = useDateRange(websiteId);
const { startDate, endDate, unit } = dateRange;
const { timezone } = useTimezone();
const {

View file

@ -12,7 +12,7 @@ export function RefreshButton({
isLoading?: boolean;
}) {
const { formatMessage, labels } = useMessages();
const [dateRange] = useDateRange(websiteId);
const { dateRange } = useDateRange(websiteId);
function handleClick() {
if (!isLoading && dateRange) {

View file

@ -8,17 +8,17 @@ import { DateRange } from 'lib/types';
export function WebsiteDateFilter({ websiteId }: { websiteId: string }) {
const { dir } = useLocale();
const [dateRange, setDateRange] = useDateRange(websiteId);
const { dateRange, saveDateRange } = useDateRange(websiteId);
const { value, startDate, endDate, offset } = dateRange;
const disableForward =
value === 'all' || isAfter(getOffsetDateRange(dateRange, 1).startDate, new Date());
const handleChange = (value: string | DateRange) => {
setDateRange(value);
saveDateRange(value);
};
const handleIncrement = (increment: number) => {
setDateRange(getOffsetDateRange(dateRange, increment));
saveDateRange(getOffsetDateRange(dateRange, increment));
};
return (

View file

@ -13,7 +13,9 @@ export interface EventsChartProps {
}
export function EventsChart({ websiteId, className }: EventsChartProps) {
const [{ startDate, endDate, unit }] = useDateRange(websiteId);
const {
dateRange: { startDate, endDate, unit },
} = useDateRange(websiteId);
const { locale } = useLocale();
const { data, isLoading } = useWebsiteEvents(websiteId);

View file

@ -24,7 +24,7 @@ export function FilterTags({
}) {
const { formatMessage, labels } = useMessages();
const { formatValue } = useFormat();
const [dateRange] = useDateRange(websiteId);
const { dateRange } = useDateRange(websiteId);
const {
router,
renderUrl,

View file

@ -5,13 +5,9 @@
min-width: 150px;
}
.card.compare {
gap: 10px;
}
.card.compare .change {
font-size: 16px;
padding: 5px 10px;
margin: 10px 0;
}
.card:first-child {
@ -23,7 +19,7 @@
}
.value {
font-size: 40px;
font-size: 36px;
font-weight: 700;
white-space: nowrap;
color: var(--base900);
@ -46,7 +42,7 @@
gap: 5px;
font-size: 13px;
font-weight: 700;
padding: 0 5px;
padding: 0.1em 0.5em;
border-radius: 5px;
color: var(--base500);
align-self: flex-start;

View file

@ -48,7 +48,7 @@ export const MetricCard = ({
[styles.hide]: ~~change === 0,
})}
>
<Icon rotate={positive ? -45 : 45} size={showPrevious ? 'sm' : 'xs'}>
<Icon rotate={positive || reverseColors ? -45 : 45} size={showPrevious ? 'md' : 'xs'}>
<Icons.ArrowRight />
</Icon>
<animated.span title={changeProps?.x as any}>

View file

@ -5,8 +5,12 @@ import { renderDateLabels } from 'lib/charts';
export interface PageviewsChartProps extends BarChartProps {
data: {
sessions: any[];
pageviews: any[];
sessions: any[];
compare?: {
pageviews: any[];
sessions: any[];
};
};
unit: string;
isLoading?: boolean;
@ -36,7 +40,25 @@ export function PageviewsChart({ data, unit, isLoading, ...props }: PageviewsCha
borderWidth: 1,
...colors.chart.views,
},
],
data.compare
? {
type: 'line',
label: formatMessage(labels.visitors),
data: data.compare.pageviews,
borderWidth: 2,
borderColor: '#f15bb5',
}
: null,
data.compare
? {
type: 'line',
label: formatMessage(labels.visits),
data: data.compare.sessions,
borderWidth: 2,
borderColor: '#9b5de5',
}
: null,
].filter(n => n),
};
}, [data, locale]);