import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { toast } from 'sonner'; import { api, ApiError, type ApiResponse } from '../lib/api'; import type { HolidayOverride, NationalHoliday, ResourceCalendarDays, ResourceException, WorkingHoursPayload, } from '../types'; function fail(e: unknown, fallback: string) { toast.error(e instanceof ApiError ? e.message : fallback); } export function useResourceCalendar(resourceUuid: string | undefined) { const qc = useQueryClient(); const key = ['resource-calendar', resourceUuid]; const query = useQuery({ queryKey: key, queryFn: () => api.get>(`/api/v1/resource/${resourceUuid}/calendar`), enabled: !!resourceUuid, }); /** PUT جایگزینی کامل است: روزی که نفرستید خالی می‌شود. */ const save = useMutation({ mutationFn: (days: WorkingHoursPayload) => api.put>(`/api/v1/resource/${resourceUuid}/calendar`, { days }), onSuccess: () => { toast.success('شیفت‌ها ذخیره شد'); qc.invalidateQueries({ queryKey: key }); }, onError: (e) => fail(e, 'ذخیرهٔ شیفت‌ها ناموفق بود'), }); return { calendar: query.data?.data, loading: query.isLoading, save }; } export function useResourceExceptions(resourceUuid: string | undefined) { const qc = useQueryClient(); const key = ['resource-exceptions', resourceUuid]; const invalidate = () => { qc.invalidateQueries({ queryKey: key }); }; const query = useQuery({ queryKey: key, queryFn: () => api.get>(`/api/v1/resource/${resourceUuid}/exceptions`), enabled: !!resourceUuid, }); const create = useMutation({ mutationFn: (d: { type: string; starts_at: number; ends_at: number; reason?: string | null }) => api.post>(`/api/v1/resource/${resourceUuid}/exception`, d), onSuccess: () => { toast.success('استثنا ثبت شد'); invalidate(); }, onError: (e) => fail(e, 'ثبت استثنا ناموفق بود'), }); const remove = useMutation({ mutationFn: (uuid: string) => api.delete>(`/api/v1/resource-exception/${uuid}`), onSuccess: () => { toast.success('استثنا حذف شد'); invalidate(); }, onError: (e) => fail(e, 'حذف استثنا ناموفق بود'), }); return { exceptions: query.data?.data ?? [], loading: query.isLoading, create, remove }; } export function useHolidays(year: number) { const qc = useQueryClient(); const key = ['national-holidays', year]; const query = useQuery({ queryKey: key, queryFn: () => api.get>( `/api/v1/national-holidays?year=${year}`, ), }); const setOverride = useMutation({ mutationFn: (d: { date: number; is_working: boolean; note?: string | null }) => api.post>('/api/v1/holiday-overrides', d), onSuccess: () => { toast.success('استثنای تعطیلی ذخیره شد'); qc.invalidateQueries({ queryKey: key }); }, onError: (e) => fail(e, 'ذخیرهٔ استثنا ناموفق بود'), }); const removeOverride = useMutation({ mutationFn: (uuid: string) => api.delete>(`/api/v1/holiday-override/${uuid}`), onSuccess: () => { toast.success('استثنا حذف شد'); qc.invalidateQueries({ queryKey: key }); }, onError: (e) => fail(e, 'حذف استثنا ناموفق بود'), }); return { holidays: query.data?.data?.holidays ?? [], overrides: query.data?.data?.overrides ?? [], loading: query.isLoading, // بدون این، درخواستِ شکست‌خورده مثل «سالِ خالی» دیده می‌شود و کاربر دنبال // تعطیلاتی می‌گردد که ثبت شده‌اند ولی نیامده‌اند. error: query.isError ? ((query.error as Error)?.message || 'خطای نامشخص') : null, setOverride, removeOverride, }; }