feat: restructure signin functionality with new hooks and improved validation

This commit is contained in:
arraysid
2025-05-20 10:00:52 +07:00
parent 1ddb2f72c6
commit f5f715175c
8 changed files with 93 additions and 58 deletions
@@ -1,29 +0,0 @@
'use server';
import { setAccessToken, setRefreshToken } from '@/lib/cookies';
import { fetcher } from '@/lib/openapi';
import { z } from 'zod';
import { signInValidationSchema } from '../_validation/signin-validation';
export async function SigninAction(
data: z.infer<typeof signInValidationSchema>
) {
const { email, password } = signInValidationSchema.parse(data);
const { data: json, error } = await fetcher.POST('/v1/auth/login', {
body: {
email,
password,
},
});
if (error) throw new Error(error.message);
const accessToken = json.data.token.access_token;
const refreshToken = json.data.token.refresh_token;
await setAccessToken(accessToken);
await setRefreshToken(refreshToken);
return json;
}
@@ -0,0 +1,22 @@
'use server';
import { setAccessToken, setRefreshToken } from '@/lib/cookies';
import { fetchPostSignin } from '../_http/signin-http';
import {
type SignInValidationType,
signInValidationSchema,
} from '../_validation/signin-validation';
export async function SigninAction(request: SignInValidationType) {
const validRequest = signInValidationSchema.parse(request);
const { data } = await fetchPostSignin(validRequest);
const accessToken = data.token.access_token;
const refreshToken = data.token.refresh_token;
await setAccessToken(accessToken);
await setRefreshToken(refreshToken);
return data;
}
@@ -10,37 +10,16 @@ import {
FormMessage,
Input,
} from '@components/atoms';
import { zodResolver } from '@hookform/resolvers/zod';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from 'next/navigation';
import { useForm } from 'react-hook-form';
import { LuLoader } from 'react-icons/lu';
import { z } from 'zod';
import { SigninAction } from '../_action/signin-action';
import { signInValidationSchema } from '../_validation/signin-validation';
import { useFormSignin } from '../_hooks/use-form-signin';
import { usePostSignin } from '../_hooks/use-post-signin';
import { type SignInValidationType } from '../_validation/signin-validation';
export function SigninForm() {
const router = useRouter();
const form = useFormSignin();
const { mutate, isPending, error } = usePostSignin(form);
const form = useForm<z.infer<typeof signInValidationSchema>>({
resolver: zodResolver(signInValidationSchema),
defaultValues: {
email: '',
password: '',
},
});
const { mutate, isPending, error } = useMutation({
mutationFn: SigninAction,
onSuccess: () => {
router.push('/');
},
onError: () => {
form.resetField('password');
},
});
const onSubmit = (values: z.infer<typeof signInValidationSchema>) => {
const onSubmit = (values: SignInValidationType) => {
mutate(values);
};
@@ -81,7 +60,11 @@ export function SigninForm() {
)}
/>
<Button type="submit" disabled={isPending} className="w-full">
<Button
type="submit"
disabled={isPending}
className="w-full hover:bg-[#5fbaef] bg-[#22a5f1] font-bold"
>
{isPending ? <LuLoader className="h-5 w-5 animate-spin" /> : 'Masuk'}
</Button>
</form>
@@ -0,0 +1,16 @@
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form';
import {
signInValidationSchema,
type SignInValidationType,
} from '../_validation/signin-validation';
export function useFormSignin() {
return useForm<SignInValidationType>({
resolver: zodResolver(signInValidationSchema),
defaultValues: {
email: '',
password: '',
},
});
}
@@ -0,0 +1,18 @@
import { useMutation } from '@tanstack/react-query';
import { useRouter } from 'next/navigation';
import { SigninAction } from '../_actions/signin-action';
import { useFormSignin } from './use-form-signin';
export function usePostSignin(form: ReturnType<typeof useFormSignin>) {
const router = useRouter();
return useMutation({
mutationFn: SigninAction,
onSuccess: () => {
router.push('/');
},
onError: () => {
form.resetField('password');
},
});
}
@@ -0,0 +1,24 @@
import { fetcher } from '@/lib/openapi';
import { SignInValidationType } from '../_validation/signin-validation';
export async function fetchPostSignin({
email,
password,
}: SignInValidationType) {
const { data, error, response } = await fetcher.POST('/v1/auth/login', {
body: {
email,
password,
},
});
if (error) {
throw new Error(error.message);
}
if (!response.ok) {
throw new Error('Someting went wrong, please try again later');
}
return data;
}
@@ -15,3 +15,4 @@ export const signInValidationSchema = z.object({
})
.min(1, 'Password tidak boleh kosong'),
});
export type SignInValidationType = z.infer<typeof signInValidationSchema>;
@@ -27,7 +27,7 @@ export default function Page() {
Belum punya akun?{' '}
<Link
href="/signup"
className="text-primary font-bold hover:underline hover:underline-offset-4 transition-colors"
className="text-[#22a5f1] font-bold hover:underline hover:underline-offset-4 transition-colors"
>
Daftar
</Link>