upd: dashboard admin
Deskripsi: - tampilan profile;2A - tampilan list category pengaduan - tampilan list category pelayanan surat - tampilan list configurasi desa No Issues
This commit is contained in:
@@ -25,6 +25,7 @@ import ListPage from "./pages/scr/dashboard/pengaduan/list_page";
|
||||
import DetailPage from "./pages/scr/dashboard/pengaduan/detail_page";
|
||||
import ApikeyPage from "./pages/scr/dashboard/apikey/apikey_page";
|
||||
import DashboardLayout from "./pages/scr/dashboard/dashboard_layout";
|
||||
import DetailSettingPage from "./pages/scr/dashboard/setting/detail_setting_page";
|
||||
import ScrLayout from "./pages/scr/scr_layout";
|
||||
import DirPage from "./pages/dir/dir_page";
|
||||
import NotFound from "./pages/NotFound";
|
||||
@@ -126,6 +127,10 @@ export default function AppRoutes() {
|
||||
path="/scr/dashboard/apikey/apikey"
|
||||
element={<ApikeyPage />}
|
||||
/>
|
||||
<Route
|
||||
path="/scr/dashboard/setting/detail-setting"
|
||||
element={<DetailSettingPage />}
|
||||
/>
|
||||
</Route>
|
||||
</Route>
|
||||
<Route path="/dir/dir" element={<DirPage />} />
|
||||
|
||||
@@ -26,6 +26,7 @@ const clientRoutes = {
|
||||
"/scr/dashboard/pengaduan/list": "/scr/dashboard/pengaduan/list",
|
||||
"/scr/dashboard/pengaduan/detail": "/scr/dashboard/pengaduan/detail",
|
||||
"/scr/dashboard/apikey/apikey": "/scr/dashboard/apikey/apikey",
|
||||
"/scr/dashboard/setting/detail-setting": "/scr/dashboard/setting/detail-setting",
|
||||
"/dir/dir": "/dir/dir",
|
||||
"/*": "/*"
|
||||
} as const;
|
||||
|
||||
@@ -242,7 +242,7 @@ function NavigationDashboard() {
|
||||
description: "Manage warga",
|
||||
},
|
||||
{
|
||||
path: "/scr/dashboard/setting",
|
||||
path: "/scr/dashboard/setting/detail-setting",
|
||||
icon: <IconSettings size={20} />,
|
||||
label: "Setting",
|
||||
description:
|
||||
|
||||
150
src/pages/scr/dashboard/setting/detail_setting_page.tsx
Normal file
150
src/pages/scr/dashboard/setting/detail_setting_page.tsx
Normal file
@@ -0,0 +1,150 @@
|
||||
import { Button, Card, Container, Divider, Flex, Grid, Group, Input, NavLink, Stack, Table, Title } from "@mantine/core";
|
||||
import { IconCircleOff, IconGauge, IconHome2 } from "@tabler/icons-react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
|
||||
export default function DetailSettingPage() {
|
||||
const { search } = useLocation();
|
||||
const query = new URLSearchParams(search);
|
||||
const type = query.get("type");
|
||||
|
||||
return (
|
||||
<Container size="xl" py="xl" w={"100%"}>
|
||||
<Grid>
|
||||
<Grid.Col span={3}>
|
||||
<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)",
|
||||
}}
|
||||
>
|
||||
<NavLink
|
||||
href={`?type=profile`}
|
||||
label="Profile"
|
||||
leftSection={<IconHome2 size={16} stroke={1.5} />}
|
||||
active={type === "profile" || !type}
|
||||
/>
|
||||
<NavLink
|
||||
href={`?type=cat-pengaduan`}
|
||||
label="Kategori Pengaduan"
|
||||
leftSection={<IconGauge size={16} stroke={1.5} />}
|
||||
active={type === "cat-pengaduan"}
|
||||
/>
|
||||
<NavLink
|
||||
href={`?type=cat-pelayanan`}
|
||||
label="Kategori Pelayanan Surat"
|
||||
leftSection={<IconCircleOff size={16} stroke={1.5} />}
|
||||
active={type === "cat-pelayanan"}
|
||||
/>
|
||||
<NavLink
|
||||
href={`?type=desa`}
|
||||
label="Desa"
|
||||
leftSection={<IconCircleOff size={16} stroke={1.5} />}
|
||||
active={type === "desa"}
|
||||
/>
|
||||
</Card>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={9}>
|
||||
<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)",
|
||||
}}
|
||||
>
|
||||
{type === "cat-pengaduan"
|
||||
? <KategoriPengaduanPage />
|
||||
: type === "cat-pelayanan"
|
||||
? <KategoriPengaduanPage />
|
||||
: type === "desa"
|
||||
? <KategoriPengaduanPage />
|
||||
: <ProfilePage />}
|
||||
</Card>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
function ProfilePage() {
|
||||
return (
|
||||
<Stack gap={"md"}>
|
||||
<Flex align="center" justify="space-between">
|
||||
<Title order={4} c="gray.2">
|
||||
Profile Pengguna
|
||||
</Title>
|
||||
<Button variant="light">Edit</Button>
|
||||
</Flex>
|
||||
<Divider my={0} />
|
||||
<Stack gap={"md"}>
|
||||
<Group gap="xl" grow>
|
||||
<Input.Wrapper label="Nama" description="" error="">
|
||||
<Input value={"Amalia Dwi Yustiani"} readOnly />
|
||||
</Input.Wrapper>
|
||||
<Input.Wrapper label="Phone" description="" error="">
|
||||
<Input value={"08123456789"} readOnly />
|
||||
</Input.Wrapper>
|
||||
</Group>
|
||||
<Group gap="xl" grow>
|
||||
<Input.Wrapper label="Email" description="" error="">
|
||||
<Input value={"amaliadwiyustiani@gmail.com"} readOnly />
|
||||
</Input.Wrapper>
|
||||
<Input.Wrapper label="Role" description="" error="">
|
||||
<Input value={"Admin"} readOnly />
|
||||
</Input.Wrapper>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
|
||||
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,191 +1,182 @@
|
||||
import apiFetch from "@/lib/apiFetch";
|
||||
import {
|
||||
Avatar,
|
||||
Box,
|
||||
Card,
|
||||
Container,
|
||||
Divider,
|
||||
Flex,
|
||||
Grid,
|
||||
Group,
|
||||
Stack,
|
||||
Table,
|
||||
Text,
|
||||
Title
|
||||
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 { 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");
|
||||
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>
|
||||
);
|
||||
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 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>
|
||||
);
|
||||
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: "",
|
||||
},
|
||||
}),
|
||||
);
|
||||
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]);
|
||||
useShallowEffect(() => {
|
||||
mutate();
|
||||
}, [status, value]);
|
||||
|
||||
const list = data?.data || [];
|
||||
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",
|
||||
}}
|
||||
/>
|
||||
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>
|
||||
{/* 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>
|
||||
{/* 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">
|
||||
<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>
|
||||
<Group gap="xs">
|
||||
<IconMapPin size={18} />
|
||||
<Text size="sm">Greenway Ave, Los Angeles, CA, USA</Text>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Card>
|
||||
);
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user