diff --git a/src/components/KategoriPelayananSurat.tsx b/src/components/KategoriPelayananSurat.tsx
new file mode 100644
index 0000000..94f90d7
--- /dev/null
+++ b/src/components/KategoriPelayananSurat.tsx
@@ -0,0 +1,492 @@
+import apiFetch from "@/lib/apiFetch";
+import {
+ ActionIcon,
+ Button,
+ Divider,
+ Flex,
+ Grid,
+ Group,
+ Input,
+ List,
+ Modal,
+ Stack,
+ Table,
+ TagsInput,
+ Text,
+ Title,
+ Tooltip
+} from "@mantine/core";
+import { useDisclosure, useShallowEffect } from "@mantine/hooks";
+import { IconEdit, IconEye, IconPlus, IconTrash } from "@tabler/icons-react";
+import { useState } from "react";
+import useSWR from "swr";
+import notification from "./notificationGlobal";
+
+export default function KategoriPelayananSurat() {
+ const [openedDelete, { open: openDelete, close: closeDelete }] = useDisclosure(false);
+ const [openedDetail, { open: openDetail, close: closeDetail }] = useDisclosure(false);
+ const [btnLoading, setBtnLoading] = useState(false);
+ const [opened, { open, close }] = useDisclosure(false);
+ const [openedTambah, { open: openTambah, close: closeTambah }] = useDisclosure(false);
+ const [dataDelete, setDataDelete] = useState("")
+ const { data, mutate, isLoading } = useSWR("/", () =>
+ apiFetch.api.pelayanan.category.get(),
+ );
+ const list = data?.data || [];
+ const [dataChoose, setDataChoose] = useState({
+ id: "",
+ name: "",
+ syaratDokumen: [{ name: "", desc: "" }],
+ dataText: [""],
+ });
+ const [dataTambah, setDataTambah] = useState({
+ name: "",
+ syaratDokumen: [{ name: "", desc: "" }],
+ dataText: [""],
+ })
+
+ useShallowEffect(() => {
+ mutate();
+ }, []);
+
+ async function handleCreate() {
+ try {
+ setBtnLoading(true);
+ const cleanedDataText = dataTambah.dataText.map(v => v.trim()).filter(v => v !== "");
+ const cleanedSyarat = dataTambah.syaratDokumen.map((item) => ({
+ name: item.name.trim(),
+ desc: item.desc.trim(),
+ })).filter(item => item.name !== "" && item.desc !== "");
+
+ const cleanedTambah = {
+ name: dataTambah.name.trim(),
+ syaratDokumen: cleanedSyarat,
+ dataText: cleanedDataText,
+ }
+ const res = await apiFetch.api.pelayanan.category.create.post(cleanedTambah);
+ if (res.status === 200) {
+ mutate();
+ closeTambah();
+ setDataTambah({
+ name: "",
+ syaratDokumen: [{ name: "", desc: "" }],
+ dataText: [""],
+ });
+ notification({
+ title: "Success",
+ message: "Your category have been saved",
+ type: "success",
+ })
+ } else {
+ notification({
+ title: "Error",
+ message: "Failed to create category",
+ type: "error",
+ })
+ }
+ } catch (error) {
+ console.error(error);
+ notification({
+ title: "Error",
+ message: "Failed to create category",
+ type: "error",
+ })
+ } finally {
+ setBtnLoading(false);
+ }
+ }
+
+ async function handleEdit() {
+ try {
+ setBtnLoading(true);
+ const cleanedDataText = dataChoose.dataText.map(v => v.trim()).filter(v => v !== "");
+ const cleanedSyarat = dataChoose.syaratDokumen.map((item) => ({
+ name: item.name.trim(),
+ desc: item.desc.trim(),
+ })).filter(item => item.name !== "" && item.desc !== "");
+
+ const res = await apiFetch.api.pelayanan.category.update.post({
+ id: dataChoose.id,
+ name: dataChoose.name,
+ syaratDokumen: cleanedSyarat,
+ dataText: cleanedDataText,
+ });
+ if (res.status === 200) {
+ mutate();
+ close();
+ notification({
+ title: "Success",
+ message: "Your category have been saved",
+ type: "success",
+ })
+ } else {
+ notification({
+ title: "Error",
+ message: "Failed to edit category",
+ type: "error",
+ })
+ }
+ } catch (error) {
+ console.error(error);
+ notification({
+ title: "Error",
+ message: "Failed to edit category",
+ type: "error",
+ })
+ } finally {
+ setBtnLoading(false);
+ }
+ }
+
+
+ async function handleDelete() {
+ try {
+ setBtnLoading(true);
+ const res = await apiFetch.api.pelayanan.category.delete.post({ id: dataDelete });
+ if (res.status === 200) {
+ mutate();
+ closeDelete();
+ notification({
+ title: "Success",
+ message: "Your category have been deleted",
+ type: "success",
+ })
+ } else {
+ notification({
+ title: "Error",
+ message: "Failed to delete category",
+ type: "error",
+ })
+ }
+ } catch (error) {
+ console.error(error);
+ notification({
+ title: "Error",
+ message: "Failed to delete category",
+ type: "error",
+ })
+ } finally {
+ setBtnLoading(false);
+ }
+ }
+
+
+ function handleAddSyarat() {
+ setDataChoose({
+ ...dataChoose,
+ syaratDokumen: [...dataChoose.syaratDokumen, { name: "", desc: "" }],
+ });
+ }
+
+ function handleDeleteSyarat(index: number) {
+ setDataChoose({
+ ...dataChoose,
+ syaratDokumen: dataChoose.syaratDokumen.filter((_, i) => i !== index),
+ });
+ }
+
+ function handleEditSyarat(index: number, data: { name: string; desc: string }) {
+ setDataChoose({
+ ...dataChoose,
+ syaratDokumen: dataChoose.syaratDokumen.map((v, i) => (i === index ? data : v)),
+ });
+ }
+
+
+ return (
+ <>
+ {/* Modal Edit */}
+
+ {dataChoose?.syaratDokumen?.map((v: any) => (
+
+
+ {dataChoose?.dataText?.map((v: any) => (
+
+
+
+