import { AuthenticationError } from "@/src/entities/errors/auth"; import { useState } from "react"; import { useAuthActions } from "./mutation"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { defaultSignInPasswordlessValues, SignInFormData, SignInPasswordless, SignInPasswordlessSchema, SignInSchema } from "@/src/entities/models/auth/sign-in.model"; import { createFormData } from "@/app/_utils/common"; import { useFormHandler } from "@/app/_hooks/use-form-handler"; import { toast } from "sonner"; import { signIn } from "./action"; import { useNavigations } from "@/app/_hooks/use-navigations"; import { VerifyOtpFormData, verifyOtpSchema } from "@/src/entities/models/auth/verify-otp.model"; /** * Hook untuk menangani proses sign in * * @returns {Object} Object berisi handler dan state untuk form sign in * @example * const { handleSubmit, isPending, error } = useSignInHandler(); *
...
*/ export function useSignInHandler() { const { signIn } = useAuthActions(); const { router } = useNavigations(); const [error, setError] = useState(); const handleSubmit = async (event: React.FormEvent) => { event.preventDefault(); if (signIn.isPending) return; setError(undefined); const formData = new FormData(event.currentTarget); const email = formData.get("email")?.toString() try { await signIn.mutateAsync(formData, { onSuccess: () => { toast("An email has been sent to you. Please check your inbox."); if (email) router.push(`/verify-otp?email=${encodeURIComponent(email)}`); }, onError: (error) => { setError(error.message); } }); } catch (error) { if (error instanceof Error) { setError(error.message); } } }; return { // formData, // handleChange, handleSignIn: handleSubmit, error, isPending: signIn.isPending, errors: !!error || signIn.error, clearError: () => setError(undefined) }; } export function useVerifyOtpHandler(email: string) { const { router } = useNavigations() const { verifyOtp } = useAuthActions() const [error, setError] = useState() const { register, handleSubmit: hookFormSubmit, control, formState: { errors }, setValue } = useForm({ resolver: zodResolver(verifyOtpSchema), defaultValues: { email, token: "" } }) const handleOtpChange = (value: string, onChange: (value: string) => void) => { onChange(value) // Clear error when user starts typing if (error) { setError(undefined) } } const handleSubmit = hookFormSubmit(async (data) => { if (verifyOtp.isPending) return setError(undefined) // Create FormData object const formData = new FormData() formData.append("email", data.email) formData.append("token", data.token) try { await verifyOtp.mutateAsync(formData, { onSuccess: () => { toast.success("OTP verified successfully") // Navigate to dashboard on success router.push("/dashboard") }, onError: (error) => { setError(error.message) } }) } catch (error) { if (error instanceof Error) { setError(error.message) } } }) return { register, control, handleVerifyOtp: handleSubmit, handleOtpChange, errors: { ...errors, token: error ? { message: error } : errors.token }, isPending: verifyOtp.isPending, clearError: () => setError(undefined) } } export function useSignOutHandler() { const { signOut } = useAuthActions() const { router } = useNavigations() const [error, setError] = useState() const handleSignOut = async () => { if (signOut.isPending) return setError(undefined) try { await signOut.mutateAsync(undefined, { onSuccess: () => { toast.success("You have been signed out successfully") router.push("/sign-in") }, onError: (error) => { if (error instanceof AuthenticationError) { setError(error.message) toast.error(error.message) } } }) } catch (error) { if (error instanceof Error) { setError(error.message) toast.error(error.message) // toast.error("An error occurred during sign out. Please try again later.") } } } return { handleSignOut, error, isPending: signOut.isPending, errors: !!error || signOut.error, clearError: () => setError(undefined) } }