update: dashboard admin
Deskripsi: - list pelayanan surat - detail pelayanan surat No Issues
This commit is contained in:
@@ -18,6 +18,7 @@ import Home from "./pages/Home";
|
|||||||
import CredentialPage from "./pages/scr/dashboard/credential/credential_page";
|
import CredentialPage from "./pages/scr/dashboard/credential/credential_page";
|
||||||
import DashboardHome from "./pages/scr/dashboard/dashboard_home";
|
import DashboardHome from "./pages/scr/dashboard/dashboard_home";
|
||||||
import ListPelayananPage from "./pages/scr/dashboard/pelayanan-surat/list_pelayanan_page";
|
import ListPelayananPage from "./pages/scr/dashboard/pelayanan-surat/list_pelayanan_page";
|
||||||
|
import DetailPelayananPage from "./pages/scr/dashboard/pelayanan-surat/detail_pelayanan_page";
|
||||||
import ListPage from "./pages/scr/dashboard/pengaduan/list_page";
|
import ListPage from "./pages/scr/dashboard/pengaduan/list_page";
|
||||||
import DetailPage from "./pages/scr/dashboard/pengaduan/detail_page";
|
import DetailPage from "./pages/scr/dashboard/pengaduan/detail_page";
|
||||||
import ApikeyPage from "./pages/scr/dashboard/apikey/apikey_page";
|
import ApikeyPage from "./pages/scr/dashboard/apikey/apikey_page";
|
||||||
@@ -99,6 +100,10 @@ export default function AppRoutes() {
|
|||||||
path="/scr/dashboard/pelayanan-surat/list-pelayanan"
|
path="/scr/dashboard/pelayanan-surat/list-pelayanan"
|
||||||
element={<ListPelayananPage />}
|
element={<ListPelayananPage />}
|
||||||
/>
|
/>
|
||||||
|
<Route
|
||||||
|
path="/scr/dashboard/pelayanan-surat/detail-pelayanan"
|
||||||
|
element={<DetailPelayananPage />}
|
||||||
|
/>
|
||||||
<Route
|
<Route
|
||||||
path="/scr/dashboard/pengaduan/list"
|
path="/scr/dashboard/pengaduan/list"
|
||||||
element={<ListPage />}
|
element={<ListPage />}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ const clientRoutes = {
|
|||||||
"/scr/dashboard/credential/credential": "/scr/dashboard/credential/credential",
|
"/scr/dashboard/credential/credential": "/scr/dashboard/credential/credential",
|
||||||
"/scr/dashboard/dashboard-home": "/scr/dashboard/dashboard-home",
|
"/scr/dashboard/dashboard-home": "/scr/dashboard/dashboard-home",
|
||||||
"/scr/dashboard/pelayanan-surat/list-pelayanan": "/scr/dashboard/pelayanan-surat/list-pelayanan",
|
"/scr/dashboard/pelayanan-surat/list-pelayanan": "/scr/dashboard/pelayanan-surat/list-pelayanan",
|
||||||
|
"/scr/dashboard/pelayanan-surat/detail-pelayanan": "/scr/dashboard/pelayanan-surat/detail-pelayanan",
|
||||||
"/scr/dashboard/pengaduan/list": "/scr/dashboard/pengaduan/list",
|
"/scr/dashboard/pengaduan/list": "/scr/dashboard/pengaduan/list",
|
||||||
"/scr/dashboard/pengaduan/detail": "/scr/dashboard/pengaduan/detail",
|
"/scr/dashboard/pengaduan/detail": "/scr/dashboard/pengaduan/detail",
|
||||||
"/scr/dashboard/apikey/apikey": "/scr/dashboard/apikey/apikey",
|
"/scr/dashboard/apikey/apikey": "/scr/dashboard/apikey/apikey",
|
||||||
|
|||||||
@@ -0,0 +1,370 @@
|
|||||||
|
import apiFetch from "@/lib/apiFetch";
|
||||||
|
import {
|
||||||
|
Anchor,
|
||||||
|
Badge,
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
Container,
|
||||||
|
Divider,
|
||||||
|
Flex,
|
||||||
|
Grid,
|
||||||
|
Group,
|
||||||
|
Modal,
|
||||||
|
Stack,
|
||||||
|
Table,
|
||||||
|
Text,
|
||||||
|
Textarea,
|
||||||
|
Title,
|
||||||
|
} from "@mantine/core";
|
||||||
|
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
|
||||||
|
import {
|
||||||
|
IconAlignJustified,
|
||||||
|
IconCategory,
|
||||||
|
IconFileCertificate,
|
||||||
|
IconInfoTriangle,
|
||||||
|
IconMapPin,
|
||||||
|
IconMessageReport,
|
||||||
|
IconPhotoScan,
|
||||||
|
IconUser,
|
||||||
|
} from "@tabler/icons-react";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { useLocation } from "react-router-dom";
|
||||||
|
import useSwr from "swr";
|
||||||
|
|
||||||
|
export default function DetailPelayananPage() {
|
||||||
|
const { search } = useLocation();
|
||||||
|
const query = new URLSearchParams(search);
|
||||||
|
const id = query.get("id");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container size="xl" py="xl" w={"100%"}>
|
||||||
|
<Grid>
|
||||||
|
<Grid.Col span={8}>
|
||||||
|
<Stack gap={"xl"}>
|
||||||
|
<DetailDataPelayanan />
|
||||||
|
<DetailDataHistori />
|
||||||
|
</Stack>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={4}>
|
||||||
|
<DetailUserPelayanan />
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function DetailDataPelayanan() {
|
||||||
|
const [opened, { open, close }] = useDisclosure(false);
|
||||||
|
const [catModal, setCatModal] = useState<"tolak" | "terima">("tolak");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Modal
|
||||||
|
opened={opened}
|
||||||
|
onClose={close}
|
||||||
|
title={"Konfirmasi"}
|
||||||
|
centered
|
||||||
|
overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
|
||||||
|
>
|
||||||
|
<Stack gap="sm">
|
||||||
|
{catModal === "tolak" ? (
|
||||||
|
<>
|
||||||
|
<Text>
|
||||||
|
Anda yakin ingin menolak pengaduan ini? Berikan alasan penolakan
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Textarea size="md" minRows={5} />
|
||||||
|
<Group justify="center" grow>
|
||||||
|
<Button variant="light" onClick={close}>
|
||||||
|
Batal
|
||||||
|
</Button>
|
||||||
|
<Button variant="filled" color="red" onClick={close}>
|
||||||
|
Tolak
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Text>Anda yakin ingin menerima pengaduan ini?</Text>
|
||||||
|
<Group justify="center" grow>
|
||||||
|
<Button variant="light" onClick={close}>
|
||||||
|
Batal
|
||||||
|
</Button>
|
||||||
|
<Button variant="filled" color="green" onClick={close}>
|
||||||
|
Terima
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
<Card
|
||||||
|
radius="md"
|
||||||
|
p="lg"
|
||||||
|
withBorder
|
||||||
|
style={{
|
||||||
|
background:
|
||||||
|
"linear-gradient(145deg, rgba(25,25,25,0.95), rgba(45,45,45,0.85))",
|
||||||
|
borderColor: "rgba(100,100,100,0.2)",
|
||||||
|
boxShadow: "0 0 20px rgba(0,255,200,0.08)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Stack gap={"md"}>
|
||||||
|
<Flex align="center" justify="space-between">
|
||||||
|
<Group gap="xs">
|
||||||
|
<Title order={4} c="gray.2">
|
||||||
|
Pelayanan Surat
|
||||||
|
</Title>
|
||||||
|
<Title order={4} c="dimmed">
|
||||||
|
#PGf-2345-33
|
||||||
|
</Title>
|
||||||
|
</Group>
|
||||||
|
<Badge
|
||||||
|
size="xl"
|
||||||
|
variant="light"
|
||||||
|
radius="sm"
|
||||||
|
color={"yellow"}
|
||||||
|
style={{ textTransform: "none" }}
|
||||||
|
>
|
||||||
|
antrian
|
||||||
|
</Badge>
|
||||||
|
</Flex>
|
||||||
|
<Divider my={0} />
|
||||||
|
<Grid>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<Stack gap="md">
|
||||||
|
<Flex direction={"column"} justify="flex-start">
|
||||||
|
<Group gap="xs">
|
||||||
|
<IconAlignJustified size={20} />
|
||||||
|
<Text size="md">Judul</Text>
|
||||||
|
</Group>
|
||||||
|
<Text size="md" c={"white"}>
|
||||||
|
Judul Pelayanan Surat
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
<Flex direction={"column"} justify="flex-start">
|
||||||
|
<Group gap="xs">
|
||||||
|
<IconMapPin size={20} />
|
||||||
|
<Text size="md">Lokasi</Text>
|
||||||
|
</Group>
|
||||||
|
<Text size="md" c="white">
|
||||||
|
fwef
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
</Stack>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<Stack gap="md">
|
||||||
|
<Flex direction={"column"} justify="flex-start">
|
||||||
|
<Group gap="xs">
|
||||||
|
<IconCategory size={20} />
|
||||||
|
<Text size="md">Kategori</Text>
|
||||||
|
</Group>
|
||||||
|
<Text size="md" c="white">
|
||||||
|
fwef
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
<Flex direction={"column"} justify="flex-start">
|
||||||
|
<Group gap="xs">
|
||||||
|
<IconPhotoScan size={20} />
|
||||||
|
<Text size="md">Gambar</Text>
|
||||||
|
</Group>
|
||||||
|
<Anchor href="https://mantine.dev/" target="_blank">
|
||||||
|
Lihat Gambar
|
||||||
|
</Anchor>
|
||||||
|
</Flex>
|
||||||
|
</Stack>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={12}>
|
||||||
|
<Stack gap="md">
|
||||||
|
<Flex direction={"column"} justify="flex-start">
|
||||||
|
<Group gap="xs">
|
||||||
|
<IconAlignJustified size={20} />
|
||||||
|
<Text size="md">Detail</Text>
|
||||||
|
</Group>
|
||||||
|
<Text size="md" c="white">
|
||||||
|
Lorem ipsum dolor sit, amet consectetur adipisicing elit.
|
||||||
|
Illum, corporis iusto. Suscipit veritatis quas, non nobis
|
||||||
|
fuga, laudantium accusantium tempora sint aliquid architecto
|
||||||
|
totam esse eum excepturi nostrum fugiat ut.
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
<Flex direction={"column"} justify="flex-start">
|
||||||
|
<Group gap="xs">
|
||||||
|
<IconInfoTriangle size={20} />
|
||||||
|
<Text size="md">Keterangan</Text>
|
||||||
|
</Group>
|
||||||
|
<Text size="md" c={"white"}>
|
||||||
|
Lorem ipsum dolor, sit amet consectetur adipisicing elit. At
|
||||||
|
fugiat eligendi nesciunt dolore? Maiores a cumque vitae
|
||||||
|
suscipit incidunt quos beatae modi, vel, id ullam quae
|
||||||
|
voluptas, deserunt quas placeat.
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
</Stack>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={12}>
|
||||||
|
<Group justify="center" grow>
|
||||||
|
<Button
|
||||||
|
variant="light"
|
||||||
|
onClick={() => {
|
||||||
|
setCatModal("tolak");
|
||||||
|
open();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Tolak
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="filled"
|
||||||
|
onClick={() => {
|
||||||
|
setCatModal("terima");
|
||||||
|
open();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Terima
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function DetailDataHistori() {
|
||||||
|
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 (
|
||||||
|
<Card
|
||||||
|
radius="md"
|
||||||
|
p="lg"
|
||||||
|
withBorder
|
||||||
|
style={{
|
||||||
|
background:
|
||||||
|
"linear-gradient(145deg, rgba(25,25,25,0.95), rgba(45,45,45,0.85))",
|
||||||
|
borderColor: "rgba(100,100,100,0.2)",
|
||||||
|
boxShadow: "0 0 20px rgba(0,255,200,0.08)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Stack gap="md">
|
||||||
|
<Flex align="center" justify="space-between">
|
||||||
|
<Title order={4} c="gray.2">
|
||||||
|
Histori Pengaduan
|
||||||
|
</Title>
|
||||||
|
</Flex>
|
||||||
|
<Divider my={0} />
|
||||||
|
<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>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function DetailUserPelayanan() {
|
||||||
|
const [page, setPage] = useState(1);
|
||||||
|
const [value, setValue] = useState("");
|
||||||
|
const { data, mutate, isLoading } = useSwr("/", () =>
|
||||||
|
apiFetch.api.pengaduan.list.get({
|
||||||
|
query: {
|
||||||
|
status,
|
||||||
|
search: value,
|
||||||
|
take: "",
|
||||||
|
page: "",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
useShallowEffect(() => {
|
||||||
|
mutate();
|
||||||
|
}, [status, value]);
|
||||||
|
|
||||||
|
const list = data?.data || [];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card
|
||||||
|
radius="md"
|
||||||
|
p="lg"
|
||||||
|
withBorder
|
||||||
|
style={{
|
||||||
|
background:
|
||||||
|
"linear-gradient(145deg, rgba(25,25,25,0.95), rgba(45,45,45,0.85))",
|
||||||
|
borderColor: "rgba(100,100,100,0.2)",
|
||||||
|
boxShadow: "0 0 20px rgba(0,255,200,0.08)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Stack gap="md">
|
||||||
|
<Flex align="center" justify="space-between">
|
||||||
|
<Flex direction={"column"}>
|
||||||
|
<Title order={4} c="gray.2">
|
||||||
|
Warga
|
||||||
|
</Title>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
<Divider my={0} />
|
||||||
|
<Stack gap="md">
|
||||||
|
<Group justify="space-between">
|
||||||
|
<Group gap="xs">
|
||||||
|
<IconUser size={20} />
|
||||||
|
<Text size="md">Nama</Text>
|
||||||
|
</Group>
|
||||||
|
<Text size="md" c={"white"}>
|
||||||
|
Amalia Dwi Yustiani
|
||||||
|
</Text>
|
||||||
|
</Group>
|
||||||
|
<Group justify="space-between">
|
||||||
|
<Group gap="xs">
|
||||||
|
<IconMapPin size={20} />
|
||||||
|
<Text size="md">Telepon</Text>
|
||||||
|
</Group>
|
||||||
|
<Text size="md" c="white">
|
||||||
|
08123456789
|
||||||
|
</Text>
|
||||||
|
</Group>
|
||||||
|
<Group justify="space-between">
|
||||||
|
<Group gap="xs">
|
||||||
|
<IconMessageReport size={20} />
|
||||||
|
<Text size="md">Jumlah Pengaduan</Text>
|
||||||
|
</Group>
|
||||||
|
<Text size="md" c="white">
|
||||||
|
10
|
||||||
|
</Text>
|
||||||
|
</Group>
|
||||||
|
<Group justify="space-between">
|
||||||
|
<Group gap="xs">
|
||||||
|
<IconFileCertificate size={20} />
|
||||||
|
<Text size="md">Jumlah Pelayanan Surat</Text>
|
||||||
|
</Group>
|
||||||
|
<Text size="md" c="white">
|
||||||
|
10
|
||||||
|
</Text>
|
||||||
|
</Group>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -133,6 +133,8 @@ function ListPelayananSurat({ status }: { status: StatusKey }) {
|
|||||||
mutate();
|
mutate();
|
||||||
}, [status, value]);
|
}, [status, value]);
|
||||||
|
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
if (isLoading)
|
if (isLoading)
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
@@ -169,17 +171,13 @@ function ListPelayananSurat({ status }: { status: StatusKey }) {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
{/* <Group justify="flex-end">
|
|
||||||
<Text size="sm">Menampilkan {Number(data?.data?.length) * (page - 1) + 1} – {Math.min(10, Number(data?.data?.length) * page)} dari {Number(data?.data?.length)}</Text>
|
|
||||||
<Pagination total={Number(data?.data?.length)} value={page} onChange={setPage} withPages={false} />
|
|
||||||
</Group> */}
|
|
||||||
</Group>
|
</Group>
|
||||||
{list.length === 0 ? (
|
{list.length === 0 ? (
|
||||||
<Flex justify="center" align="center" py={"xl"}>
|
<Flex justify="center" align="center" py={"xl"}>
|
||||||
<Stack gap={4} align="center">
|
<Stack gap={4} align="center">
|
||||||
<IconFileSad size={32} color="gray" />
|
<IconFileSad size={32} color="gray" />
|
||||||
<Text c="dimmed" size="sm">
|
<Text c="dimmed" size="sm">
|
||||||
No pengaduan have been added yet.
|
No pelayanan surat have been added yet.
|
||||||
</Text>
|
</Text>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -196,6 +194,9 @@ function ListPelayananSurat({ status }: { status: StatusKey }) {
|
|||||||
borderColor: "rgba(100,100,100,0.2)",
|
borderColor: "rgba(100,100,100,0.2)",
|
||||||
boxShadow: "0 0 20px rgba(0,255,200,0.08)",
|
boxShadow: "0 0 20px rgba(0,255,200,0.08)",
|
||||||
}}
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
navigate(`/scr/dashboard/pelayanan-surat/detail-pelayanan?id=${v.id}`);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Stack gap="md">
|
<Stack gap="md">
|
||||||
<Flex align="center" justify="space-between">
|
<Flex align="center" justify="space-between">
|
||||||
|
|||||||
@@ -1,345 +1,370 @@
|
|||||||
import apiFetch from "@/lib/apiFetch";
|
import apiFetch from "@/lib/apiFetch";
|
||||||
import {
|
import {
|
||||||
Anchor,
|
Anchor,
|
||||||
Badge,
|
Badge,
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
Container,
|
Container,
|
||||||
Divider,
|
Divider,
|
||||||
Flex,
|
Flex,
|
||||||
Grid,
|
Grid,
|
||||||
Group,
|
Group,
|
||||||
Modal,
|
Modal,
|
||||||
Stack,
|
Stack,
|
||||||
Table,
|
Table,
|
||||||
Text,
|
Text,
|
||||||
Textarea,
|
Textarea,
|
||||||
Title
|
Title,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
|
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
|
||||||
import {
|
import {
|
||||||
IconAlignJustified,
|
IconAlignJustified,
|
||||||
IconCategory,
|
IconCategory,
|
||||||
IconFileCertificate,
|
IconFileCertificate,
|
||||||
IconInfoTriangle,
|
IconInfoTriangle,
|
||||||
IconMapPin,
|
IconMapPin,
|
||||||
IconMessageReport,
|
IconMessageReport,
|
||||||
IconPhotoScan,
|
IconPhotoScan,
|
||||||
IconUser
|
IconUser,
|
||||||
} from "@tabler/icons-react";
|
} from "@tabler/icons-react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
import useSwr from "swr";
|
import useSwr from "swr";
|
||||||
|
|
||||||
export default function DetailPengaduanPage() {
|
export default function DetailPengaduanPage() {
|
||||||
const { search } = useLocation();
|
const { search } = useLocation();
|
||||||
const query = new URLSearchParams(search);
|
const query = new URLSearchParams(search);
|
||||||
const id = query.get("id");
|
const id = query.get("id");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container size="xl" py="xl" w={"100%"}>
|
<Container size="xl" py="xl" w={"100%"}>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.Col span={8}>
|
<Grid.Col span={8}>
|
||||||
<Stack gap={"xl"}>
|
<Stack gap={"xl"}>
|
||||||
<DetailDataPengaduan />
|
<DetailDataPengaduan />
|
||||||
<DetailDataHistori />
|
<DetailDataHistori />
|
||||||
</Stack>
|
</Stack>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
<Grid.Col span={4}>
|
<Grid.Col span={4}>
|
||||||
<DetailUserPengaduan />
|
<DetailUserPengaduan />
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function DetailDataPengaduan() {
|
function DetailDataPengaduan() {
|
||||||
const [opened, { open, close }] = useDisclosure(false);
|
const [opened, { open, close }] = useDisclosure(false);
|
||||||
const [catModal, setCatModal] = useState<'tolak' | 'terima'>('tolak');
|
const [catModal, setCatModal] = useState<"tolak" | "terima">("tolak");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Modal opened={opened} onClose={close} title={"Konfirmasi"} centered overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}>
|
<Modal
|
||||||
<Stack gap="sm">
|
opened={opened}
|
||||||
{
|
onClose={close}
|
||||||
catModal === 'tolak'
|
title={"Konfirmasi"}
|
||||||
? (
|
centered
|
||||||
<>
|
overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
|
||||||
<Text>Anda yakin ingin menolak pengaduan ini? Berikan alasan penolakan</Text>
|
>
|
||||||
|
<Stack gap="sm">
|
||||||
|
{catModal === "tolak" ? (
|
||||||
|
<>
|
||||||
|
<Text>
|
||||||
|
Anda yakin ingin menolak pengaduan ini? Berikan alasan penolakan
|
||||||
|
</Text>
|
||||||
|
|
||||||
<Textarea size="md" minRows={5} />
|
<Textarea size="md" minRows={5} />
|
||||||
<Group justify="center" grow>
|
<Group justify="center" grow>
|
||||||
<Button variant="light" onClick={close}>Batal</Button>
|
<Button variant="light" onClick={close}>
|
||||||
<Button variant="filled" color="red" onClick={close}>Tolak</Button>
|
Batal
|
||||||
</Group>
|
</Button>
|
||||||
</>
|
<Button variant="filled" color="red" onClick={close}>
|
||||||
)
|
Tolak
|
||||||
:
|
</Button>
|
||||||
(
|
</Group>
|
||||||
<>
|
</>
|
||||||
<Text>Anda yakin ingin menerima pengaduan ini?</Text>
|
) : (
|
||||||
<Group justify="center" grow>
|
<>
|
||||||
<Button variant="light" onClick={close}>Batal</Button>
|
<Text>Anda yakin ingin menerima pengaduan ini?</Text>
|
||||||
<Button variant="filled" color="green" onClick={close}>Terima</Button>
|
<Group justify="center" grow>
|
||||||
</Group>
|
<Button variant="light" onClick={close}>
|
||||||
</>
|
Batal
|
||||||
)
|
</Button>
|
||||||
}
|
<Button variant="filled" color="green" onClick={close}>
|
||||||
|
Terima
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
</Stack>
|
<Card
|
||||||
</Modal>
|
radius="md"
|
||||||
|
p="lg"
|
||||||
<Card
|
withBorder
|
||||||
radius="md"
|
style={{
|
||||||
p="lg"
|
background:
|
||||||
withBorder
|
"linear-gradient(145deg, rgba(25,25,25,0.95), rgba(45,45,45,0.85))",
|
||||||
style={{
|
borderColor: "rgba(100,100,100,0.2)",
|
||||||
background:
|
boxShadow: "0 0 20px rgba(0,255,200,0.08)",
|
||||||
"linear-gradient(145deg, rgba(25,25,25,0.95), rgba(45,45,45,0.85))",
|
}}
|
||||||
borderColor: "rgba(100,100,100,0.2)",
|
>
|
||||||
boxShadow: "0 0 20px rgba(0,255,200,0.08)",
|
<Stack gap={"md"}>
|
||||||
}}
|
<Flex align="center" justify="space-between">
|
||||||
>
|
<Group gap="xs">
|
||||||
<Stack gap={"md"}>
|
<Title order={4} c="gray.2">
|
||||||
<Flex align="center" justify="space-between">
|
Pengaduan
|
||||||
|
</Title>
|
||||||
|
<Title order={4} c="dimmed">
|
||||||
|
#PGf-2345-33
|
||||||
|
</Title>
|
||||||
|
</Group>
|
||||||
|
<Badge
|
||||||
|
size="xl"
|
||||||
|
variant="light"
|
||||||
|
radius="sm"
|
||||||
|
color={"yellow"}
|
||||||
|
style={{ textTransform: "none" }}
|
||||||
|
>
|
||||||
|
antrian
|
||||||
|
</Badge>
|
||||||
|
</Flex>
|
||||||
|
<Divider my={0} />
|
||||||
|
<Grid>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<Stack gap="md">
|
||||||
|
<Flex direction={"column"} justify="flex-start">
|
||||||
<Group gap="xs">
|
<Group gap="xs">
|
||||||
<Title order={4} c="gray.2">
|
<IconAlignJustified size={20} />
|
||||||
Pengaduan
|
<Text size="md">Judul</Text>
|
||||||
</Title>
|
|
||||||
<Title order={4} c="dimmed">
|
|
||||||
#PGf-2345-33
|
|
||||||
</Title>
|
|
||||||
</Group>
|
</Group>
|
||||||
<Badge
|
<Text size="md" c={"white"}>
|
||||||
size="xl"
|
Judul Pengaduan
|
||||||
variant="light"
|
</Text>
|
||||||
radius="sm"
|
</Flex>
|
||||||
color={"yellow"}
|
<Flex direction={"column"} justify="flex-start">
|
||||||
style={{ textTransform: "none" }}
|
<Group gap="xs">
|
||||||
>
|
<IconMapPin size={20} />
|
||||||
antrian
|
<Text size="md">Lokasi</Text>
|
||||||
</Badge>
|
</Group>
|
||||||
</Flex>
|
<Text size="md" c="white">
|
||||||
<Divider my={0} />
|
fwef
|
||||||
<Grid>
|
</Text>
|
||||||
<Grid.Col span={6}>
|
</Flex>
|
||||||
<Stack gap="md">
|
</Stack>
|
||||||
<Flex direction={"column"} justify="flex-start">
|
</Grid.Col>
|
||||||
<Group gap="xs">
|
<Grid.Col span={6}>
|
||||||
<IconAlignJustified size={20} />
|
<Stack gap="md">
|
||||||
<Text size="md">
|
<Flex direction={"column"} justify="flex-start">
|
||||||
Judul
|
<Group gap="xs">
|
||||||
</Text>
|
<IconCategory size={20} />
|
||||||
</Group>
|
<Text size="md">Kategori</Text>
|
||||||
<Text size="md" c={"white"}>Judul Pengaduan</Text>
|
</Group>
|
||||||
</Flex>
|
<Text size="md" c="white">
|
||||||
<Flex direction={"column"} justify="flex-start">
|
fwef
|
||||||
<Group gap="xs">
|
</Text>
|
||||||
<IconMapPin size={20} />
|
</Flex>
|
||||||
<Text size="md">
|
<Flex direction={"column"} justify="flex-start">
|
||||||
Lokasi
|
<Group gap="xs">
|
||||||
</Text>
|
<IconPhotoScan size={20} />
|
||||||
</Group>
|
<Text size="md">Gambar</Text>
|
||||||
<Text size="md" c="white">fwef</Text>
|
</Group>
|
||||||
</Flex>
|
<Anchor href="https://mantine.dev/" target="_blank">
|
||||||
</Stack>
|
Lihat Gambar
|
||||||
</Grid.Col>
|
</Anchor>
|
||||||
<Grid.Col span={6}>
|
</Flex>
|
||||||
<Stack gap="md">
|
</Stack>
|
||||||
<Flex direction={"column"} justify="flex-start">
|
</Grid.Col>
|
||||||
<Group gap="xs">
|
<Grid.Col span={12}>
|
||||||
<IconCategory size={20} />
|
<Stack gap="md">
|
||||||
<Text size="md">
|
<Flex direction={"column"} justify="flex-start">
|
||||||
Kategori
|
<Group gap="xs">
|
||||||
</Text>
|
<IconAlignJustified size={20} />
|
||||||
</Group>
|
<Text size="md">Detail</Text>
|
||||||
<Text size="md" c="white">fwef</Text>
|
</Group>
|
||||||
</Flex>
|
<Text size="md" c="white">
|
||||||
<Flex direction={"column"} justify="flex-start">
|
Lorem ipsum dolor sit, amet consectetur adipisicing elit.
|
||||||
<Group gap="xs">
|
Illum, corporis iusto. Suscipit veritatis quas, non nobis
|
||||||
<IconPhotoScan size={20} />
|
fuga, laudantium accusantium tempora sint aliquid architecto
|
||||||
<Text size="md">
|
totam esse eum excepturi nostrum fugiat ut.
|
||||||
Gambar
|
</Text>
|
||||||
</Text>
|
</Flex>
|
||||||
</Group>
|
<Flex direction={"column"} justify="flex-start">
|
||||||
<Anchor href="https://mantine.dev/" target="_blank">
|
<Group gap="xs">
|
||||||
Lihat Gambar
|
<IconInfoTriangle size={20} />
|
||||||
</Anchor>
|
<Text size="md">Keterangan</Text>
|
||||||
</Flex>
|
</Group>
|
||||||
</Stack>
|
<Text size="md" c={"white"}>
|
||||||
</Grid.Col>
|
Lorem ipsum dolor, sit amet consectetur adipisicing elit. At
|
||||||
<Grid.Col span={12}>
|
fugiat eligendi nesciunt dolore? Maiores a cumque vitae
|
||||||
<Stack gap="md">
|
suscipit incidunt quos beatae modi, vel, id ullam quae
|
||||||
<Flex direction={"column"} justify="flex-start">
|
voluptas, deserunt quas placeat.
|
||||||
<Group gap="xs">
|
</Text>
|
||||||
<IconAlignJustified size={20} />
|
</Flex>
|
||||||
<Text size="md">
|
</Stack>
|
||||||
Detail
|
</Grid.Col>
|
||||||
</Text>
|
<Grid.Col span={12}>
|
||||||
</Group>
|
<Group justify="center" grow>
|
||||||
<Text size="md" c="white">
|
<Button
|
||||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Illum, corporis iusto. Suscipit veritatis quas, non nobis fuga, laudantium accusantium tempora sint aliquid architecto totam esse eum excepturi nostrum fugiat ut.
|
variant="light"
|
||||||
</Text>
|
onClick={() => {
|
||||||
</Flex>
|
setCatModal("tolak");
|
||||||
<Flex direction={"column"} justify="flex-start">
|
open();
|
||||||
<Group gap="xs">
|
}}
|
||||||
<IconInfoTriangle size={20} />
|
>
|
||||||
<Text size="md">
|
Tolak
|
||||||
Keterangan
|
</Button>
|
||||||
</Text>
|
<Button
|
||||||
</Group>
|
variant="filled"
|
||||||
<Text size="md" c={"white"}>
|
onClick={() => {
|
||||||
Lorem ipsum dolor, sit amet consectetur adipisicing elit. At fugiat eligendi nesciunt dolore? Maiores a cumque vitae suscipit incidunt quos beatae modi, vel, id ullam quae voluptas, deserunt quas placeat.
|
setCatModal("terima");
|
||||||
</Text>
|
open();
|
||||||
</Flex>
|
}}
|
||||||
</Stack>
|
>
|
||||||
</Grid.Col>
|
Terima
|
||||||
<Grid.Col span={12}>
|
</Button>
|
||||||
<Group justify="center" grow>
|
</Group>
|
||||||
<Button variant="light" onClick={() => { setCatModal('tolak'); open() }}>Tolak</Button>
|
</Grid.Col>
|
||||||
<Button variant="filled" onClick={() => { setCatModal('terima'); open() }}>Terima</Button>
|
</Grid>
|
||||||
</Group>
|
</Stack>
|
||||||
</Grid.Col>
|
</Card>
|
||||||
</Grid>
|
</>
|
||||||
</Stack>
|
);
|
||||||
</Card>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function DetailDataHistori() {
|
function DetailDataHistori() {
|
||||||
const elements = [
|
const elements = [
|
||||||
{ position: 6, mass: 12.011, symbol: 'C', name: 'Carbon' },
|
{ position: 6, mass: 12.011, symbol: "C", name: "Carbon" },
|
||||||
{ position: 7, mass: 14.007, symbol: 'N', name: 'Nitrogen' },
|
{ position: 7, mass: 14.007, symbol: "N", name: "Nitrogen" },
|
||||||
{ position: 39, mass: 88.906, symbol: 'Y', name: 'Yttrium' },
|
{ position: 39, mass: 88.906, symbol: "Y", name: "Yttrium" },
|
||||||
{ position: 56, mass: 137.33, symbol: 'Ba', name: 'Barium' },
|
{ position: 56, mass: 137.33, symbol: "Ba", name: "Barium" },
|
||||||
{ position: 58, mass: 140.12, symbol: 'Ce', name: 'Cerium' },
|
{ position: 58, mass: 140.12, symbol: "Ce", name: "Cerium" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const rows = elements.map((element) => (
|
const rows = elements.map((element) => (
|
||||||
<Table.Tr key={element.name}>
|
<Table.Tr key={element.name}>
|
||||||
<Table.Td>{element.position}</Table.Td>
|
<Table.Td>{element.position}</Table.Td>
|
||||||
<Table.Td>{element.name}</Table.Td>
|
<Table.Td>{element.name}</Table.Td>
|
||||||
<Table.Td>{element.symbol}</Table.Td>
|
<Table.Td>{element.symbol}</Table.Td>
|
||||||
<Table.Td>{element.mass}</Table.Td>
|
<Table.Td>{element.mass}</Table.Td>
|
||||||
</Table.Tr>
|
</Table.Tr>
|
||||||
));
|
));
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
radius="md"
|
radius="md"
|
||||||
p="lg"
|
p="lg"
|
||||||
withBorder
|
withBorder
|
||||||
style={{
|
style={{
|
||||||
background:
|
background:
|
||||||
"linear-gradient(145deg, rgba(25,25,25,0.95), rgba(45,45,45,0.85))",
|
"linear-gradient(145deg, rgba(25,25,25,0.95), rgba(45,45,45,0.85))",
|
||||||
borderColor: "rgba(100,100,100,0.2)",
|
borderColor: "rgba(100,100,100,0.2)",
|
||||||
boxShadow: "0 0 20px rgba(0,255,200,0.08)",
|
boxShadow: "0 0 20px rgba(0,255,200,0.08)",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Stack gap="md">
|
<Stack gap="md">
|
||||||
<Flex align="center" justify="space-between">
|
<Flex align="center" justify="space-between">
|
||||||
<Title order={4} c="gray.2">
|
<Title order={4} c="gray.2">
|
||||||
Histori Pengaduan
|
Histori Pengaduan
|
||||||
</Title>
|
</Title>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Divider my={0} />
|
<Divider my={0} />
|
||||||
<Table>
|
<Table>
|
||||||
<Table.Thead>
|
<Table.Thead>
|
||||||
<Table.Tr>
|
<Table.Tr>
|
||||||
<Table.Th>Tanggal</Table.Th>
|
<Table.Th>Tanggal</Table.Th>
|
||||||
<Table.Th>Deskripsi</Table.Th>
|
<Table.Th>Deskripsi</Table.Th>
|
||||||
<Table.Th>Status</Table.Th>
|
<Table.Th>Status</Table.Th>
|
||||||
<Table.Th>User</Table.Th>
|
<Table.Th>User</Table.Th>
|
||||||
</Table.Tr>
|
</Table.Tr>
|
||||||
</Table.Thead>
|
</Table.Thead>
|
||||||
<Table.Tbody>{rows}</Table.Tbody>
|
<Table.Tbody>{rows}</Table.Tbody>
|
||||||
</Table>
|
</Table>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Card>
|
</Card>
|
||||||
|
);
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function DetailUserPengaduan() {
|
function DetailUserPengaduan() {
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [value, setValue] = useState("");
|
const [value, setValue] = useState("");
|
||||||
const { data, mutate, isLoading } = useSwr("/", () =>
|
const { data, mutate, isLoading } = useSwr("/", () =>
|
||||||
apiFetch.api.pengaduan.list.get({
|
apiFetch.api.pengaduan.list.get({
|
||||||
query: {
|
query: {
|
||||||
status,
|
status,
|
||||||
search: value,
|
search: value,
|
||||||
take: "",
|
take: "",
|
||||||
page: "",
|
page: "",
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
useShallowEffect(() => {
|
useShallowEffect(() => {
|
||||||
mutate();
|
mutate();
|
||||||
}, [status, value]);
|
}, [status, value]);
|
||||||
|
|
||||||
const list = data?.data || [];
|
const list = data?.data || [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
radius="md"
|
radius="md"
|
||||||
p="lg"
|
p="lg"
|
||||||
withBorder
|
withBorder
|
||||||
style={{
|
style={{
|
||||||
background:
|
background:
|
||||||
"linear-gradient(145deg, rgba(25,25,25,0.95), rgba(45,45,45,0.85))",
|
"linear-gradient(145deg, rgba(25,25,25,0.95), rgba(45,45,45,0.85))",
|
||||||
borderColor: "rgba(100,100,100,0.2)",
|
borderColor: "rgba(100,100,100,0.2)",
|
||||||
boxShadow: "0 0 20px rgba(0,255,200,0.08)",
|
boxShadow: "0 0 20px rgba(0,255,200,0.08)",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Stack gap="md">
|
<Stack gap="md">
|
||||||
<Flex align="center" justify="space-between">
|
<Flex align="center" justify="space-between">
|
||||||
<Flex direction={"column"}>
|
<Flex direction={"column"}>
|
||||||
<Title order={4} c="gray.2">
|
<Title order={4} c="gray.2">
|
||||||
Warga
|
Warga
|
||||||
</Title>
|
</Title>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Divider my={0} />
|
<Divider my={0} />
|
||||||
<Stack gap="md">
|
<Stack gap="md">
|
||||||
<Group justify="space-between" >
|
<Group justify="space-between">
|
||||||
<Group gap="xs">
|
<Group gap="xs">
|
||||||
<IconUser size={20} />
|
<IconUser size={20} />
|
||||||
<Text size="md">
|
<Text size="md">Nama</Text>
|
||||||
Nama
|
</Group>
|
||||||
</Text>
|
<Text size="md" c={"white"}>
|
||||||
</Group>
|
Amalia Dwi Yustiani
|
||||||
<Text size="md" c={"white"}>Amalia Dwi Yustiani</Text>
|
</Text>
|
||||||
</Group>
|
</Group>
|
||||||
<Group justify="space-between" >
|
<Group justify="space-between">
|
||||||
<Group gap="xs">
|
<Group gap="xs">
|
||||||
<IconMapPin size={20} />
|
<IconMapPin size={20} />
|
||||||
<Text size="md">
|
<Text size="md">Telepon</Text>
|
||||||
Telepon
|
</Group>
|
||||||
</Text>
|
<Text size="md" c="white">
|
||||||
</Group>
|
08123456789
|
||||||
<Text size="md" c="white">08123456789</Text>
|
</Text>
|
||||||
</Group>
|
</Group>
|
||||||
<Group justify="space-between" >
|
<Group justify="space-between">
|
||||||
<Group gap="xs">
|
<Group gap="xs">
|
||||||
<IconMessageReport size={20} />
|
<IconMessageReport size={20} />
|
||||||
<Text size="md">
|
<Text size="md">Jumlah Pengaduan</Text>
|
||||||
Jumlah Pengaduan
|
</Group>
|
||||||
</Text>
|
<Text size="md" c="white">
|
||||||
</Group>
|
10
|
||||||
<Text size="md" c="white">10</Text>
|
</Text>
|
||||||
</Group>
|
</Group>
|
||||||
<Group justify="space-between" >
|
<Group justify="space-between">
|
||||||
<Group gap="xs">
|
<Group gap="xs">
|
||||||
<IconFileCertificate size={20} />
|
<IconFileCertificate size={20} />
|
||||||
<Text size="md">
|
<Text size="md">Jumlah Pelayanan Surat</Text>
|
||||||
Jumlah Pelayanan Surat
|
</Group>
|
||||||
</Text>
|
<Text size="md" c="white">
|
||||||
</Group>
|
10
|
||||||
<Text size="md" c="white">10</Text>
|
</Text>
|
||||||
</Group>
|
</Group>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -198,7 +198,9 @@ function ListPengaduan({ status }: { status: StatusKey }) {
|
|||||||
borderColor: "rgba(100,100,100,0.2)",
|
borderColor: "rgba(100,100,100,0.2)",
|
||||||
boxShadow: "0 0 20px rgba(0,255,200,0.08)",
|
boxShadow: "0 0 20px rgba(0,255,200,0.08)",
|
||||||
}}
|
}}
|
||||||
onClick={() => navigate(`/scr/dashboard/pengaduan/detail?id=${v.id}`)}
|
onClick={() =>
|
||||||
|
navigate(`/scr/dashboard/pengaduan/detail?id=${v.id}`)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Stack gap="md">
|
<Stack gap="md">
|
||||||
<Flex align="center" justify="space-between">
|
<Flex align="center" justify="space-between">
|
||||||
|
|||||||
Reference in New Issue
Block a user