import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { getSites, getSiteById, createSite, updateSite, softDeleteSite, deleteSite, restoreSite, } from "@/super-admin/services/api/sitesService"; import { SiteDto, SitePayloadDto, SiteQueryParams } from "@/super-admin/dto/SitesDto"; import { toast } from "sonner"; import { useErrorHandler } from "@/shared/hooks/useErrorHandler"; import { useTranslation } from "react-i18next"; // Helper function to transform English name into snake_case format export function toSnakeCase(str: string): string { if (!str) return ""; return str .toLowerCase() .trim() .replace(/[^a-z0-9\s-_]/g, "") // remove special characters .replace(/[\s-]+/g, "_"); // replace spaces or hyphens with underscores } export const useSites = (params?: SiteQueryParams) => { const queryClient = useQueryClient(); const { t } = useTranslation(); const { handleError } = useErrorHandler(t); // 🔵 Query: Fetch sites list const { data: sitesResponse, isLoading, isError, refetch, } = useQuery({ queryKey: ["sites", params], queryFn: async () => { const { data } = await getSites(params); // Defensively support both [{...}] and { items: [...], count: X } formats const items = Array.isArray(data) ? data : (data?.items || []); const count = Array.isArray(data) ? data.length : (data?.count || items.length || 0); return { items: items as SiteDto[], count: count as number, }; }, staleTime: 5 * 60 * 1000, retry: false, }); // 🟢 Mutation: Create Site const { mutate: createMutation, isPending: isCreating } = useMutation({ mutationFn: async (payload: SitePayloadDto) => { const transformedPayload: SitePayloadDto = { ...payload, name: { ...payload.name, en: toSnakeCase(payload.name.en), }, }; const { data } = await createSite(transformedPayload); return data; }, onSuccess: () => { toast.success("Site created successfully!"); queryClient.invalidateQueries({ queryKey: ["sites"] }); }, onError: (error) => { handleError(error); }, }); // 🟠 Mutation: Update Site const { mutate: updateMutation, isPending: isUpdating } = useMutation({ mutationFn: async ({ id, payload }: { id: string; payload: SitePayloadDto }) => { const transformedPayload: SitePayloadDto = { ...payload, name: { ...payload.name, en: toSnakeCase(payload.name.en), }, }; const { data } = await updateSite(id, transformedPayload); return data; }, onSuccess: () => { toast.success("Site updated successfully!"); queryClient.invalidateQueries({ queryKey: ["sites"] }); }, onError: (error) => { handleError(error); }, }); // 🟡 Mutation: Archive Site (Soft Delete) const { mutate: archiveMutation, isPending: isArchiving } = useMutation({ mutationFn: async ({ id }: { id: string }) => { const { data } = await softDeleteSite(id); return data; }, onSuccess: () => { toast.success("Site archived successfully!"); queryClient.invalidateQueries({ queryKey: ["sites"] }); }, onError: (error) => { handleError(error); }, }); // 🔴 Mutation: Permanent Delete Site const { mutate: deleteMutation, isPending: isDeleting } = useMutation({ mutationFn: async ({ id }: { id: string }) => { const { data } = await deleteSite(id); return data; }, onSuccess: () => { toast.success("Site permanently deleted!"); queryClient.invalidateQueries({ queryKey: ["sites"] }); }, onError: (error) => { handleError(error); }, }); // 🟣 Mutation: Restore Archived Site const { mutate: restoreMutation, isPending: isRestoring } = useMutation({ mutationFn: async ({ id }: { id: string }) => { const { data } = await restoreSite(id); return data; }, onSuccess: () => { toast.success("Site restored successfully!"); queryClient.invalidateQueries({ queryKey: ["sites"] }); }, onError: (error) => { handleError(error); }, }); return { sitesResponse, isLoading, isError, refetch, createSite: createMutation, isCreating, updateSite: updateMutation, isUpdating, archiveSite: archiveMutation, isArchiving, deleteSite: deleteMutation, isDeleting, restoreSite: restoreMutation, isRestoring, }; }; export const useSiteDetail = (id: string, enabled: boolean = true) => { const { data: site, isLoading, isError, refetch, } = useQuery({ queryKey: ["site", id], queryFn: async () => { const { data } = await getSiteById(id); return data; }, enabled: enabled && !!id, staleTime: 5 * 60 * 1000, retry: false, }); return { site, isLoading, isError, refetch, }; };