upd: dahsboar admin
Deskripsi: - list kategori pelayanan surat - edit kategori pelayanan surat - tambah kategori pelayanan surat - hapush kategori pelayanan surat No Issues
This commit is contained in:
492
src/components/KategoriPelayananSurat.tsx
Normal file
492
src/components/KategoriPelayananSurat.tsx
Normal file
@@ -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 */}
|
||||||
|
<Modal
|
||||||
|
opened={opened}
|
||||||
|
onClose={close}
|
||||||
|
title={"Edit"}
|
||||||
|
size="xl"
|
||||||
|
overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
|
||||||
|
>
|
||||||
|
<Stack gap="lg">
|
||||||
|
<Input.Wrapper label="Kategori">
|
||||||
|
<Input value={dataChoose.name} onChange={(e) => setDataChoose({ ...dataChoose, name: e.target.value })} />
|
||||||
|
</Input.Wrapper>
|
||||||
|
<TagsInput
|
||||||
|
label="Data Pelengkap"
|
||||||
|
placeholder="Tambah data pelengkap"
|
||||||
|
splitChars={[',']}
|
||||||
|
value={dataChoose.dataText}
|
||||||
|
onChange={(value) => setDataChoose({ ...dataChoose, dataText: value })}
|
||||||
|
/>
|
||||||
|
<Flex direction={"column"} gap={"md"}>
|
||||||
|
<Group>
|
||||||
|
<Text size="sm" c={"white"}>
|
||||||
|
Syarat dokumen
|
||||||
|
</Text>
|
||||||
|
<Tooltip label="Tambah Syarat Dokumen">
|
||||||
|
<ActionIcon
|
||||||
|
variant="light"
|
||||||
|
size="sm"
|
||||||
|
color="blue"
|
||||||
|
style={{ boxShadow: "0 0 8px rgba(0,255,200,0.2)" }}
|
||||||
|
onClick={handleAddSyarat}
|
||||||
|
>
|
||||||
|
<IconPlus size={20} />
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
</Group>
|
||||||
|
{
|
||||||
|
dataChoose?.syaratDokumen?.map((v: any, i: number) => (
|
||||||
|
<Grid key={i} style={{ borderBottom: "1px solid gray", paddingBottom: "10px" }}>
|
||||||
|
<Grid.Col span={1} style={{ display: "flex", alignItems: "center", justifyContent: "center" }}>
|
||||||
|
<Tooltip label="Delete Syarat Dokumen">
|
||||||
|
<ActionIcon
|
||||||
|
variant="light"
|
||||||
|
size="sm"
|
||||||
|
color="red"
|
||||||
|
style={{ boxShadow: "0 0 8px rgba(0,255,200,0.2)" }}
|
||||||
|
onClick={() => {
|
||||||
|
handleDeleteSyarat(i)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<IconTrash size={20} />
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={5}>
|
||||||
|
<Input.Wrapper label="Nama">
|
||||||
|
<Input value={v.name} onChange={(e) => handleEditSyarat(i, { name: e.target.value, desc: v.desc })} />
|
||||||
|
</Input.Wrapper>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<Input.Wrapper label="Deskripsi">
|
||||||
|
<Input value={v.desc} onChange={(e) => handleEditSyarat(i, { name: v.name, desc: e.target.value })} />
|
||||||
|
</Input.Wrapper>
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Group justify="center" grow>
|
||||||
|
<Button variant="light" onClick={close}>
|
||||||
|
Batal
|
||||||
|
</Button>
|
||||||
|
<Button variant="filled" onClick={handleEdit} loading={btnLoading}>
|
||||||
|
Simpan
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
|
</Stack>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
{/* Modal Tambah */}
|
||||||
|
<Modal
|
||||||
|
opened={openedTambah}
|
||||||
|
onClose={closeTambah}
|
||||||
|
title={"Tambah"}
|
||||||
|
overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
|
||||||
|
size={"lg"}
|
||||||
|
>
|
||||||
|
<Stack gap="lg">
|
||||||
|
<Input.Wrapper label="Tambah Kategori Pelayanan Surat">
|
||||||
|
<Input value={dataTambah.name} onChange={(e) => setDataTambah({ ...dataTambah, name: e.target.value })} />
|
||||||
|
</Input.Wrapper>
|
||||||
|
<TagsInput
|
||||||
|
label="Data Pelengkap"
|
||||||
|
placeholder="Tambah data pelengkap"
|
||||||
|
splitChars={[',']}
|
||||||
|
value={dataTambah.dataText}
|
||||||
|
onChange={(value) => setDataTambah({ ...dataTambah, dataText: value })}
|
||||||
|
/>
|
||||||
|
<Flex direction={"column"} gap={"md"}>
|
||||||
|
<Group>
|
||||||
|
<Text size="sm" c={"white"}>
|
||||||
|
Syarat dokumen
|
||||||
|
</Text>
|
||||||
|
<Tooltip label="Tambah Syarat Dokumen">
|
||||||
|
<ActionIcon
|
||||||
|
variant="light"
|
||||||
|
size="sm"
|
||||||
|
color="blue"
|
||||||
|
style={{ boxShadow: "0 0 8px rgba(0,255,200,0.2)" }}
|
||||||
|
onClick={() => {
|
||||||
|
setDataTambah({ ...dataTambah, syaratDokumen: [...dataTambah.syaratDokumen, { name: "", desc: "" }] })
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<IconPlus size={20} />
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
</Group>
|
||||||
|
{
|
||||||
|
|
||||||
|
dataTambah?.syaratDokumen?.map((v: any, index: number) => (
|
||||||
|
<Grid key={index} style={{ borderBottom: "1px solid gray", paddingBottom: "10px" }}>
|
||||||
|
<Grid.Col span={1} style={{ display: "flex", alignItems: "center", justifyContent: "center" }}>
|
||||||
|
<Tooltip label="Delete Syarat Dokumen">
|
||||||
|
<ActionIcon
|
||||||
|
variant="light"
|
||||||
|
size="sm"
|
||||||
|
color="red"
|
||||||
|
style={{ boxShadow: "0 0 8px rgba(0,255,200,0.2)" }}
|
||||||
|
onClick={() => {
|
||||||
|
setDataTambah({ ...dataTambah, syaratDokumen: dataTambah.syaratDokumen.filter((v: any, i: number) => i !== index) })
|
||||||
|
}}
|
||||||
|
disabled={dataTambah?.syaratDokumen?.length === 1}
|
||||||
|
>
|
||||||
|
<IconTrash size={20} />
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={5}>
|
||||||
|
<Input.Wrapper label="Nama">
|
||||||
|
<Input value={dataTambah?.syaratDokumen[index]?.name} onChange={(e) => setDataTambah({ ...dataTambah, syaratDokumen: dataTambah.syaratDokumen.map((v: any, i: number) => i === index ? { ...v, name: e.target.value } : v) })} />
|
||||||
|
</Input.Wrapper>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<Input.Wrapper label="Deskripsi">
|
||||||
|
<Input value={dataTambah?.syaratDokumen[index]?.desc} onChange={(e) => setDataTambah({ ...dataTambah, syaratDokumen: dataTambah.syaratDokumen.map((v: any, i: number) => i === index ? { ...v, desc: e.target.value } : v) })} />
|
||||||
|
</Input.Wrapper>
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</Flex>
|
||||||
|
<Group justify="center" grow>
|
||||||
|
<Button variant="light" onClick={closeTambah}>
|
||||||
|
Batal
|
||||||
|
</Button>
|
||||||
|
<Button variant="filled" onClick={handleCreate} loading={btnLoading}>
|
||||||
|
Simpan
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
|
</Stack>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
{/* Modal Delete */}
|
||||||
|
<Modal
|
||||||
|
opened={openedDelete}
|
||||||
|
onClose={closeDelete}
|
||||||
|
title={"Delete Kategori Pelayanan Surat"}
|
||||||
|
overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
|
||||||
|
>
|
||||||
|
<Stack gap="md">
|
||||||
|
<Text size="md" color="gray.6">
|
||||||
|
Apakah anda yakin ingin menghapus kategori ini?
|
||||||
|
</Text>
|
||||||
|
<Group justify="center" grow>
|
||||||
|
<Button variant="light" onClick={closeDelete}>
|
||||||
|
Batal
|
||||||
|
</Button>
|
||||||
|
<Button variant="filled" color="red" onClick={handleDelete} loading={btnLoading}>
|
||||||
|
Hapus
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
|
</Stack>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
{/* Modal Detail */}
|
||||||
|
<Modal
|
||||||
|
opened={openedDetail}
|
||||||
|
onClose={closeDetail}
|
||||||
|
title={"Detail Kategori"}
|
||||||
|
overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
|
||||||
|
size={"lg"}
|
||||||
|
>
|
||||||
|
<Stack gap="sm">
|
||||||
|
<Flex direction={"column"}>
|
||||||
|
<Text size="sm" color="white">Kategori</Text>
|
||||||
|
<Text size="md" >{dataChoose?.name ?? ""}</Text>
|
||||||
|
</Flex>
|
||||||
|
<Flex direction={"column"}>
|
||||||
|
<Text size="sm" color="white">Syarat Dokumen</Text>
|
||||||
|
<List>
|
||||||
|
{dataChoose?.syaratDokumen?.map((v: any) => (
|
||||||
|
<List.Item key={v.id}>{v.desc}</List.Item>
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
</Flex>
|
||||||
|
<Flex direction={"column"}>
|
||||||
|
<Text size="sm" color="white">Data Pelengkap</Text>
|
||||||
|
<List>
|
||||||
|
{dataChoose?.dataText?.map((v: any) => (
|
||||||
|
<List.Item key={v.id}>{v}</List.Item>
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
</Flex>
|
||||||
|
</Stack>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
|
||||||
|
{/* Table */}
|
||||||
|
<Stack gap={"md"}>
|
||||||
|
<Flex align="center" justify="space-between">
|
||||||
|
<Title order={4} c="gray.2">
|
||||||
|
Kategori Pelayanan Surat
|
||||||
|
</Title>
|
||||||
|
<Tooltip label="Tambah Kategori Pelayanan Surat">
|
||||||
|
<Button
|
||||||
|
variant="light"
|
||||||
|
leftSection={<IconPlus size={20} />}
|
||||||
|
onClick={openTambah}
|
||||||
|
>
|
||||||
|
Tambah
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</Flex>
|
||||||
|
<Divider my={0} />
|
||||||
|
<Stack gap={"md"}>
|
||||||
|
<Table highlightOnHover>
|
||||||
|
<Table.Thead>
|
||||||
|
<Table.Tr>
|
||||||
|
<Table.Th>Kategori</Table.Th>
|
||||||
|
<Table.Th>Aksi</Table.Th>
|
||||||
|
</Table.Tr>
|
||||||
|
</Table.Thead>
|
||||||
|
<Table.Tbody>
|
||||||
|
{list?.map((v: any) => (
|
||||||
|
<Table.Tr key={v.id}>
|
||||||
|
<Table.Td>{v.name}</Table.Td>
|
||||||
|
<Table.Td>
|
||||||
|
<Group>
|
||||||
|
<Tooltip label="View Detail">
|
||||||
|
<ActionIcon
|
||||||
|
variant="light"
|
||||||
|
size="sm"
|
||||||
|
color="green"
|
||||||
|
style={{ boxShadow: "0 0 8px rgba(0,255,200,0.2)" }}
|
||||||
|
onClick={() => { setDataChoose(v); openDetail() }}
|
||||||
|
>
|
||||||
|
<IconEye size={20} />
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip label="Edit Kategori">
|
||||||
|
<ActionIcon
|
||||||
|
variant="light"
|
||||||
|
size="sm"
|
||||||
|
style={{ boxShadow: "0 0 8px rgba(0,255,200,0.2)" }}
|
||||||
|
onClick={() => { setDataChoose(v); open(); }}
|
||||||
|
>
|
||||||
|
<IconEdit size={20} />
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip label="Delete Kategori">
|
||||||
|
<ActionIcon
|
||||||
|
variant="light"
|
||||||
|
size="sm"
|
||||||
|
color="red"
|
||||||
|
style={{ boxShadow: "0 0 8px rgba(0,255,200,0.2)" }}
|
||||||
|
onClick={() => {
|
||||||
|
setDataDelete(v.id)
|
||||||
|
openDelete()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<IconTrash size={20} />
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
</Group>
|
||||||
|
</Table.Td>
|
||||||
|
</Table.Tr>
|
||||||
|
))}
|
||||||
|
</Table.Tbody>
|
||||||
|
</Table>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import DesaSetting from "@/components/DesaSetting";
|
import DesaSetting from "@/components/DesaSetting";
|
||||||
|
import KategoriPelayananSurat from "@/components/KategoriPelayananSurat";
|
||||||
import KategoriPengaduan from "@/components/KategoriPengaduan";
|
import KategoriPengaduan from "@/components/KategoriPengaduan";
|
||||||
import ProfileUser from "@/components/ProfileUser";
|
import ProfileUser from "@/components/ProfileUser";
|
||||||
import UserSetting from "@/components/UserSetting";
|
import UserSetting from "@/components/UserSetting";
|
||||||
@@ -90,7 +91,7 @@ export default function DetailSettingPage() {
|
|||||||
{type === "cat-pengaduan" ? (
|
{type === "cat-pengaduan" ? (
|
||||||
<KategoriPengaduan />
|
<KategoriPengaduan />
|
||||||
) : type === "cat-pelayanan" ? (
|
) : type === "cat-pelayanan" ? (
|
||||||
<KategoriPengaduanPage />
|
<KategoriPelayananSurat />
|
||||||
) : type === "desa" ? (
|
) : type === "desa" ? (
|
||||||
<DesaSetting />
|
<DesaSetting />
|
||||||
) : type === "user" ? (
|
) : type === "user" ? (
|
||||||
@@ -103,48 +104,4 @@ export default function DetailSettingPage() {
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function KategoriPengaduanPage() {
|
|
||||||
const elements = [
|
|
||||||
{ position: 6, mass: 12.011, symbol: "C", name: "Carbon" },
|
|
||||||
{ position: 7, mass: 14.007, symbol: "N", name: "Nitrogen" },
|
|
||||||
{ position: 39, mass: 88.906, symbol: "Y", name: "Yttrium" },
|
|
||||||
{ position: 56, mass: 137.33, symbol: "Ba", name: "Barium" },
|
|
||||||
{ position: 58, mass: 140.12, symbol: "Ce", name: "Cerium" },
|
|
||||||
];
|
|
||||||
|
|
||||||
const rows = elements.map((element) => (
|
|
||||||
<Table.Tr key={element.name}>
|
|
||||||
<Table.Td>{element.position}</Table.Td>
|
|
||||||
<Table.Td>{element.name}</Table.Td>
|
|
||||||
<Table.Td>{element.symbol}</Table.Td>
|
|
||||||
<Table.Td>{element.mass}</Table.Td>
|
|
||||||
</Table.Tr>
|
|
||||||
));
|
|
||||||
return (
|
|
||||||
<Stack gap={"md"}>
|
|
||||||
<Flex align="center" justify="space-between">
|
|
||||||
<Title order={4} c="gray.2">
|
|
||||||
Kategori Pengaduan
|
|
||||||
</Title>
|
|
||||||
<Button variant="light">Tambah</Button>
|
|
||||||
</Flex>
|
|
||||||
<Divider my={0} />
|
|
||||||
<Stack gap={"md"}>
|
|
||||||
<Table>
|
|
||||||
<Table.Thead>
|
|
||||||
<Table.Tr>
|
|
||||||
<Table.Th>Tanggal</Table.Th>
|
|
||||||
<Table.Th>Deskripsi</Table.Th>
|
|
||||||
<Table.Th>Status</Table.Th>
|
|
||||||
<Table.Th>User</Table.Th>
|
|
||||||
</Table.Tr>
|
|
||||||
</Table.Thead>
|
|
||||||
<Table.Tbody>{rows}</Table.Tbody>
|
|
||||||
</Table>
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import Elysia, { StatusMap, t } from "elysia"
|
import Elysia, { t } from "elysia"
|
||||||
import { generateNoPengajuanSurat } from "../lib/no-pengajuan-surat"
|
|
||||||
import { prisma } from "../lib/prisma"
|
|
||||||
import type { StatusPengaduan } from "generated/prisma"
|
import type { StatusPengaduan } from "generated/prisma"
|
||||||
|
import { generateNoPengajuanSurat } from "../lib/no-pengajuan-surat"
|
||||||
import { normalizePhoneNumber } from "../lib/normalizePhone"
|
import { normalizePhoneNumber } from "../lib/normalizePhone"
|
||||||
|
import { prisma } from "../lib/prisma"
|
||||||
|
|
||||||
const PelayananRoute = new Elysia({
|
const PelayananRoute = new Elysia({
|
||||||
prefix: "pelayanan",
|
prefix: "pelayanan",
|
||||||
@@ -15,7 +15,7 @@ const PelayananRoute = new Elysia({
|
|||||||
where: {
|
where: {
|
||||||
isActive: true
|
isActive: true
|
||||||
},
|
},
|
||||||
orderBy:{
|
orderBy: {
|
||||||
name: "asc"
|
name: "asc"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -42,8 +42,8 @@ const PelayananRoute = new Elysia({
|
|||||||
}, {
|
}, {
|
||||||
body: t.Object({
|
body: t.Object({
|
||||||
name: t.String({ minLength: 1, error: "name harus diisi" }),
|
name: t.String({ minLength: 1, error: "name harus diisi" }),
|
||||||
syaratDokumen: t.Array(t.String({ minLength: 1, error: "syaratDokumen harus diisi" })),
|
syaratDokumen: t.Any(),
|
||||||
dataText: t.Array(t.String({ minLength: 1, error: "dataText harus diisi" })),
|
dataText: t.Any(),
|
||||||
}),
|
}),
|
||||||
detail: {
|
detail: {
|
||||||
summary: "buat kategori pelayanan surat",
|
summary: "buat kategori pelayanan surat",
|
||||||
@@ -69,8 +69,8 @@ const PelayananRoute = new Elysia({
|
|||||||
body: t.Object({
|
body: t.Object({
|
||||||
id: t.String({ minLength: 1, error: "id harus diisi" }),
|
id: t.String({ minLength: 1, error: "id harus diisi" }),
|
||||||
name: t.String({ minLength: 1, error: "name harus diisi" }),
|
name: t.String({ minLength: 1, error: "name harus diisi" }),
|
||||||
syaratDokumen: t.Array(t.String({ minLength: 1, error: "syaratDokumen harus diisi" })),
|
syaratDokumen: t.Any(),
|
||||||
dataText: t.Array(t.String({ minLength: 1, error: "dataText harus diisi" })),
|
dataText: t.Any(),
|
||||||
}),
|
}),
|
||||||
detail: {
|
detail: {
|
||||||
summary: "update kategori pelayanan surat",
|
summary: "update kategori pelayanan surat",
|
||||||
|
|||||||
Reference in New Issue
Block a user