Enhance date handling in RecentMailingStatsChart

- Import additional Dayjs plugins for UTC and timezone support.
- Update start and end dates to reflect the start and end of the day.
- Fetch mailing statistics using formatted date strings in the correct timezone.
- Modify statistics aggregation to include all dates in the range.
- Change aggregation method from `reduce` to `forEach`.
- Update x-axis value formatter to use UTC date formatting.
This commit is contained in:
David Headrick 2025-04-07 21:09:14 -05:00
parent 5e85b9e596
commit c14b33c77b

View File

@ -1,61 +1,84 @@
import { useState, useEffect } from 'react';
import { Box, Typography } from '@mui/material';
import { BarChart } from '@mui/x-charts/BarChart';
import dayjs from 'dayjs';
import dayjs from 'dayjs'; // Import Dayjs for date handling
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
import MailingStatistic from '@/types/mailingStatistic';
dayjs.extend(utc);
dayjs.extend(timezone);
export default function RecentMailingStatsChart({ days = 7 }: { days?: number }) {
const [stats, setStats] = useState<MailingStatistic[]>([]);
const [loading, setLoading] = useState(true);
const startDate = dayjs().subtract(days, 'day').format('YYYY-MM-DD');
const endDate = dayjs().format('YYYY-MM-DD');
//startDate = '2025-02-12';
//endDate = '2025-02-26'
const fetchStats = async () => {
try {
const response = await fetch(`/api/mailings/status/s%2Csd/stats?startDate=${startDate}&endDate=${endDate}`);
const data: MailingStatistic[] = await response.json();
setStats(data);
} catch (error) {
console.error('Error fetching mailing stats:', error);
} finally {
setLoading(false);
}
};
const startDate = dayjs().subtract(days, 'day').startOf('day');
const endDate = dayjs().endOf('day');
const startDateString = dayjs.utc(startDate).tz("America/Chicago").format("YYYY-M-D");
const endDateString = dayjs.utc(endDate).tz("America/Chicago").format("YYYY-M-D")
useEffect(() => {
const fetchStats = async () => {
try {
const response = await fetch(`/api/mailings/status/s%2Csd/stats?startDate=${startDateString}&endDate=${endDateString}`);
const data: MailingStatistic[] = await response.json();
setStats(data);
} catch (error) {
console.error('Error fetching mailing stats:', error);
} finally {
setLoading(false);
}
};
fetchStats();
const intervalId = setInterval(fetchStats, 5000);
return () => clearInterval(intervalId);
}, [days]);
}, [days, startDateString, endDateString]);
if (loading) {
return <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}>Loading...</Box>;
}
const aggregatedStats: Record<string, {
sentCount: number;
deliveredCount: number;
failedCount: number;
bounceCount: number;
blockedCount: number;
invalidCount: number
}> = {};
let currentDate = startDate;
const endDateFormatted = endDate.format('YYYY-MM-DD');
// Include all dates from startDate to endDate (today)
while (!currentDate.isAfter(endDate, 'day')) {
const dateStr = currentDate.format('YYYY-MM-DD');
aggregatedStats[dateStr] = {
sentCount: 0,
deliveredCount: 0,
failedCount: 0,
bounceCount: 0,
blockedCount: 0,
invalidCount: 0,
};
currentDate = currentDate.add(1, 'day');
}
// Aggregate stats by date
const aggregatedStats = stats.reduce((acc, stat) => {
const dateStr = stat.sentDate ? dayjs(stat.sentDate).format('YYYY-MM-DD') : dayjs().format('YYYY-MM-DD');
if (!acc[dateStr]) {
acc[dateStr] = {
sentCount: 0,
deliveredCount: 0,
failedCount: 0,
bounceCount: 0,
blockedCount: 0,
invalidCount: 0,
};
stats.forEach(stat => {
const dateStr = stat.sentDate ? dayjs(stat.sentDate).format('YYYY-MM-DD') : endDateFormatted;
if (aggregatedStats[dateStr]) {
aggregatedStats[dateStr].sentCount += stat.sendCount;
aggregatedStats[dateStr].deliveredCount += stat.deliveredCount;
aggregatedStats[dateStr].failedCount += stat.failedCount;
aggregatedStats[dateStr].bounceCount += stat.bounceCount;
aggregatedStats[dateStr].blockedCount += stat.blockedCount;
aggregatedStats[dateStr].invalidCount += stat.invalidCount;
}
acc[dateStr].sentCount += stat.sendCount;
acc[dateStr].deliveredCount += stat.deliveredCount;
acc[dateStr].failedCount += stat.failedCount;
acc[dateStr].bounceCount += stat.bounceCount;
acc[dateStr].blockedCount += stat.blockedCount;
acc[dateStr].invalidCount += stat.invalidCount;
return acc;
}, {} as Record<string, { sentCount: number; deliveredCount: number; failedCount: number; bounceCount: number; blockedCount: number; invalidCount: number }>);
});
// Prepare chart data, sorted by date ascending
const sortedDates = Object.keys(aggregatedStats).sort((a, b) => dayjs(a).isBefore(dayjs(b)) ? -1 : 1);
@ -103,7 +126,7 @@ export default function RecentMailingStatsChart({ days = 7 }: { days?: number })
{
scaleType: 'band',
data: dates,
valueFormatter: (value) => dayjs(value).format("MMM DD"),
valueFormatter: (value) => dayjs.utc(value).format("MMM DD"),
},
]}
/>