update: dashboard
Deskripsi: - tampilan list warga - tampilan detail warga No Issues
This commit is contained in:
@@ -19,6 +19,8 @@ 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 DetailPelayananPage from "./pages/scr/dashboard/pelayanan-surat/detail_pelayanan_page";
|
||||||
|
import DetailWargaPage from "./pages/scr/dashboard/warga/detail_warga_page";
|
||||||
|
import ListWargaPage from "./pages/scr/dashboard/warga/list_warga_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";
|
||||||
@@ -104,6 +106,14 @@ export default function AppRoutes() {
|
|||||||
path="/scr/dashboard/pelayanan-surat/detail-pelayanan"
|
path="/scr/dashboard/pelayanan-surat/detail-pelayanan"
|
||||||
element={<DetailPelayananPage />}
|
element={<DetailPelayananPage />}
|
||||||
/>
|
/>
|
||||||
|
<Route
|
||||||
|
path="/scr/dashboard/warga/detail-warga"
|
||||||
|
element={<DetailWargaPage />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/scr/dashboard/warga/list-warga"
|
||||||
|
element={<ListWargaPage />}
|
||||||
|
/>
|
||||||
<Route
|
<Route
|
||||||
path="/scr/dashboard/pengaduan/list"
|
path="/scr/dashboard/pengaduan/list"
|
||||||
element={<ListPage />}
|
element={<ListPage />}
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ const clientRoutes = {
|
|||||||
"/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/pelayanan-surat/detail-pelayanan": "/scr/dashboard/pelayanan-surat/detail-pelayanan",
|
||||||
|
"/scr/dashboard/warga/detail-warga": "/scr/dashboard/warga/detail-warga",
|
||||||
|
"/scr/dashboard/warga/list-warga": "/scr/dashboard/warga/list-warga",
|
||||||
"/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",
|
||||||
|
|||||||
@@ -236,10 +236,10 @@ function NavigationDashboard() {
|
|||||||
description: "Manage pelayanan surat",
|
description: "Manage pelayanan surat",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/scr/dashboard/user",
|
path: "/scr/dashboard/warga/list-warga",
|
||||||
icon: <IconUsersGroup size={20} />,
|
icon: <IconUsersGroup size={20} />,
|
||||||
label: "User",
|
label: "Warga",
|
||||||
description: "Manage user",
|
description: "Manage warga",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/scr/dashboard/setting",
|
path: "/scr/dashboard/setting",
|
||||||
|
|||||||
@@ -195,7 +195,9 @@ function ListPelayananSurat({ status }: { status: StatusKey }) {
|
|||||||
boxShadow: "0 0 20px rgba(0,255,200,0.08)",
|
boxShadow: "0 0 20px rgba(0,255,200,0.08)",
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigate(`/scr/dashboard/pelayanan-surat/detail-pelayanan?id=${v.id}`);
|
navigate(
|
||||||
|
`/scr/dashboard/pelayanan-surat/detail-pelayanan?id=${v.id}`,
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Stack gap="md">
|
<Stack gap="md">
|
||||||
|
|||||||
191
src/pages/scr/dashboard/warga/detail_warga_page.tsx
Normal file
191
src/pages/scr/dashboard/warga/detail_warga_page.tsx
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
import apiFetch from "@/lib/apiFetch";
|
||||||
|
import {
|
||||||
|
Avatar,
|
||||||
|
Box,
|
||||||
|
Card,
|
||||||
|
Container,
|
||||||
|
Divider,
|
||||||
|
Flex,
|
||||||
|
Grid,
|
||||||
|
Group,
|
||||||
|
Stack,
|
||||||
|
Table,
|
||||||
|
Text,
|
||||||
|
Title
|
||||||
|
} from "@mantine/core";
|
||||||
|
import { useShallowEffect } from "@mantine/hooks";
|
||||||
|
import {
|
||||||
|
IconMail,
|
||||||
|
IconMapPin,
|
||||||
|
IconPhone
|
||||||
|
} from "@tabler/icons-react";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { useLocation } from "react-router-dom";
|
||||||
|
import useSwr from "swr";
|
||||||
|
|
||||||
|
export default function DetailWargaPage() {
|
||||||
|
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={4}>
|
||||||
|
<DetailWarga />
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={8}>
|
||||||
|
<Stack gap={"xl"}>
|
||||||
|
<DetailDataHistori />
|
||||||
|
<DetailDataHistori />
|
||||||
|
</Stack>
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 DetailWarga() {
|
||||||
|
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)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#f7d86c",
|
||||||
|
height: 100,
|
||||||
|
borderRadius: "12px",
|
||||||
|
position: "relative",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Group>
|
||||||
|
{/* Profile image */}
|
||||||
|
<Avatar
|
||||||
|
src="https://i.pravatar.cc/150?img=32"
|
||||||
|
radius={100}
|
||||||
|
size={90}
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
top: 80,
|
||||||
|
left: 30,
|
||||||
|
border: "4px solid white",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Main content */}
|
||||||
|
<Stack ml={115} gap={4}>
|
||||||
|
<Text fw={700} fz="lg">
|
||||||
|
Lizbeth Moore
|
||||||
|
</Text>
|
||||||
|
<Text fz="sm" c="dimmed">
|
||||||
|
Social Media Strategies
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
</Group>
|
||||||
|
|
||||||
|
{/* Contact info */}
|
||||||
|
<Card
|
||||||
|
radius="md"
|
||||||
|
mt="md"
|
||||||
|
p="md"
|
||||||
|
withBorder={false}
|
||||||
|
>
|
||||||
|
<Stack gap="xs">
|
||||||
|
<Group gap="xs">
|
||||||
|
<IconMail size={18} />
|
||||||
|
<Text size="sm">lizbeth.moore@email.com</Text>
|
||||||
|
</Group>
|
||||||
|
|
||||||
|
<Group gap="xs">
|
||||||
|
<IconPhone size={18} />
|
||||||
|
<Text size="sm">+1 555-7788</Text>
|
||||||
|
</Group>
|
||||||
|
|
||||||
|
<Group gap="xs">
|
||||||
|
<IconMapPin size={18} />
|
||||||
|
<Text size="sm">Greenway Ave, Los Angeles, CA, USA</Text>
|
||||||
|
</Group>
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
97
src/pages/scr/dashboard/warga/list_warga_page.tsx
Normal file
97
src/pages/scr/dashboard/warga/list_warga_page.tsx
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
CloseButton,
|
||||||
|
Container,
|
||||||
|
Divider,
|
||||||
|
Flex,
|
||||||
|
Input,
|
||||||
|
Stack,
|
||||||
|
Table,
|
||||||
|
Title,
|
||||||
|
} from "@mantine/core";
|
||||||
|
import { IconSearch } from "@tabler/icons-react";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
|
export default function ListWargaPage() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [value, setValue] = useState("");
|
||||||
|
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.Td>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
onClick={() => {
|
||||||
|
navigate(
|
||||||
|
`/scr/dashboard/warga/detail-warga?id=${element.position}`,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Detail
|
||||||
|
</Button>
|
||||||
|
</Table.Td>
|
||||||
|
</Table.Tr>
|
||||||
|
));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container size="xl" py="xl" w={"100%"}>
|
||||||
|
<Card
|
||||||
|
radius="lg"
|
||||||
|
p="xl"
|
||||||
|
withBorder
|
||||||
|
style={{
|
||||||
|
background:
|
||||||
|
"linear-gradient(145deg, rgba(25,25,25,0.95), rgba(45,45,45,0.85))",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Stack gap="md">
|
||||||
|
<Flex align="center" justify="space-between">
|
||||||
|
<Title order={3} c="gray.2">
|
||||||
|
List Data Warga
|
||||||
|
</Title>
|
||||||
|
<Input
|
||||||
|
value={value}
|
||||||
|
placeholder="Cari warga..."
|
||||||
|
onChange={(event) => setValue(event.currentTarget.value)}
|
||||||
|
leftSection={<IconSearch size={16} />}
|
||||||
|
rightSectionPointerEvents="all"
|
||||||
|
rightSection={
|
||||||
|
<CloseButton
|
||||||
|
aria-label="Clear input"
|
||||||
|
onClick={() => setValue("")}
|
||||||
|
style={{ display: value ? undefined : "none" }}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</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.Th>Aksi</Table.Th>
|
||||||
|
</Table.Tr>
|
||||||
|
</Table.Thead>
|
||||||
|
<Table.Tbody>{rows}</Table.Tbody>
|
||||||
|
</Table>
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user