upd: form surat

Deskripsi:
- api detail categori list
- form awal buat surat

No Issues
This commit is contained in:
2025-12-16 17:38:13 +08:00
parent a13e51a724
commit 7c6e4ac9eb
38 changed files with 4236 additions and 2941 deletions

View File

@@ -1,133 +1,210 @@
import apiFetch from "@/lib/apiFetch";
import { Badge, Button, Card, Flex, Group, Stack, Text, Title, Tooltip } from "@mantine/core";
import {
Badge,
Button,
Card,
Flex,
Group,
Stack,
Text,
Title,
Tooltip,
} from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import { useNavigate } from "react-router-dom";
import useSWR from "swr";
export default function DashboardLastData() {
const navigate = useNavigate();
const { data, mutate, isLoading } = useSWR("last-update", async () => {
const res = await apiFetch.api.dashboard["last-update"].get();
return res.data
});
const navigate = useNavigate();
const { data, mutate, isLoading } = useSWR("last-update", async () => {
const res = await apiFetch.api.dashboard["last-update"].get();
return res.data;
});
useShallowEffect(() => {
mutate();
}, []);
useShallowEffect(() => {
mutate();
}, []);
return (
<Flex justify="flex-start" gap="md">
<Card
radius="lg"
p="xl"
withBorder
w={"50%"}
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 25px rgba(0,255,200,0.08)",
}}
>
<Stack gap="sm">
<Flex
align="center"
pb={"sm"}
justify="space-between"
style={{ borderBottom: "1px solid rgba(255,255,255,0.1)" }}
>
<Title order={4} c="gray.0">
Last update pengaduan
</Title>
<Button
variant="subtle"
size="xs"
radius="md"
onClick={() => navigate(`/scr/dashboard/pengaduan/list`)}
>
View All
</Button>
</Flex>
<Stack gap="sm" mt="md" align="stretch" justify="center">
{data &&
Array.isArray(data.pengaduan) &&
data.pengaduan.length > 0 ? (
data.pengaduan.map((item: any, index: number) => (
<PengaduanSection
key={index}
id={item.id}
nomer={item.noPengaduan}
judul={item.title}
status={item.status}
updated={item.updatedAt}
kategori="pengaduan"
/>
))
) : (
<Text c="dimmed" ta={"center"}>
Tidak ada data
</Text>
)}
</Stack>
</Stack>
</Card>
return (
<Flex justify="flex-start" gap="md">
<Card
radius="lg"
p="xl"
withBorder
w={"50%"}
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 25px rgba(0,255,200,0.08)",
}}
>
<Stack gap="sm">
<Flex align="center" pb={"sm"} justify="space-between" style={{ borderBottom: "1px solid rgba(255,255,255,0.1)" }}>
<Title order={4} c="gray.0">
Last update pengaduan
</Title>
<Button variant="subtle" size="xs" radius="md" onClick={() => navigate(`/scr/dashboard/pengaduan/list`)}>View All</Button>
</Flex>
<Stack gap="sm" mt="md" align="stretch" justify="center">
{
data && Array.isArray(data.pengaduan) && data.pengaduan.length > 0 ? data.pengaduan.map((item: any, index: number) => (
<PengaduanSection
key={index}
id={item.id}
nomer={item.noPengaduan}
judul={item.title}
status={item.status}
updated={item.updatedAt}
kategori="pengaduan"
/>
)) : <Text c="dimmed" ta={"center"} >Tidak ada data</Text>
}
</Stack>
</Stack>
</Card>
<Card
radius="lg"
p="xl"
withBorder
w={"50%"}
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 25px rgba(0,255,200,0.08)",
}}
>
<Stack gap="sm">
<Flex align="center" pb={"sm"} justify="space-between" style={{ borderBottom: "1px solid rgba(255,255,255,0.1)" }}>
<Title order={4} c="gray.0">
Last update pelayanan surat
</Title>
<Button variant="subtle" size="xs" radius="md" onClick={() => navigate(`/scr/dashboard/pelayanan-surat/list-pelayanan`)}>View All</Button>
</Flex>
<Stack gap="sm" mt="md" align="stretch" justify="center">
{
data && Array.isArray(data.pelayanan) && data.pelayanan.length > 0 ? data.pelayanan.map((item: any, index: number) => (
<PengaduanSection
key={index}
id={item.id}
nomer={item.noPengajuan}
judul={item.title}
status={item.status}
updated={item.updatedAt}
kategori="pelayanan"
/>
)) : <Text c="dimmed" ta={"center"} >Tidak ada data</Text>
}
</Stack>
</Stack>
</Card>
</Flex>
);
<Card
radius="lg"
p="xl"
withBorder
w={"50%"}
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 25px rgba(0,255,200,0.08)",
}}
>
<Stack gap="sm">
<Flex
align="center"
pb={"sm"}
justify="space-between"
style={{ borderBottom: "1px solid rgba(255,255,255,0.1)" }}
>
<Title order={4} c="gray.0">
Last update pelayanan surat
</Title>
<Button
variant="subtle"
size="xs"
radius="md"
onClick={() =>
navigate(`/scr/dashboard/pelayanan-surat/list-pelayanan`)
}
>
View All
</Button>
</Flex>
<Stack gap="sm" mt="md" align="stretch" justify="center">
{data &&
Array.isArray(data.pelayanan) &&
data.pelayanan.length > 0 ? (
data.pelayanan.map((item: any, index: number) => (
<PengaduanSection
key={index}
id={item.id}
nomer={item.noPengajuan}
judul={item.title}
status={item.status}
updated={item.updatedAt}
kategori="pelayanan"
/>
))
) : (
<Text c="dimmed" ta={"center"}>
Tidak ada data
</Text>
)}
</Stack>
</Stack>
</Card>
</Flex>
);
}
function PengaduanSection({ id, nomer, judul, status, updated, kategori }: { id: string, nomer: string, judul: string, status: string, updated: string, kategori: 'pengaduan' | 'pelayanan' }) {
const navigate = useNavigate();
function PengaduanSection({
id,
nomer,
judul,
status,
updated,
kategori,
}: {
id: string;
nomer: string;
judul: string;
status: string;
updated: string;
kategori: "pengaduan" | "pelayanan";
}) {
const navigate = useNavigate();
return (
<Stack
gap="xs"
onClick={() => navigate(kategori == "pelayanan" ? `/scr/dashboard/pelayanan-surat/detail-pelayanan?id=${id}` : `/scr/dashboard/pengaduan/detail?id=${id}`)}
return (
<Stack
gap="xs"
onClick={() =>
navigate(
kategori == "pelayanan"
? `/scr/dashboard/pelayanan-surat/detail-pelayanan?id=${id}`
: `/scr/dashboard/pengaduan/detail?id=${id}`,
)
}
>
<Flex
align="center"
pb={"sm"}
justify="space-between"
gap="md"
style={{ borderBottom: "1px solid rgba(255,255,255,0.1)" }}
>
<Flex align="center" pb={"sm"} justify="space-between" gap="md" style={{ borderBottom: "1px solid rgba(255,255,255,0.1)" }}>
<Flex direction={"column"}>
<Text size="md" c="gray.2" lineClamp={1}>
{judul}
</Text>
<Group>
<Text size="sm" c="dimmed">
#{nomer} {updated}
</Text>
</Group>
</Flex>
<Tooltip label={status}>
<Badge size="xs" circle color={
status === "diterima"
? "green"
: status === "ditolak"
? "red"
: status === "selesai"
? "blue"
: status === "dikerjakan"
? "gray"
: "yellow"
} />
</Tooltip>
</Flex>
</Stack>
)
}
<Flex direction={"column"}>
<Text size="md" c="gray.2" lineClamp={1}>
{judul}
</Text>
<Group>
<Text size="sm" c="dimmed">
#{nomer} {updated}
</Text>
</Group>
</Flex>
<Tooltip label={status}>
<Badge
size="xs"
circle
color={
status === "diterima"
? "green"
: status === "ditolak"
? "red"
: status === "selesai"
? "blue"
: status === "dikerjakan"
? "gray"
: "yellow"
}
/>
</Tooltip>
</Flex>
</Stack>
);
}