import { ResponsiveLine } from '@nivo/line';
import { Box, Flex, Skeleton, Tile, ActionButton } from '@rocket.chat/fuselage';
import moment from 'moment';
import React, { useMemo } from 'react';
import { useTranslation } from '../../../../../../client/contexts/TranslationContext';
import { useEndpointData } from '../../../../../../client/hooks/useEndpointData';
import { useFormatDate } from '../../../../../../client/hooks/useFormatDate';
import CounterSet from '../../../../../../client/components/data/CounterSet';
import { LegendSymbol } from '../data/LegendSymbol';
import { Section } from '../Section';
import { downloadCsvAs } from '../../../../../../client/lib/download';
const ActiveUsersSection = ({ timezone }) => {
const t = useTranslation();
const utc = timezone === 'utc';
const formatDate = useFormatDate();
const period = useMemo(() => ({
start: utc
? moment.utc().subtract(30, 'days')
: moment().subtract(30, 'days'),
end: utc
? moment.utc().subtract(1, 'days')
: moment().subtract(1, 'days'),
}), [utc]);
const params = useMemo(() => ({
start: period.start.clone().subtract(29, 'days').toISOString(),
end: period.end.toISOString(),
}), [period]);
const { value: data } = useEndpointData('engagement-dashboard/users/active-users', useMemo(() => params, [params]));
const [
countDailyActiveUsers,
diffDailyActiveUsers,
countWeeklyActiveUsers,
diffWeeklyActiveUsers,
countMonthlyActiveUsers,
diffMonthlyActiveUsers,
dauValues,
wauValues,
mauValues,
] = useMemo(() => {
if (!data) {
return [];
}
const createPoint = (i) => ({
x: moment(period.start).add(i, 'days').toDate(),
y: 0,
});
const createPoints = () => Array.from({ length: moment(period.end).diff(period.start, 'days') + 1 }, (_, i) => createPoint(i));
const dauValues = createPoints();
const prevDauValue = createPoint(-1);
const wauValues = createPoints();
const prevWauValue = createPoint(-1);
const mauValues = createPoints();
const prevMauValue = createPoint(-1);
const usersListsMap = data.month.reduce((map, dayData) => {
const date = utc
? moment.utc({ year: dayData.year, month: dayData.month - 1, day: dayData.day }).endOf('day')
: moment({ year: dayData.year, month: dayData.month - 1, day: dayData.day }).endOf('day');
const dateOffset = date.diff(period.start, 'days');
if (dateOffset >= 0) {
map[dateOffset] = dayData.usersList;
dauValues[dateOffset].y = dayData.users;
}
return map;
}, {});
const distributeValueOverPoints = (usersListsMap, dateOffset, T, array) => {
const usersSet = new Set();
for (let k = dateOffset; T > 0; k--, T--) {
if (usersListsMap[k]) {
usersListsMap[k].forEach((userId) => usersSet.add(userId));
}
}
array[dateOffset].y = usersSet.size;
};
for (let i = 0; i < 30; i++) {
distributeValueOverPoints(usersListsMap, i, 7, wauValues);
distributeValueOverPoints(usersListsMap, i, 30, mauValues);
}
prevWauValue.y = wauValues[28].y;
prevMauValue.y = mauValues[28].y;
prevDauValue.y = dauValues[28].y;
return [
dauValues[dauValues.length - 1].y,
dauValues[dauValues.length - 1].y - prevDauValue.y,
wauValues[wauValues.length - 1].y,
wauValues[wauValues.length - 1].y - prevWauValue.y,
mauValues[mauValues.length - 1].y,
mauValues[mauValues.length - 1].y - prevMauValue.y,
dauValues,
wauValues,
mauValues,
];
}, [data, period.end, period.start, utc]);
const downloadData = () => {
const data = [{
countDailyActiveUsers,
diffDailyActiveUsers,
countWeeklyActiveUsers,
diffWeeklyActiveUsers,
countMonthlyActiveUsers,
diffMonthlyActiveUsers,
dauValues,
wauValues,
mauValues,
}];
downloadCsvAs(data, `ActiveUsersSection_start_${ params.start }_end_${ params.end }`);
};
return }>
,
variation: data ? diffDailyActiveUsers : 0,
description: <> {t('Daily_Active_Users')}>,
},
{
count: data ? countWeeklyActiveUsers : ,
variation: data ? diffWeeklyActiveUsers : 0,
description: <> {t('Weekly_Active_Users')}>,
},
{
count: data ? countMonthlyActiveUsers : ,
variation: data ? diffMonthlyActiveUsers : 0,
description: <> {t('Monthly_Active_Users')}>,
},
]}
/>
{data
?
moment(date).format(dauValues.length === 7 ? 'dddd' : 'L'),
}}
animate={true}
motionStiffness={90}
motionDamping={15}
theme={{
// TODO: Get it from theme
axis: {
ticks: {
text: {
fill: '#9EA2A8',
fontFamily: 'Inter, -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Helvetica Neue", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Meiryo UI", Arial, sans-serif',
fontSize: '10px',
fontStyle: 'normal',
fontWeight: '600',
letterSpacing: '0.2px',
lineHeight: '12px',
},
},
},
tooltip: {
container: {
backgroundColor: '#1F2329',
boxShadow: '0px 0px 12px rgba(47, 52, 61, 0.12), 0px 0px 2px rgba(47, 52, 61, 0.08)',
borderRadius: 2,
},
},
}}
enableSlices='x'
sliceTooltip={({ slice: { points } }) =>
{formatDate(points[0].data.x)}
{points.map(({ serieId, data: { y: activeUsers } }) =>
{(serieId === 'dau' && t('DAU_value', { value: activeUsers }))
|| (serieId === 'wau' && t('WAU_value', { value: activeUsers }))
|| (serieId === 'mau' && t('MAU_value', { value: activeUsers }))}
)}
}
/>
: }
;
};
export default ActiveUsersSection;