104 lines
2.8 KiB
TypeScript
104 lines
2.8 KiB
TypeScript
'use client';
|
|
|
|
import { useCallback, useEffect, useState } from 'react';
|
|
import { getLocalDayIsoRange } from '@/components/appointments/appointmentTime';
|
|
import {
|
|
loadTodayChartPeriods,
|
|
saveTodayChartPeriods,
|
|
type TodayChartPeriod,
|
|
type TodayChartPeriodKey,
|
|
type TodayChartPeriods,
|
|
TODAY_CHART_PERIOD_DEFAULTS,
|
|
} from '@/components/today/chart-periods';
|
|
import { todayApi } from '@/lib/api/today';
|
|
import type { TodaySummaryData } from '@/types/today';
|
|
import type { ApiError } from '@/types/api';
|
|
|
|
interface UseTodaySummaryResult {
|
|
data: TodaySummaryData | null;
|
|
loading: boolean;
|
|
isInitialLoad: boolean;
|
|
error: ApiError | null;
|
|
chartPeriods: TodayChartPeriods;
|
|
setChartPeriod: (key: TodayChartPeriodKey, period: TodayChartPeriod) => void;
|
|
reload: () => Promise<void>;
|
|
}
|
|
|
|
export function useTodaySummary(organizationId?: string | null): UseTodaySummaryResult {
|
|
const enabled = Boolean(organizationId);
|
|
const [data, setData] = useState<TodaySummaryData | null>(null);
|
|
const [loading, setLoading] = useState(enabled);
|
|
const [error, setError] = useState<ApiError | null>(null);
|
|
const [chartPeriods, setChartPeriods] = useState<TodayChartPeriods>(() =>
|
|
organizationId ? loadTodayChartPeriods(organizationId) : TODAY_CHART_PERIOD_DEFAULTS,
|
|
);
|
|
|
|
useEffect(() => {
|
|
if (!organizationId) {
|
|
setChartPeriods(TODAY_CHART_PERIOD_DEFAULTS);
|
|
return;
|
|
}
|
|
setChartPeriods(loadTodayChartPeriods(organizationId));
|
|
}, [organizationId]);
|
|
|
|
const reload = useCallback(async () => {
|
|
if (!organizationId) {
|
|
setData(null);
|
|
setLoading(false);
|
|
setError(null);
|
|
return;
|
|
}
|
|
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const range = getLocalDayIsoRange(new Date());
|
|
const utcOffsetMinutes = -new Date().getTimezoneOffset();
|
|
const response = await todayApi.summary({
|
|
...range,
|
|
utcOffsetMinutes,
|
|
chartPeriods,
|
|
});
|
|
setData(response.data);
|
|
} catch (err) {
|
|
setError(err as ApiError);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, [organizationId, chartPeriods]);
|
|
|
|
useEffect(() => {
|
|
setData(null);
|
|
setError(null);
|
|
if (!organizationId) {
|
|
setLoading(false);
|
|
return;
|
|
}
|
|
setLoading(true);
|
|
void reload();
|
|
}, [organizationId, reload]);
|
|
|
|
const setChartPeriod = useCallback(
|
|
(key: TodayChartPeriodKey, period: TodayChartPeriod) => {
|
|
setChartPeriods((prev) => {
|
|
if (prev[key] === period) return prev;
|
|
const next = { ...prev, [key]: period };
|
|
if (organizationId) saveTodayChartPeriods(organizationId, next);
|
|
return next;
|
|
});
|
|
},
|
|
[organizationId],
|
|
);
|
|
|
|
return {
|
|
data,
|
|
loading,
|
|
isInitialLoad: loading && !data,
|
|
error,
|
|
chartPeriods,
|
|
setChartPeriod,
|
|
reload,
|
|
};
|
|
}
|