import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import toast from "react-hot-toast"; import { QUERY_KEYS } from "@/constants/TANSTACK_QUEY_KEY"; import { ruleEngineService, type RuleEngineListParams, } from "@/services/ruleEngine/ruleEngine.service"; import { RULE_ENGINE_SELECT_NONE } from "@/pages/ruleEngine/config/resources"; import type { ApproveRatePayload, RuleEngineRecord, RuleEngineResourceSlug, } from "@/types/rule-engine"; const CARGO_TYPE_PARENT_PAGE_SIZE = 500; export const useRuleEngineList = ( resource: RuleEngineResourceSlug, params: RuleEngineListParams, ) => useQuery({ queryKey: [...QUERY_KEYS.RULE_ENGINE.list(resource), params], queryFn: () => ruleEngineService.list(resource, params), }); export const useCargoTypeParentOptions = (excludeId?: string, enabled = true) => useQuery({ queryKey: [ ...QUERY_KEYS.RULE_ENGINE.list("cargo-types"), "parent-options", excludeId ?? "", ], queryFn: () => ruleEngineService.list("cargo-types", { page: 1, pageSize: CARGO_TYPE_PARENT_PAGE_SIZE, }), enabled, select: (result) => { const noneOption = { label: "None", value: RULE_ENGINE_SELECT_NONE }; const parents = (result.data ?? []) .filter((row) => row.id && String(row.id) !== excludeId) .map((row) => { const name = String(row.cargoTypeName ?? "").trim(); const code = String(row.code ?? "").trim(); const label = name && code ? `${name} (${code})` : name || code || String(row.id); return { label, value: String(row.id) }; }); return [noneOption, ...parents]; }, }); export const useApprovalChain = (enabled: boolean) => useQuery({ queryKey: QUERY_KEYS.RULE_ENGINE.chain, queryFn: () => ruleEngineService.getApprovalChain(), enabled, }); export const useRuleEngineMutations = (resource: RuleEngineResourceSlug) => { const qc = useQueryClient(); const invalidate = () => qc.invalidateQueries({ queryKey: QUERY_KEYS.RULE_ENGINE.list(resource) }); const create = useMutation({ mutationFn: (payload: Record) => ruleEngineService.create(resource, payload), onSuccess: () => { toast.success("Created successfully"); invalidate(); }, onError: () => toast.error("Failed to create record"), }); const update = useMutation({ mutationFn: ({ id, payload, }: { id: string; payload: Record; }) => ruleEngineService.update(resource, id, payload), onSuccess: () => { toast.success("Updated successfully"); invalidate(); }, onError: () => toast.error("Failed to update record"), }); const remove = useMutation({ mutationFn: (id: string) => ruleEngineService.remove(resource, id), onSuccess: () => { toast.success("Deleted successfully"); invalidate(); }, onError: () => toast.error("Failed to delete record"), }); return { create, update, remove }; }; export const useRateWorkflow = () => { const qc = useQueryClient(); const invalidate = () => qc.invalidateQueries({ queryKey: QUERY_KEYS.RULE_ENGINE.list("rates") }); const submit = useMutation({ mutationFn: (id: string) => ruleEngineService.submitRate(id), onSuccess: () => { toast.success("Rate submitted for approval"); invalidate(); }, onError: () => toast.error("Failed to submit rate"), }); const approve = useMutation({ mutationFn: ({ id, payload }: { id: string; payload: ApproveRatePayload }) => ruleEngineService.approveRate(id, payload), onSuccess: () => { toast.success("Rate approved"); invalidate(); }, onError: () => toast.error("Failed to approve rate"), }); return { submit, approve }; };