diff --git a/app/(admin)/admin/master-category/page.tsx b/app/(admin)/admin/master-category/page.tsx new file mode 100644 index 0000000..6aaf9cb --- /dev/null +++ b/app/(admin)/admin/master-category/page.tsx @@ -0,0 +1,341 @@ +"use client"; +import { AddIcon, CloudUploadIcon, TimesIcon } from "@/components/icons"; +import CategoriesTable from "@/components/table/master-categories/categories-table"; +import * as z from "zod"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { Controller, useForm } from "react-hook-form"; +import { useEffect, useState } from "react"; +import ReactSelect from "react-select"; +import makeAnimated from "react-select/animated"; +import { useDropzone } from "react-dropzone"; +import { close, error, loading } from "@/config/swal"; +import Swal from "sweetalert2"; +import withReactContent from "sweetalert2-react-content"; +import Image from "next/image"; + +import { getArticleByCategory } from "@/service/article"; +import { + createCategory, + uploadCategoryThumbnail, +} from "@/service/master-categories"; +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogFooter, +} from "@/components/ui/dialog"; +import { Textarea } from "@/components/ui/textarea"; +import { Input } from "@/components/ui/input"; +import useDisclosure from "@/components/useDisclosure"; + +const createArticleSchema = z.object({ + title: z.string().min(2, { + message: "Judul harus diisi", + }), + description: z.string().min(2, { + message: "Deskripsi harus diisi", + }), + tags: z.array(z.string()), + // parent: z.array(categorySchema).nonempty({ + // message: "Kategori harus memiliki setidaknya satu item", + // }), + // tags: z.array(z.string()).nonempty({ + // message: "Minimal 1 tag", + // }), +}); + +interface CategoryType { + id: number; + label: string; + value: number; +} + +export default function MasterCategoryTable() { + const MySwal = withReactContent(Swal); + const animatedComponents = makeAnimated(); + const { isOpen, onOpen, onOpenChange, onClose } = useDisclosure(); + const [listCategory, setListCategory] = useState([]); + const [files, setFiles] = useState([]); + const [refresh, setRefresh] = useState(false); + const [tag, setTag] = useState(""); + const [selectedParent, setSelectedParent] = useState(); + const [isDetail] = useState(); + + const formOptions = { + resolver: zodResolver(createArticleSchema), + defaultValues: { title: "", description: "", tags: [] }, + }; + + const { getRootProps, getInputProps } = useDropzone({ + onDrop: (acceptedFiles) => { + setFiles(acceptedFiles.map((file) => Object.assign(file))); + }, + maxFiles: 1, + }); + type UserSettingSchema = z.infer; + const { + control, + handleSubmit, + formState: { errors }, + setValue, + getValues, + setError, + clearErrors, + } = useForm(formOptions); + + useEffect(() => { + fetchCategory(); + }, []); + + const fetchCategory = async () => { + const res = await getArticleByCategory(); + if (res?.data?.data) { + setupCategory(res?.data?.data); + } + }; + + const setupCategory = (data: any) => { + const temp = []; + for (const element of data) { + temp.push({ + id: element.id, + label: element.title, + value: element.id, + }); + } + setListCategory(temp); + }; + + const onSubmit = async (values: z.infer) => { + console.log("values,", values); + loading(); + const formData = { + title: values.title, + statusId: 1, + parentId: selectedParent ? selectedParent.id : 0, + tags: values.tags.join(","), + description: values.description, + }; + + const response = await createCategory(formData); + + if (response?.error) { + error(response.message); + return false; + } + const categoryId = response?.data?.data?.id; + const formFiles = new FormData(); + + formFiles.append("files", files[0]); + const resFile = await uploadCategoryThumbnail(categoryId, formFiles); + if (resFile?.error) { + error(resFile.message); + return false; + } + close(); + setRefresh(!refresh); + MySwal.fire({ + title: "Sukses", + icon: "success", + confirmButtonColor: "#3085d6", + confirmButtonText: "OK", + }).then((result) => { + if (result.isConfirmed) { + } + }); + }; + + const handleRemoveFile = (file: File) => { + const uploadedFiles = files; + const filtered = uploadedFiles.filter((i) => i.name !== file.name); + setFiles([...filtered]); + }; + + return ( +
+
+
+ + +
+
+ + + + Kategori Baru + +
+
+

Nama Kategori

+ ( + + )} + /> + {errors?.title && ( +

{errors.title?.message}

+ )} +
+
+

Deskripsi

+ ( +