import { useMutation, useQuery } from "@tanstack/react-query"; import type { NPEDFieldType } from "../types/types"; import { useIntegrationsContext } from "../context/IntegrationsContext"; import { useEffect } from "react"; import { CAM_BASE } from "../utils/config"; import { toast } from "sonner"; async function fetchNPEDDetails() { const fetchUrl = `${CAM_BASE}/api/fetch-config?id=NPED`; const response = await fetch(fetchUrl, { signal: AbortSignal.timeout(500), }); if (!response.ok) throw new Error("Cannot reach fetch-config endpoint"); return response.json(); } async function signIn(loginDetails: NPEDFieldType) { const { frontId, rearId, username, password, clientId } = loginDetails; const NPEDLoginURLFront = `${CAM_BASE}/api/update-config?id=${frontId}`; const NPEDLoginURLRear = `${CAM_BASE}/api/update-config?id=${rearId}`; const payload = (id: string) => ({ id, fields: [ { property: "propEnabled", value: true }, { property: "propUsername", value: username }, { property: "propPassword", value: password }, { property: "propClientID", value: clientId }, ], }); const [frontRes, rearRes] = await Promise.all([ fetch(NPEDLoginURLFront, { method: "POST", body: JSON.stringify(payload(frontId)), }), fetch(NPEDLoginURLRear, { method: "POST", body: JSON.stringify(payload(rearId)), }), ]); if (!frontRes.ok || !rearRes.ok) throw new Error("Cannot reach NPED endpoint"); return { frontResponse: frontRes.json(), rearResponse: rearRes.json(), }; } async function signOut() { const nullPayload = { id: "NPED", fields: [ { property: "propEnabled", value: false }, { property: "propUsername", value: "" }, { property: "propPassword", value: "" }, { property: "propClientID", value: "" }, ], }; const NPEDLoginURLFront = `${CAM_BASE}/api/update-config?id=NPED`; const response = await fetch(NPEDLoginURLFront, { method: "POST", body: JSON.stringify(nullPayload), }); if (!response.ok) throw new Error("cannot reach NPED sign out endpoint"); return response.json(); } export const useNPEDAuth = () => { const { dispatch } = useIntegrationsContext(); const signInMutation = useMutation({ mutationKey: ["NPEDSignin"], mutationFn: signIn, onMutate: () => { toast.loading("Signing in..."); }, onSuccess: async (data) => { toast.dismiss(); toast.success("Signed in successfully!"); dispatch({ type: "LOGIN", payload: await data.frontResponse }); }, onError: (error) => { toast.dismiss(); if (error.message.includes("timed out")) { toast.error("Connection timed out. Please check your network."); } else { toast.error(`Sign-in failed: ${error.message}`); } }, }); const signOutMutation = useMutation({ mutationKey: ["auth", "NPEDSignOut"], mutationFn: signOut, onSuccess: () => { toast.success("Signed out successfully"); dispatch({ type: "LOGOUT", payload: null }); }, onError: (error) => { toast.error(`Sign-out failed: ${error.message}`); }, }); const fetchdataQuery = useQuery({ queryKey: ["auth", "NPEDFetch"], queryFn: fetchNPEDDetails, }); useEffect(() => { if (fetchdataQuery.isSuccess && fetchdataQuery.data) { dispatch({ type: "LOGIN", payload: fetchdataQuery.data }); } else { dispatch({ type: "LOGOUT", payload: null }); } }, [dispatch, fetchdataQuery.data, fetchdataQuery.isSuccess]); useEffect(() => { if (fetchdataQuery.isError) toast.error(fetchdataQuery.error.message); }, [fetchdataQuery?.error?.message, fetchdataQuery.isError]); return { signIn: signInMutation.mutate, signInAsync: signInMutation.mutateAsync, isPending: signInMutation.isPending, isError: signInMutation.isError, error: signInMutation.error, data: signInMutation.data, fetchdataQueryError: fetchdataQuery.error, fetchdataQueryLoading: fetchdataQuery.isLoading, signOut: signOutMutation.mutate, }; };