"use client"; import { useState } from "react"; import { Box, Card, CardContent, Typography, IconButton, Alert, CircularProgress, } from "@mui/material"; import MoreVertIcon from "@mui/icons-material/MoreVert"; import CalendarTodayIcon from "@mui/icons-material/CalendarToday"; import { Range } from "react-date-range"; import { DateRangePicker } from "../DateRangePicker/DateRangePicker"; import { StatItem } from "./components/StatItem"; import { DEFAULT_DATE_RANGE } from "./constants"; import { IHealthData } from "@/app/services/health"; import { useDebouncedDateRange } from "@/app/hooks/useDebouncedDateRange"; import { dashboardService } from "@/app/services/dashboardService"; import { normalizeDateRangeForAPI } from "@/app/utils/formatDate"; import "./GeneralHealthCard.scss"; interface IGeneralHealthCardProps { initialHealthData?: IHealthData | null; initialStats?: Array<{ label: string; value: string | number; change: string; }> | null; initialDateRange?: Range[]; } const DEBOUNCE_MS = 1000; export const GeneralHealthCard = ({ initialHealthData = null, initialStats = null, initialDateRange, }: IGeneralHealthCardProps) => { const [healthData, setHealthData] = useState( initialHealthData ); const [error, setError] = useState(null); const [isLoading, setIsLoading] = useState(false); /** * Fetch health data for a given range */ const fetchHealthData = async (range: Range[]) => { if (!range || !range[0]) return; const startDate = range[0]?.startDate; const endDate = range[0]?.endDate; if (!startDate || !endDate) return; setError(null); setIsLoading(true); try { // Normalize dates to ensure full day coverage const { dateStart, dateEnd } = normalizeDateRangeForAPI( startDate, endDate ); // This will update the service and notify all subscribers const { healthData } = await dashboardService.fetchDashboardData({ dateStart, dateEnd, }); setHealthData(healthData); } catch (err) { const message = err instanceof Error ? err.message : "Failed to fetch health data"; setError(message); setHealthData(null); } finally { setIsLoading(false); } }; const { dateRange, handleDateRangeChange } = useDebouncedDateRange({ initialDateRange: initialDateRange ?? DEFAULT_DATE_RANGE, debounceMs: DEBOUNCE_MS, onDateRangeChange: fetchHealthData, skipInitialFetch: !!initialHealthData, }); /** * Resolve stats source */ const stats = healthData?.stats ?? initialStats ?? [ { label: "TOTAL", value: 0, change: "0%" }, { label: "SUCCESSFUL", value: 0, change: "0%" }, { label: "ACCEPTANCE RATE", value: "0%", change: "0%" }, { label: "AMOUNT", value: "€0.00", change: "0%" }, { label: "ATV", value: "€0.00", change: "0%" }, ]; return ( General Health {error && ( {error} )} {isLoading ? ( ) : ( !error && ( {stats.map((item, i) => ( ))} ) )} ); };