import { Route as LoginRoute } from '@/routes/auth/login'; import type { AuthResponseDtoUserDetailDto, LoginUserAuthResponse, RegisterUserAuthResponse, ResetPasswordUserAuthResponse, SendOtpUserAuthResponse, ValidateTokenUserAuthResponse, } from '@/sdk'; import { loginUserAuthMutation, logoutUserAuthMutation, registerUserAuthMutation, resetPasswordUserAuthMutation, sendOtpUserAuthMutation, validateTokenUserAuthMutation, } from '@/sdk/@tanstack/react-query.gen'; import { client } from '@/sdk/client.gen'; import { useMutation } from '@tanstack/react-query'; import { useNavigate } from '@tanstack/react-router'; import { atom, useAtomValue, useSetAtom } from 'jotai'; import { atomWithStorage } from 'jotai/utils'; import { useTranslation } from 'react-i18next'; import { toast } from 'sonner'; import { SupportedLanguages } from '@/lib/i18n'; import { DEFAULT_NON_LOGGED_IN_ROUTE } from '@/lib/routes'; export const HEADER_KEYS = { AUTH_TOKEN: 'x-auth-token', ACCEPT_LANGUAGE: 'accept-language', }; export const LOCAL_STORAGE_KEYS = { AUTH_TOKEN: 'authTokenAtom', }; export const authTokenAtom = atomWithStorage(LOCAL_STORAGE_KEYS.AUTH_TOKEN, '', undefined, { getOnInit: true, }); export const currentUserDetailsAtom = atom(); export const setTokenInClient = (token?: string | null) => { if (token) { client.setConfig({ headers: { [HEADER_KEYS.AUTH_TOKEN]: token, }, }); } else { client.setConfig({ headers: { [HEADER_KEYS.AUTH_TOKEN]: undefined, }, }); } }; export const setLocaleInClient = (locale: SupportedLanguages) => { client.setConfig({ headers: { [HEADER_KEYS.ACCEPT_LANGUAGE]: locale, }, }); }; export const useLogin = () => { const { t } = useTranslation(); const setAuthToken = useSetAtom(authTokenAtom); const setCurrentUser = useSetAtom(currentUserDetailsAtom); return useMutation({ ...loginUserAuthMutation({}), onSuccess: (response: LoginUserAuthResponse) => { const authData = response.data; setAuthToken(authData?.token || ''); setCurrentUser(authData); setTokenInClient(authData?.token); }, onError: (err) => { console.error('Login error:', err); toast.error(err.response?.data.message || t('auth.messages.loginFailed')); }, }); }; export const useSignup = () => { const { t } = useTranslation(); const setAuthToken = useSetAtom(authTokenAtom); const setCurrentUser = useSetAtom(currentUserDetailsAtom); return useMutation({ ...registerUserAuthMutation({}), onSuccess: (response: RegisterUserAuthResponse) => { const authData = response.data; setAuthToken(authData?.token || ''); setCurrentUser(authData); setTokenInClient(authData?.token); }, onError: (err) => { console.error('Signup error:', err); toast.error(err.response?.data.message || t('auth.messages.signupFailed')); }, }); }; export const useValidateToken = () => { const setCurrentUser = useSetAtom(currentUserDetailsAtom); const setAuthToken = useSetAtom(authTokenAtom); const authToken = useAtomValue(authTokenAtom); setTokenInClient(authToken); return useMutation({ ...validateTokenUserAuthMutation({}), retry: false, onSuccess: (response: ValidateTokenUserAuthResponse) => { const authData = response.data; setCurrentUser(authData); setAuthToken(authData?.token || ''); setTokenInClient(authData?.token); }, onError: (err) => { console.error('Validate token error:', err); setCurrentUser(undefined); setAuthToken(''); setTokenInClient(); }, }); }; export const useLogout = () => { const setAuthToken = useSetAtom(authTokenAtom); const setCurrentUser = useSetAtom(currentUserDetailsAtom); const navigate = useNavigate(); return useMutation({ ...logoutUserAuthMutation({}), onSuccess: () => { setAuthToken(''); setCurrentUser(undefined); setTokenInClient(); navigate({ to: DEFAULT_NON_LOGGED_IN_ROUTE }); }, }); }; export const useSendOtp = () => { const { t } = useTranslation(); const navigate = useNavigate(); return useMutation({ ...sendOtpUserAuthMutation({}), onSuccess: (response: SendOtpUserAuthResponse, variables) => { toast.success(response.message || t('auth.messages.otpSentSuccess')); // Extract email from the mutation variables and navigate to reset-password const email = variables.query?.authId; if (email) { navigate({ to: '/auth/reset-password', search: { email }, }); } }, onError: (err) => { console.error('Send OTP error:', err); toast.error(err.response?.data.message || t('auth.messages.otpSendFailed')); }, }); }; export const useResetPassword = () => { const { t } = useTranslation(); const navigate = useNavigate(); return useMutation({ ...resetPasswordUserAuthMutation({}), onSuccess: (response: ResetPasswordUserAuthResponse) => { toast.success(response.message || t('auth.messages.passwordResetSuccess')); navigate({ to: LoginRoute.to }); }, onError: (err) => { console.error('Reset password error:', err); toast.error(err.response?.data.message || t('auth.messages.passwordResetFailed')); }, }); };