import { ReactNode } from 'react'; import { Grid, Row, Column, Text, Icon } from '@umami/react-zen'; import { Users } from '@/components/icons'; import { useMessages, useLocale, useResultQuery } from '@/components/hooks'; import { formatDate } from '@/lib/date'; import { formatLongNumber } from '@/lib/format'; import { Panel } from '@/components/common/Panel'; import { LoadingPanel } from '@/components/common/LoadingPanel'; const DAYS = [1, 2, 3, 4, 5, 6, 7, 14, 21, 28]; export interface RetentionProps { websiteId: string; startDate: Date; endDate: Date; days?: number[]; } export function Retention({ websiteId, days = DAYS, startDate, endDate }: RetentionProps) { const { formatMessage, labels } = useMessages(); const { locale } = useLocale(); const { data, error, isLoading } = useResultQuery('retention', { websiteId, startDate, endDate, }); const rows = data?.reduce((arr: any[], row: { date: any; visitors: any; day: any }) => { const { date, visitors, day } = row; if (day === 0) { return arr.concat({ date, visitors, records: days .reduce((arr, day) => { arr[day] = data.find( (x: { date: any; day: number }) => x.date === date && x.day === day, ); return arr; }, []) .filter(n => n), }); } return arr; }, []) || []; const totalDays = rows.length; return ( {data && ( {formatMessage(labels.cohort)} {days.map(n => ( {formatMessage(labels.day)} {n} ))} {rows.map(({ date, visitors, records }: any, rowIndex: number) => { return ( {formatDate(date, 'PP', locale)} {formatLongNumber(visitors)} {days.map(day => { if (totalDays - rowIndex < day) { return null; } const percentage = records.filter(a => a.day === day)[0]?.percentage; return ( {percentage ? `${Number(percentage).toFixed(2)}%` : ''} ); })} ); })} )} ); } const Cell = ({ children }: { children: ReactNode }) => { return ( {children} ); };