F. Integrasi Create Bulk
1. Integrasi CreateBulk
Membuat Interface
payload endpoint create bulk
{
"data" : [
{
"title": "NestJS For Backend",
"author": "Ihsan",
"year": 2023
},
{
"title": "Become Network Engineer",
"author": "Fathi",
"year": 2021
}
]
}
response endpoint create bulk
{
"status": "Success",
"message": "Berhasil menyimpan 8 dan gagal 0",
"data": {}
}
book/interface/index.ts
import { BaseResponsePagination } from "@/lib/axiosClient";
interface Book {
id: number | undefined;
title: string;
author: string;
year: number | undefined | string
created_at: string;
updated_at: string;
}
...
export interface BookCreatePayload
extends Pick<Book, "author" | "title" | "year"> {}
...
export interface BookCreateArrayPayload {
data: BookCreatePayload[];
}
Membuat Service Create Bulk
book/lib/index.ts
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { axiosClient } from "@/lib/axiosClient";
import Swal from "sweetalert2";
import {
BookCreateArrayPayload,
BookCreatePayload,
BookDetail,
BookListFilter,
BookListResponse,
BookUpdatePayload,
} from "../interface";
import { usePagination } from "@/hook/usePagination";
const useBookModule = () => {
...
const useCreateBulkBook = () => {
const { mutate, isLoading } = useMutation(
(payload: BookCreateArrayPayload) => {
return axiosClient.post("/book/create/bulk", payload);
},
{
onSuccess: (response) => {
Swal.fire({
position: "top-end",
icon: "success",
title: response.data.message,
showConfirmButton: false,
timer: 1000,
});
},
onError: (error) => {
Swal.fire({
position: "top",
icon: "error",
title: "Ada Kesalahan",
showConfirmButton: false,
timer: 1000,
});
},
}
);
return { mutate, isLoading };
};
return {
useBookList,
useCreateBook,
useDetailBook,
useUpdateBook,
useDeleteBook,
useCreateBulkBook
};
};
export default useBookModule;
Menambahkan Navigati Create Bulk
app/book/oage.tsx
"use client";
const Book = () => {
return (
<>
<Drawer
onClose={onClose}
onClear={handleClear}
onSubmit={handleFilter}
title="Filter Buku"
isOpen={isOpen}
>
<Filter params={params} setParams={setParams} />
</Drawer>
<section className=" p-10 overflow-auto ">
<section className="flex items-center justify-between ">
<Button
width="sm"
onClick={onOpen}
colorSchema="blue"
title="Filter"
/>
<div className="space-x-5">
<Button
onClick={() => {
router.push("/book/tambah");
}}
width="sm"
colorSchema="red"
title="tambah"
/>
<Button
onClick={() => {
router.push("/book/tambah-bulk");
}}
width="sm"
colorSchema="green"
title="tambah bulk"
/>
</div>
</section>
...
export default Book;
Membuat Halaman Create Bulk
app/book/tambah-bulk/page.tsx
"use client";
import Button from "@/components/Button";
import InputText from "@/components/InputText";
import Label from "@/components/Label";
import Select from "@/components/Select";
import {
useFormik,
Form,
FormikProvider,
FieldArray,
ArrayHelpers,
getIn
} from "formik";
import * as yup from "yup";
import { BookCreateArrayPayload } from "../interface";
import useBookModule from "../lib";
import Link from "next/link";
import { ArrowLongLeftIcon } from "@heroicons/react/20/solid";
import { createBookSchema } from "../tambah/page";
import { option } from "../tambah/page";
import { AddButton, DeleteButton } from "@/components/ButtonAction";
const defaultCatatanArray = {
data: [
{
title: "",
author: "",
year: undefined,
},
],
};
const createBookArraySchema = yup
.object()
.shape({
data: yup.array().of(createBookSchema),
})
.default(defaultCatatanArray);
const CreateBook = () => {
const { useCreateBulkBook } = useBookModule();
const { mutate, isLoading } = useCreateBulkBook();
const onSubmit = async (values: BookCreateArrayPayload) => {
mutate(values, {
onSuccess: () => {
resetForm();
setValues(defaultCatatanArray);
},
});
};
const formik = useFormik<BookCreateArrayPayload>({
initialValues: createBookArraySchema.getDefault(),
validationSchema: createBookArraySchema,
enableReinitialize: true,
onSubmit: onSubmit,
});
const {
handleChange,
handleSubmit,
setFieldValue,
handleBlur,
values,
errors,
resetForm,
setValues,
} = formik;
return (
<section className="flex items-center justify-center w-full h-full overflow-auto py-10">
<section className="w-1/2">
<Link href={"/book"}>
<span className="flex items-center">
{" "}
<ArrowLongLeftIcon className="h-5 w-5 mr-2" />
Kembali
</span>
</Link>
<h2 className="text-xl font-bold text-gray-500">Tambah Buku</h2>
{JSON.stringify(errors)}
<FormikProvider value={formik}>
<Form className="space-y-5" onSubmit={handleSubmit}>
<FieldArray
name={"data"}
render={(arrayHelpers: ArrayHelpers) => (
<>
{values &&
values?.data?.map((value, index) => (
<section
key={index}
className="space-y-2 shadow-lg p-5 relative"
>
<section className="flex items-center justify-end">
<DeleteButton
onClick={() => arrayHelpers.remove(index)}
/>
</section>
<section>
<Label htmlFor="title" title="Title" />
<InputText
value={value.title}
placeholder="Judul Buku"
id={`data[${index}]title`}
name={`data[${index}]title`}
onChange={handleChange}
onBlur={handleBlur}
isError={
getIn(errors?.data?.[index], "title")
}
messageError={ getIn(errors?.data?.[index], "title")}
/>
</section>
<section>
<Label htmlFor="author" title="Auhtor" />
<InputText
value={value.author}
placeholder="Penulis Buku"
id={`data[${index}]author`}
name={`data[${index}]author`}
onChange={(e) => {
setFieldValue(
`data[${index}]author`,
e.target.value
);
}}
onBlur={handleBlur}
isError={
getIn(errors?.data?.[index], "author")
}
messageError={ getIn(errors?.data?.[index], "author")}
/>
</section>
<section>
<Label htmlFor="year" title="Year" />
<Select
value={value.year}
id={`data[${index}]year`}
name={`data[${index}]year`}
onChange={handleChange}
onBlur={handleBlur}
options={option}
isError={
getIn(errors?.data?.[index], "year")
}
messageError={ getIn(errors?.data?.[index], "year")}
/>
</section>
</section>
))}
<section>
<AddButton
onClick={() =>
arrayHelpers.push(createBookSchema.getDefault())
}
/>
</section>
</>
)}
/>
<section>
<Button
height="md"
title="Simpan"
colorSchema="blue"
isLoading={isLoading}
isDisabled={isLoading}
/>
</section>
</Form>
</FormikProvider>
</section>
</section>
);
};
export default CreateBook;