2. Login
Integrasi Login
Membuat Interface Login
response endpoint login
{
"status": "Success",
"message": "Login Success",
"data": {
"id": 1,
"nama": "ihsan santana w",
"email": "ihsanabuhanifah@gmail.com",
"password": "$2b$12$otdHLxtVDZq05dQAVccfpOH20OTJ57cg7kuAuzWkh3gWuaQrbA4YG",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwibmFtYSI6Imloc2FuIHNhbnRhbmEgdyIsImVtYWlsIjoiaWhzYW5hYnVoYW5pZmFoQGdtYWlsLmNvbSIsImlhdCI6MTY5NTUyOTUwMSwiZXhwIjoxNjk2MTM0MzAxfQ.IPBj5X78Q9fC3RWuHpAaq1fZzcvgaPv18ztmQs5ObaI",
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwibmFtYSI6Imloc2FuIHNhbnRhbmEgdyIsImVtYWlsIjoiaWhzYW5hYnVoYW5pZmFoQGdtYWlsLmNvbSIsImlhdCI6MTY5NTUyOTUwMSwiZXhwIjoxNjk1NjE1OTAxfQ.g6aMvyav9VAJ8mKY4drSfrn0pI1toBrF1TBvfq9YVCg"
}
}
app/auth/interface/index.ts
import { BaseResponseSuccess } from "@/lib/axiosClient";
interface User {
id?: number;
nama: string;
email: string;
password: string;
refresh_token: string;
access_token: string;
}
export interface LoginPayload extends Pick<User, "email" | "password"> {}
export interface RegisterPayload
extends Pick<User, "nama" | "email" | "password"> {}
export interface RegisterResponse extends BaseResponseSuccess {}
export interface LoginResponse extends BaseResponseSuccess {
data: User;
}
Membuat Service Login
app/auth/lib/index.ts
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useToast } from "@/hook";
import {
LoginPayload,
LoginResponse,
RegisterPayload,
RegisterResponse,
} from "../interface";
import { axiosClient } from "@/lib/axiosClient";
import { useRouter } from "next/navigation";
const useAuthModule = () => {
const { toastError, toastSuccess, toastWarning } = useToast();
const router = useRouter();
...
const login = async (payload: LoginPayload): Promise<LoginResponse> => {
return axiosClient.post("/auth/login", payload).then((res) => res.data);
};
const useLogin = () => {
const { mutate, isLoading } = useMutation(
(payload: LoginPayload) => login(payload),
{
onSuccess: async (response) => {
toastSuccess(response.message);
router.push("/admin");
},
onError: (error: any) => {
if (error.response.status == 422) {
toastWarning(error.response.data.message);
} else {
toastError();
}
},
}
);
return { mutate, isLoading };
};
return { useRegister };
};
export default useAuthModule;
Membuat Halaman Login dan Integrasi dengan Service
app/auth/login/page.tsx
"use client";
import { useFormik, Form, FormikProvider, getIn } from "formik";
import * as yup from "yup";
import { LoginPayload } from "../interface";
import InputText from "@/components/InputText";
import Label from "@/components/Label";
import Button from "@/components/Button";
import useAuthModule from "../lib";
import Link from "next/link";
export const registerSchema = yup.object().shape({
email: yup
.string()
.nullable()
.default("")
.email("Gunakan format email")
.required("Wajib isi"),
password: yup
.string()
.nullable()
.default("")
.required("Wajib isi")
.min(8, "Minimal 8 karakater"),
});
const Login = () => {
const { useLogin } = useAuthModule();
const { mutate, isLoading } = useLogin();
const formik = useFormik<LoginPayload>({
initialValues: registerSchema.getDefault(),
validationSchema: registerSchema,
enableReinitialize: true,
onSubmit: (payload) => {
mutate(payload);
},
});
const { handleChange, handleSubmit, handleBlur, values, errors } = formik;
return (
<section>
<div className="flex items-center justify-center w-full">
<h1 className="text-3xl text-blue-400">Login</h1>
</div>
<FormikProvider value={formik}>
<Form className="space-y-5" onSubmit={handleSubmit}>
<section>
<Label htmlFor="email" title="Email" />
<InputText
value={values.email}
placeholder="exampel@email.com"
id="email"
name="email"
onChange={handleChange}
onBlur={handleBlur}
isError={getIn(errors, "email")}
messageError={getIn(errors, "email")}
/>
</section>
<section>
<Label htmlFor="password" title="Password" />
<InputText
value={values.password}
placeholder="**********"
id="password"
name="password"
type="password"
onChange={handleChange}
onBlur={handleBlur}
isError={getIn(errors, "password")}
messageError={getIn(errors, "password")}
/>
</section>
<section>
<Button
height="lg"
title="Login"
colorSchema="blue"
isLoading={isLoading}
isDisabled={isLoading}
/>
<Link href={"register"}>
<Button title="Halaman Register" colorSchema="green" />
</Link>
</section>
</Form>
</FormikProvider>
</section>
);
};
export default Login;