From 64356a20e606efba97b649c7ebf4dd556c5ee4db Mon Sep 17 00:00:00 2001 From: ghost2023 Date: Thu, 28 May 2026 10:37:03 +0300 Subject: [PATCH] feat(frieght): setup useAuth --- .../portal/src/hooks/useAuth.ts | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 apps/edr-freight-web/portal/src/hooks/useAuth.ts diff --git a/apps/edr-freight-web/portal/src/hooks/useAuth.ts b/apps/edr-freight-web/portal/src/hooks/useAuth.ts new file mode 100644 index 000000000..2bd7b6383 --- /dev/null +++ b/apps/edr-freight-web/portal/src/hooks/useAuth.ts @@ -0,0 +1,141 @@ +import { useQuery, useQueryClient } from "@tanstack/react-query"; +import { api } from "@/services/api"; +import type { + GenerateVerificationCodePayload, + LoginPayload, + LoginResponse, + OtpPayload, + OtpResponse, + SetPasswordPayload, + SignupPayload, + SignupResponse, +} from "@/types/auth"; +import type { Result } from "@/utils/result"; +import { extractApiError } from "@/utils/result"; + +const useAuth = () => { + const queryClient = useQueryClient(); + + const authQuery = useQuery(api.auth.getMyInfo.queryOptions()); + + const customerQuery = useQuery( + api.customers.getByUserId.queryOptions({ + input: { id: authQuery.data?.id ?? "" }, + enabled: !!authQuery.data?.id, + retry: false, + }), + ); + + const isPending = authQuery.isPending; + + const login = async ( + payload: LoginPayload, + ): Promise> => { + try { + const res = await api.auth.login.call(payload); + await queryClient.invalidateQueries({ + queryKey: api.auth.getMyInfo.queryKey(), + }); + return { success: true, data: res }; + } catch (err) { + return { success: false, error: extractApiError(err) }; + } + }; + + const signup = async ( + payload: SignupPayload, + ): Promise> => { + try { + const res = await api.auth.createUser.call(payload); + return { success: true, data: res }; + } catch (err) { + return { success: false, error: extractApiError(err) }; + } + }; + + const setPassword = async ( + payload: SetPasswordPayload, + ): Promise> => { + try { + await api.auth.setPassword.call(payload); + return { success: true, data: undefined }; + } catch (err) { + return { success: false, error: extractApiError(err) }; + } + }; + + const verifyOTP = async ( + payload: OtpPayload, + ): Promise> => { + try { + const res = await api.auth.verifyOTP.call(payload); + return { success: true, data: res }; + } catch (err) { + return { success: false, error: extractApiError(err) }; + } + }; + + const sendOTP = async ( + payload: OtpPayload, + ): Promise> => { + try { + const res = await api.auth.sendOTP.call(payload); + return { success: true, data: res }; + } catch (err) { + return { success: false, error: extractApiError(err) }; + } + }; + + const generateVerificationCode = async ( + payload: GenerateVerificationCodePayload, + ): Promise> => { + try { + const res = await api.auth.generateVerificationCode.call(payload); + return { success: true, data: res }; + } catch (err) { + return { success: false, error: extractApiError(err) }; + } + }; + + const logout = async () => { + try { + await api.auth.logout.call(); + } catch { + // proceed with client-side cleanup even if server call fails + } + [ + "auth-token", + "refresh-token", + "auth-user", + "current-position-id", + "selected-position-id", + ].forEach((name) => { + document.cookie = `${name}=; Max-Age=0; path=/`; + }); + localStorage.clear(); + queryClient.clear(); + window.location.href = "/auth"; + }; + + const invalidate = async () => { + await Promise.all([authQuery.refetch(), customerQuery.refetch()]); + }; + + return { + isPending, + user: authQuery.data ?? null, + customer: customerQuery.data ?? null, + login, + signup, + setPassword, + verifyOTP, + sendOTP, + generateVerificationCode, + logout, + invalidate, + authQuery, + customerQuery, + }; +}; + +export default useAuth;