From c14b33c77b0c960f1c8e665df01ed5cde2e9e32d Mon Sep 17 00:00:00 2001 From: David Headrick Date: Mon, 7 Apr 2025 21:09:14 -0500 Subject: [PATCH] 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. --- .../widgets/RecentMailingStatsChart.tsx | 99 ++++++++++++------- 1 file changed, 61 insertions(+), 38 deletions(-) diff --git a/Surge365.MassEmailReact.Web/src/components/widgets/RecentMailingStatsChart.tsx b/Surge365.MassEmailReact.Web/src/components/widgets/RecentMailingStatsChart.tsx index c47904c..16ee0ec 100644 --- a/Surge365.MassEmailReact.Web/src/components/widgets/RecentMailingStatsChart.tsx +++ b/Surge365.MassEmailReact.Web/src/components/widgets/RecentMailingStatsChart.tsx @@ -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([]); 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 Loading...; } + const aggregatedStats: Record = {}; + + 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); + }); // 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"), }, ]} />