umami/components/pages/reports/retention/RetentionTable.js

79 lines
2.3 KiB
JavaScript
Raw Normal View History

2023-08-04 20:10:03 +00:00
import { useContext } from 'react';
2023-08-16 17:50:28 +00:00
import classNames from 'classnames';
2023-08-04 20:10:03 +00:00
import { ReportContext } from '../Report';
2023-08-13 03:13:11 +00:00
import EmptyPlaceholder from 'components/common/EmptyPlaceholder';
2023-08-15 05:36:18 +00:00
import { useMessages } from 'hooks';
2023-08-16 17:50:28 +00:00
import { formatDate } from 'lib/date';
2023-08-13 03:13:11 +00:00
import styles from './RetentionTable.module.css';
2023-08-04 20:10:03 +00:00
export function RetentionTable() {
2023-08-15 05:36:18 +00:00
const { formatMessage, labels } = useMessages();
2023-08-04 20:10:03 +00:00
const { report } = useContext(ReportContext);
2023-08-13 03:13:11 +00:00
const { data } = report || {};
2023-08-07 21:01:53 +00:00
2023-08-13 03:13:11 +00:00
if (!data) {
return <EmptyPlaceholder />;
}
2023-08-17 10:21:20 +00:00
const days = [1, 2, 3, 4, 5, 6, 7, 14, 21, 28];
const rows = data.reduce((arr, row) => {
const { date, visitors, day } = row;
if (day === 0) {
return arr.concat({
date,
visitors,
records: days
.reduce((arr, day) => {
arr[day] = data.find(x => x.date === date && x.day === day);
return arr;
}, [])
.filter(n => n),
});
2023-08-13 03:13:11 +00:00
}
return arr;
}, []);
2023-08-17 10:21:20 +00:00
const totalDays = rows.length;
2023-08-13 03:13:11 +00:00
return (
<>
<div className={styles.table}>
2023-08-16 17:50:28 +00:00
<div className={classNames(styles.row, styles.header)}>
2023-08-15 05:36:18 +00:00
<div className={styles.date}>{formatMessage(labels.date)}</div>
2023-08-16 17:50:28 +00:00
<div className={styles.visitors}>{formatMessage(labels.visitors)}</div>
{days.map(n => (
<div key={n} className={styles.day}>
{formatMessage(labels.day)} {n}
2023-08-13 03:13:11 +00:00
</div>
))}
</div>
2023-08-17 10:21:20 +00:00
{rows.map(({ date, visitors, records }, rowIndex) => {
2023-08-13 03:13:11 +00:00
return (
2023-08-17 10:21:20 +00:00
<div key={rowIndex} className={styles.row}>
2023-08-16 17:50:28 +00:00
<div className={styles.date}>{formatDate(`${date} 00:00:00`, 'PP')}</div>
<div className={styles.visitors}>{visitors}</div>
2023-08-17 10:21:20 +00:00
{days.map(day => {
if (totalDays - rowIndex < day) {
return null;
}
const percentage = records[day]?.percentage;
2023-08-13 03:13:11 +00:00
return (
2023-08-17 10:21:20 +00:00
<div
key={day}
className={classNames(styles.cell, { [styles.empty]: !percentage })}
>
{percentage ? `${percentage.toFixed(2)}%` : ''}
2023-08-13 03:13:11 +00:00
</div>
);
})}
</div>
);
})}
</div>
</>
);
}
2023-08-04 20:10:03 +00:00
export default RetentionTable;