mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-28 11:21:18 +00:00
186 lines
4.9 KiB
TypeScript
186 lines
4.9 KiB
TypeScript
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,
|
|
};
|
|
};
|