From c4cfe2f389c83852e578f04e3b2801fbd418b68a Mon Sep 17 00:00:00 2001 From: Max Kowalski Date: Sat, 28 Jun 2025 00:39:35 +0200 Subject: [PATCH] fix: enhance date range calculations and optimize date range change handling --- app/api/dashboard/metrics/route.ts | 21 ++++++++++++++++----- app/dashboard/overview/page.tsx | 19 +++++++++++-------- components/DateRangePicker.tsx | 27 +++++++++++++++++++++++---- 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/app/api/dashboard/metrics/route.ts b/app/api/dashboard/metrics/route.ts index 6b6c2cd..b0facf6 100644 --- a/app/api/dashboard/metrics/route.ts +++ b/app/api/dashboard/metrics/route.ts @@ -91,13 +91,24 @@ export async function GET(request: NextRequest) { const metrics = sessionMetrics(chatSessions, companyConfigForMetrics); - // Calculate date range from sessions + // Calculate date range from ALL sessions (not filtered) to get the full available range let dateRange: { minDate: string; maxDate: string } | null = null; - if (prismaSessions.length > 0) { - const dates = prismaSessions.map(s => new Date(s.startTime)).sort((a, b) => a.getTime() - b.getTime()); + const allSessions = await prisma.session.findMany({ + where: { + companyId: user.companyId, + }, + select: { + startTime: true, + }, + orderBy: { + startTime: 'asc', + }, + }); + + if (allSessions.length > 0) { dateRange = { - minDate: dates[0].toISOString().split('T')[0], // First session date - maxDate: dates[dates.length - 1].toISOString().split('T')[0] // Last session date + minDate: allSessions[0].startTime.toISOString().split('T')[0], // First session date + maxDate: allSessions[allSessions.length - 1].startTime.toISOString().split('T')[0] // Last session date }; } diff --git a/app/dashboard/overview/page.tsx b/app/dashboard/overview/page.tsx index 65fbdb5..718891f 100644 --- a/app/dashboard/overview/page.tsx +++ b/app/dashboard/overview/page.tsx @@ -84,12 +84,15 @@ function DashboardContent() { } }; - // Handle date range changes + // Handle date range changes with proper memoization const handleDateRangeChange = useCallback((startDate: string, endDate: string) => { - setSelectedStartDate(startDate); - setSelectedEndDate(endDate); - fetchMetrics(startDate, endDate); - }, []); + // Only update if dates actually changed to prevent unnecessary API calls + if (startDate !== selectedStartDate || endDate !== selectedEndDate) { + setSelectedStartDate(startDate); + setSelectedEndDate(endDate); + fetchMetrics(startDate, endDate); + } + }, [selectedStartDate, selectedEndDate]); useEffect(() => { // Redirect if not authenticated @@ -329,8 +332,8 @@ function DashboardContent() { - {/* Date Range Picker - Temporarily disabled to debug infinite loop */} - {/* {dateRange && ( + {/* Date Range Picker */} + {dateRange && ( - )} */} + )} {/* Modern Metrics Grid */}
diff --git a/components/DateRangePicker.tsx b/components/DateRangePicker.tsx index 4b70a0a..e26f23b 100644 --- a/components/DateRangePicker.tsx +++ b/components/DateRangePicker.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState, useEffect } from "react"; +import { useState, useEffect, useRef, memo } from "react"; interface DateRangePickerProps { minDate: string; @@ -10,7 +10,7 @@ interface DateRangePickerProps { initialEndDate?: string; } -export default function DateRangePicker({ +function DateRangePicker({ minDate, maxDate, onDateRangeChange, @@ -19,10 +19,26 @@ export default function DateRangePicker({ }: DateRangePickerProps) { const [startDate, setStartDate] = useState(initialStartDate || minDate); const [endDate, setEndDate] = useState(initialEndDate || maxDate); + const isInitializedRef = useRef(false); useEffect(() => { - // Only notify parent component when dates change, not when the callback changes - onDateRangeChange(startDate, endDate); + // Update local state when props change (e.g., when date range is loaded from API) + if (initialStartDate && initialStartDate !== startDate) { + setStartDate(initialStartDate); + } + if (initialEndDate && initialEndDate !== endDate) { + setEndDate(initialEndDate); + } + }, [initialStartDate, initialEndDate]); + + useEffect(() => { + // Only notify parent component after initial render and when dates actually change + // This prevents the infinite loop by not including onDateRangeChange in dependencies + if (isInitializedRef.current) { + onDateRangeChange(startDate, endDate); + } else { + isInitializedRef.current = true; + } }, [startDate, endDate]); const handleStartDateChange = (newStartDate: string) => { @@ -151,3 +167,6 @@ export default function DateRangePicker({
); } + +// Export memoized component as default +export default memo(DateRangePicker);