Refactor ui keuangan

This commit is contained in:
2026-03-24 23:17:23 +08:00
parent d714c09efc
commit 8159216a2c
5 changed files with 561 additions and 264 deletions

View File

@@ -1,73 +1,70 @@
import { BarChart } from "@mantine/charts";
import { import {
Badge, Badge,
Box, Box,
Button,
Card, Card,
Grid, Grid,
GridCol,
Group, Group,
Progress,
Stack, Stack,
Text, Text,
ThemeIcon,
Title, Title,
useMantineColorScheme, useMantineColorScheme,
} from "@mantine/core"; } from "@mantine/core";
import { import {
IconCurrency, Coins,
IconTrendingDown, CheckCircle,
IconTrendingUp, TrendingUp,
} from "@tabler/icons-react"; TrendingDown,
import React from "react"; PieChart as PieChartIcon,
Receipt,
} from "lucide-react";
import {
Bar,
BarChart,
CartesianGrid,
Line,
LineChart,
ResponsiveContainer,
Tooltip,
XAxis,
YAxis,
} from "recharts";
// Sample Data // KPI Data
const kpiData = [ const kpiData = [
{ {
id: 1, id: 1,
title: "Total APBDes", title: "Total APBDes",
value: "Rp 5.2M", value: "Rp 5.2M",
sub: "Tahun 2025", subtitle: "Tahun 2025",
icon: <IconCurrency className="h-6 w-6 text-muted-foreground" />, icon: Coins,
}, },
{ {
id: 2, id: 2,
title: "Realisasi", title: "Realisasi",
value: "68%", value: "68%",
sub: "Rp 3.5M dari 5.2M", subtitle: "Rp 3.5M dari 5.2M",
icon: ( icon: CheckCircle,
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="h-6 w-6 text-muted-foreground"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M9 12.75 11.25 15 15 9.75M21 12c0 1.268-.63 2.473-1.688 3.342-.48.485-.926.97-1.378 1.44c-1.472 1.58-2.306 2.787-2.91 3.514-.15.18-.207.33-.207.33A.75.75 0 0 1 15 21h-3c-1.104 0-2.08-.542-2.657-1.455-.139-.201-.264-.406-.38-.614l-.014-.025C8.85 18.067 8.156 17.2 7.5 16.325.728 12.56.728 7.44 7.5 3.675c3.04-.482 5.584.47 7.042 1.956.674.672 1.228 1.462 1.696 2.307.426.786.793 1.582 1.113 2.392h.001Z"
/>
</svg>
),
}, },
{ {
id: 3, id: 3,
title: "Pemasukan", title: "Pemasukan",
value: "Rp 580jt", value: "Rp 580jt",
sub: "Bulan ini", subtitle: "Bulan ini",
delta: "+8%", trend: "+8%",
deltaType: "positive", icon: TrendingUp,
icon: <IconTrendingUp className="h-6 w-6 text-muted-foreground" />,
}, },
{ {
id: 4, id: 4,
title: "Pengeluaran", title: "Pengeluaran",
value: "Rp 520jt", value: "Rp 520jt",
sub: "Bulan ini", subtitle: "Bulan ini",
icon: <IconTrendingDown className="h-6 w-6 text-muted-foreground" />, icon: TrendingDown,
}, },
]; ];
// Income & Expense Data
const incomeExpenseData = [ const incomeExpenseData = [
{ month: "Apr", income: 450, expense: 380 }, { month: "Apr", income: 450, expense: 380 },
{ month: "Mei", income: 520, expense: 420 }, { month: "Mei", income: 520, expense: 420 },
@@ -78,6 +75,7 @@ const incomeExpenseData = [
{ month: "Okt", income: 580, expense: 520 }, { month: "Okt", income: 580, expense: 520 },
]; ];
// Sector Allocation Data
const allocationData = [ const allocationData = [
{ sector: "Pembangunan", amount: 1200 }, { sector: "Pembangunan", amount: 1200 },
{ sector: "Kesehatan", amount: 800 }, { sector: "Kesehatan", amount: 800 },
@@ -87,13 +85,7 @@ const allocationData = [
{ sector: "Teknologi", amount: 300 }, { sector: "Teknologi", amount: 300 },
]; ];
const assistanceFundData = [ // APBDes Report Data
{ source: "Dana Desa (DD)", amount: 1800, status: "cair" },
{ source: "Alokasi Dana Desa (ADD)", amount: 950, status: "cair" },
{ source: "Bagi Hasil Pajak", amount: 450, status: "cair" },
{ source: "Hibah Provinsi", amount: 300, status: "proses" },
];
const apbdReport = { const apbdReport = {
income: [ income: [
{ category: "Dana Desa", amount: 1800 }, { category: "Dana Desa", amount: 1800 },
@@ -113,244 +105,423 @@ const apbdReport = {
totalExpenses: 2155, totalExpenses: 2155,
}; };
// Aid & Grants Data
const assistanceFundData = [
{ source: "Dana Desa (DD)", amount: 1800, status: "cair" },
{ source: "Alokasi Dana Desa (ADD)", amount: 950, status: "cair" },
{ source: "Bagi Hasil Pajak", amount: 450, status: "cair" },
{ source: "Hibah Provinsi", amount: 300, status: "proses" },
];
const KeuanganAnggaran = () => { const KeuanganAnggaran = () => {
const { colorScheme } = useMantineColorScheme(); const { colorScheme } = useMantineColorScheme();
const dark = colorScheme === "dark"; const dark = colorScheme === "dark";
return (
<Box>
<Stack gap="xl">
{/* KPI Cards */}
<Grid gutter="lg">
{kpiData.map((kpi) => (
<Grid.Col key={kpi.id} span={{ base: 12, md: 6, lg: 3 }}>
<Card
p="md"
radius="md"
withBorder
bg={dark ? "#141D34" : "white"}
style={{ borderColor: dark ? "#141D34" : "white" }}
h="100%"
>
<Group justify="space-between" align="flex-start" mb="xs">
<Text size="sm" fw={500} c="dimmed">
{kpi.title}
</Text>
{React.cloneElement(kpi.icon, {
className: "h-6 w-6",
color: "var(--mantine-color-dimmed)",
})}
</Group>
<Title order={3} fw={700} mt="xs">
{kpi.value}
</Title>
{kpi.delta && (
<Text
size="xs"
c={
kpi.deltaType === "positive"
? "green"
: kpi.deltaType === "negative"
? "red"
: "dimmed"
}
mt={4}
>
{kpi.delta}
</Text>
)}
{kpi.sub && (
<Text size="xs" c="dimmed" mt="auto">
{kpi.sub}
</Text>
)}
</Card>
</Grid.Col>
))}
</Grid>
{/* Charts Section */} return (
<Grid gutter="lg"> <Stack gap="lg">
{/* Grafik Pemasukan vs Pengeluaran */} {/* TOP SECTION - 4 STAT CARDS */}
<Grid.Col span={{ base: 12, lg: 6 }}> <Grid gutter="md">
{kpiData.map((item) => (
<Grid.Col key={item.id} span={{ base: 12, sm: 6, lg: 3 }}>
<Card <Card
p="md" p="md"
radius="md" radius="xl"
withBorder withBorder
bg={dark ? "#141D34" : "white"} bg={dark ? "#1E293B" : "white"}
style={{ borderColor: dark ? "#141D34" : "white" }} style={{
borderColor: dark ? "#334155" : "white",
boxShadow: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
transition: "transform 0.15s ease, box-shadow 0.15s ease",
}}
h="100%"
> >
<Title order={3} fw={500} mb="md"> <Group justify="space-between" align="flex-start" w="100%">
Pemasukan vs Pengeluaran <Stack gap={2}>
</Title> <Text size="sm" c="dimmed">
<BarChart {item.title}
h={300} </Text>
data={incomeExpenseData} <Text size="xl" fw={700} c={dark ? "white" : "gray.9"}>
dataKey="month" {item.value}
series={[ </Text>
{ name: "income", color: "green", label: "Pemasukan" }, <Group gap={4} align="flex-start">
{ name: "expense", color: "red", label: "Pengeluaran" }, {item.trend && (
]} <TrendingUp size={14} color="#22C55E" />
withLegend )}
/> <Text
size="xs"
c={
item.trend
? "green"
: dark
? "gray.4"
: "gray.5"
}
>
{item.subtitle}
</Text>
</Group>
</Stack>
<ThemeIcon
color="#1E3A5F"
variant="filled"
size="lg"
radius="xl"
>
<item.icon style={{ width: "60%", height: "60%" }} />
</ThemeIcon>
</Group>
</Card> </Card>
</Grid.Col> </Grid.Col>
))}
</Grid>
{/* Alokasi Anggaran Per Sektor */} {/* MAIN CHART SECTION */}
<Grid.Col span={{ base: 12, lg: 6 }}> <Grid gutter="lg">
<Card {/* LEFT: PEMASUKAN DAN PENGELUARAN (70%) */}
p="md" <Grid.Col span={{ base: 12, lg: 8 }}>
radius="md" <Card
withBorder p="md"
bg={dark ? "#141D34" : "white"} radius="xl"
style={{ borderColor: dark ? "#141D34" : "white" }} withBorder
> bg={dark ? "#1E293B" : "white"}
<Title order={3} fw={500} mb="md"> style={{
borderColor: dark ? "#334155" : "white",
boxShadow: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
}}
h="100%"
>
<Group gap="xs" mb="md">
<ThemeIcon color="#1E3A5F" variant="filled" size="sm" radius="sm">
<PieChartIcon size={14} />
</ThemeIcon>
<Title order={4} c={dark ? "white" : "gray.9"}>
Pemasukan dan Pengeluaran
</Title>
</Group>
<ResponsiveContainer width="100%" height={300}>
<LineChart data={incomeExpenseData}>
<CartesianGrid
strokeDasharray="3 3"
vertical={false}
stroke={dark ? "#334155" : "#e5e7eb"}
/>
<XAxis
dataKey="month"
axisLine={false}
tickLine={false}
tick={{
fill: dark ? "#E2E8F0" : "#374151",
fontSize: 12,
}}
/>
<YAxis
axisLine={false}
tickLine={false}
tick={{
fill: dark ? "#E2E8F0" : "#374151",
fontSize: 12,
}}
tickFormatter={(value) => `Rp ${value}jt`}
/>
<Tooltip
contentStyle={{
backgroundColor: dark ? "#1E293B" : "white",
borderColor: dark ? "#334155" : "#e5e7eb",
borderRadius: "8px",
}}
labelStyle={{ color: dark ? "#E2E8F0" : "#374151" }}
formatter={(value: number | undefined) => [
`Rp ${value}jt`,
"",
]}
/>
<Line
type="monotone"
dataKey="income"
stroke="#22C55E"
strokeWidth={2}
dot={{ fill: "#22C55E", strokeWidth: 2, r: 4 }}
activeDot={{ r: 6 }}
name="Pemasukan"
/>
<Line
type="monotone"
dataKey="expense"
stroke="#EF4444"
strokeWidth={2}
dot={{ fill: "#EF4444", strokeWidth: 2, r: 4 }}
activeDot={{ r: 6 }}
name="Pengeluaran"
/>
</LineChart>
</ResponsiveContainer>
</Card>
</Grid.Col>
{/* RIGHT: ALOKASI ANGGARAN PER SEKTOR (30%) */}
<Grid.Col span={{ base: 12, lg: 4 }}>
<Card
p="md"
radius="xl"
withBorder
bg={dark ? "#1E293B" : "white"}
style={{
borderColor: dark ? "#334155" : "white",
boxShadow: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
}}
h="100%"
>
<Group gap="xs" mb="md">
<ThemeIcon color="#1E3A5F" variant="filled" size="sm" radius="sm">
<PieChartIcon size={14} />
</ThemeIcon>
<Title order={4} c={dark ? "white" : "gray.9"}>
Alokasi Anggaran Per Sektor Alokasi Anggaran Per Sektor
</Title> </Title>
<BarChart </Group>
h={300} <ResponsiveContainer width="100%" height={300}>
data={allocationData} <BarChart data={allocationData} layout="vertical">
dataKey="sector" <CartesianGrid
series={[ strokeDasharray="3 3"
{ name: "amount", color: "darmasaba-navy", label: "Jumlah" }, horizontal={false}
]} stroke={dark ? "#334155" : "#e5e7eb"}
withLegend />
orientation="horizontal" <XAxis
/> type="number"
</Card> axisLine={false}
</Grid.Col> tickLine={false}
</Grid> tick={{
fill: dark ? "#E2E8F0" : "#374151",
fontSize: 12,
}}
tickFormatter={(value) => `${value}`}
/>
<YAxis
type="category"
dataKey="sector"
axisLine={false}
tickLine={false}
tick={{
fill: dark ? "#E2E8F0" : "#374151",
fontSize: 11,
}}
width={100}
/>
<Tooltip
contentStyle={{
backgroundColor: dark ? "#1E293B" : "white",
borderColor: dark ? "#334155" : "#e5e7eb",
borderRadius: "8px",
}}
formatter={(value: number | undefined) => [`Rp ${value}jt`, "Jumlah"]}
/>
<Bar
dataKey="amount"
fill="#1E3A5F"
radius={[0, 8, 8, 0]}
maxBarSize={30}
/>
</BarChart>
</ResponsiveContainer>
</Card>
</Grid.Col>
</Grid>
<Grid gutter="lg"> {/* BOTTOM SECTION */}
{/* Dana Bantuan & Hibah */} <Grid gutter="lg">
<Grid.Col span={{ base: 12, lg: 6 }}> {/* LEFT: LAPORAN APBDES */}
<Card <Grid.Col span={{ base: 12, lg: 6 }}>
p="md" <Card
radius="md" p="md"
withBorder radius="xl"
bg={dark ? "#141D34" : "white"} withBorder
style={{ borderColor: dark ? "#141D34" : "white" }} bg={dark ? "#1E293B" : "white"}
> style={{
<Title order={3} fw={500} mb="md"> borderColor: dark ? "#334155" : "white",
Dana Bantuan & Hibah boxShadow: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
}}
h="100%"
>
<Group gap="xs" mb="md">
<ThemeIcon color="#1E3A5F" variant="filled" size="sm" radius="sm">
<Receipt size={14} />
</ThemeIcon>
<Title order={4} c={dark ? "white" : "gray.9"}>
Laporan APBDes
</Title> </Title>
<Stack gap="sm"> </Group>
{assistanceFundData.map((fund, index) => (
<Group <Grid gutter="md">
key={index} {/* Pendapatan */}
justify="space-between" <Grid.Col span={6}>
align="center" <Card
p="sm" p="sm"
style={{ radius="lg"
border: "1px solid var(--mantine-color-gray-3)", bg={dark ? "#064E3B" : "#DCFCE7"}
borderRadius: "var(--mantine-radius-sm)", >
}} <Title order={5} c="#22C55E" mb="sm">
> Pendapatan
</Title>
<Stack gap="xs">
{apbdReport.income.map((item, index) => (
<Group key={index} justify="space-between">
<Text size="sm" c={dark ? "gray.3" : "gray.7"}>
{item.category}
</Text>
<Text size="sm" fw={600} c="#22C55E">
Rp {item.amount.toLocaleString()}jt
</Text>
</Group>
))}
<Group
justify="space-between"
mt="sm"
pt="sm"
style={{
borderTop: `1px solid ${dark ? "#065F46" : "#86EFAC"}`,
}}
>
<Text fw={700} c="#22C55E">
Total:
</Text>
<Text fw={700} c="#22C55E">
Rp {apbdReport.totalIncome.toLocaleString()}jt
</Text>
</Group>
</Stack>
</Card>
</Grid.Col>
{/* Belanja */}
<Grid.Col span={6}>
<Card
p="sm"
radius="lg"
bg={dark ? "#7F1D1D" : "#FEE2E2"}
>
<Title order={5} c="#EF4444" mb="sm">
Belanja
</Title>
<Stack gap="xs">
{apbdReport.expenses.map((item, index) => (
<Group key={index} justify="space-between">
<Text size="sm" c={dark ? "gray.3" : "gray.7"}>
{item.category}
</Text>
<Text size="sm" fw={600} c="#EF4444">
Rp {item.amount.toLocaleString()}jt
</Text>
</Group>
))}
<Group
justify="space-between"
mt="sm"
pt="sm"
style={{
borderTop: `1px solid ${dark ? "#991B1B" : "#FCA5A5"}`,
}}
>
<Text fw={700} c="#EF4444">
Total:
</Text>
<Text fw={700} c="#EF4444">
Rp {apbdReport.totalExpenses.toLocaleString()}jt
</Text>
</Group>
</Stack>
</Card>
</Grid.Col>
</Grid>
{/* Saldo */}
<Group
justify="space-between"
mt="md"
pt="md"
style={{
borderTop: `1px solid ${dark ? "#334155" : "#e5e7eb"}`,
}}
>
<Text fw={700} c={dark ? "white" : "gray.9"}>
Saldo:
</Text>
<Text
fw={700}
size="lg"
c={
apbdReport.totalIncome > apbdReport.totalExpenses
? "#22C55E"
: "#EF4444"
}
>
Rp{" "}
{(
apbdReport.totalIncome - apbdReport.totalExpenses
).toLocaleString()}
jt
</Text>
</Group>
</Card>
</Grid.Col>
{/* RIGHT: DANA BANTUAN DAN HIBAH */}
<Grid.Col span={{ base: 12, lg: 6 }}>
<Card
p="md"
radius="xl"
withBorder
bg={dark ? "#1E293B" : "white"}
style={{
borderColor: dark ? "#334155" : "white",
boxShadow: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
}}
h="100%"
>
<Group gap="xs" mb="md">
<ThemeIcon color="#1E3A5F" variant="filled" size="sm" radius="sm">
<Coins size={14} />
</ThemeIcon>
<Title order={4} c={dark ? "white" : "gray.9"}>
Dana Bantuan dan Hibah
</Title>
</Group>
<Stack gap="sm">
{assistanceFundData.map((fund, index) => (
<Card
key={index}
p="sm"
radius="lg"
bg={dark ? "#334155" : "#F1F5F9"}
style={{
borderColor: "transparent",
transition: "background-color 0.15s ease",
}}
>
<Group justify="space-between" align="center">
<Box> <Box>
<Text size="sm" fw={500}> <Text size="sm" fw={600} c={dark ? "white" : "gray.9"}>
{fund.source} {fund.source}
</Text> </Text>
<Text size="sm" c="dimmed"> <Text size="xs" c="dimmed">
Rp {fund.amount.toLocaleString()}jt Rp {fund.amount.toLocaleString()}jt
</Text> </Text>
</Box> </Box>
<Badge <Badge
variant="light" variant="light"
color={fund.status === "cair" ? "green" : "yellow"} color={fund.status === "cair" ? "green" : "yellow"}
radius="sm"
fw={600}
> >
{fund.status} {fund.status === "cair" ? "Cair" : "Proses"}
</Badge> </Badge>
</Group> </Group>
))} </Card>
</Stack> ))}
</Card> </Stack>
</Grid.Col> </Card>
</Grid.Col>
{/* Laporan APBDes */} </Grid>
<Grid.Col span={{ base: 12, lg: 6 }}> </Stack>
<Card
p="md"
radius="md"
withBorder
bg={dark ? "#141D34" : "white"}
style={{ borderColor: dark ? "#141D34" : "white" }}
>
<Title order={3} fw={500} mb="md">
Laporan APBDes
</Title>
<Box mb="md">
<Title order={4} mb="sm">
Pendapatan
</Title>
<Stack gap="xs">
{apbdReport.income.map((item, index) => (
<Group key={index} justify="space-between">
<Text size="sm">{item.category}</Text>
<Text size="sm" c="green">
Rp {item.amount.toLocaleString()}jt
</Text>
</Group>
))}
<Group justify="space-between" mt="sm">
<Text fw={700}>Total Pendapatan:</Text>
<Text fw={700} c="green">
Rp {apbdReport.totalIncome.toLocaleString()}jt
</Text>
</Group>
</Stack>
</Box>
<Box>
<Title order={4} mb="sm">
Belanja
</Title>
<Stack gap="xs">
{apbdReport.expenses.map((item, index) => (
<Group key={index} justify="space-between">
<Text size="sm">{item.category}</Text>
<Text size="sm" c="red">
Rp {item.amount.toLocaleString()}jt
</Text>
</Group>
))}
<Group justify="space-between" mt="sm">
<Text fw={700}>Total Belanja:</Text>
<Text fw={700} c="red">
Rp {apbdReport.totalExpenses.toLocaleString()}jt
</Text>
</Group>
</Stack>
</Box>
<Box
mt="md"
pt="md"
style={{ borderTop: "1px solid var(--mantine-color-gray-3)" }}
>
<Group justify="space-between">
<Text fw={700}>Saldo:</Text>
<Text
fw={700}
c={
apbdReport.totalIncome > apbdReport.totalExpenses
? "green"
: "red"
}
>
Rp{" "}
{(
apbdReport.totalIncome - apbdReport.totalExpenses
).toLocaleString()}
jt
</Text>
</Group>
</Box>
</Card>
</Grid.Col>
</Grid>
</Stack>
</Box>
); );
}; };

View File

@@ -2,14 +2,14 @@ import { AppShell, Burger, Group, useMantineColorScheme } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks"; import { useDisclosure } from "@mantine/hooks";
import { createFileRoute } from "@tanstack/react-router"; import { createFileRoute } from "@tanstack/react-router";
import { Header } from "@/components/header"; import { Header } from "@/components/header";
import HelpPage from "@/components/help-page";
import { Sidebar } from "@/components/sidebar"; import { Sidebar } from "@/components/sidebar";
import HelpPage from "@/components/help-page";
export const Route = createFileRoute("/bantuan")({ export const Route = createFileRoute("/bantuan")({
component: BantuanPage, component: BantuanRoute,
}); });
function BantuanPage() { function BantuanRoute() {
const [opened, { toggle }] = useDisclosure(); const [opened, { toggle }] = useDisclosure();
const { colorScheme } = useMantineColorScheme(); const { colorScheme } = useMantineColorScheme();
const headerBgColor = colorScheme === "dark" ? "#11192D" : "#19355E"; const headerBgColor = colorScheme === "dark" ? "#11192D" : "#19355E";

View File

@@ -1,9 +1,51 @@
import { AppShell, Burger, Group, useMantineColorScheme } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { createFileRoute } from "@tanstack/react-router"; import { createFileRoute } from "@tanstack/react-router";
import { Header } from "@/components/header";
import { Sidebar } from "@/components/sidebar";
import BumdesPage from "@/components/bumdes-page";
export const Route = createFileRoute("/bumdes")({ export const Route = createFileRoute("/bumdes")({
component: RouteComponent, component: BumdesRoute,
}); });
function RouteComponent() { function BumdesRoute() {
return <div>Hello "/bumdes"!</div>; const [opened, { toggle }] = useDisclosure();
const { colorScheme } = useMantineColorScheme();
const headerBgColor = colorScheme === "dark" ? "#11192D" : "#19355E";
const navbarBgColor = colorScheme === "dark" ? "#11192D" : "white";
const mainBgColor = colorScheme === "dark" ? "#11192D" : "#edf3f8ff";
return (
<AppShell
header={{ height: 60 }}
navbar={{
width: 300,
breakpoint: "sm",
collapsed: { mobile: !opened },
}}
padding="md"
>
<AppShell.Header bg={headerBgColor}>
<Group h="100%" px="md">
<Burger opened={opened} onClick={toggle} hiddenFrom="sm" size="sm" />
<Header />
</Group>
</AppShell.Header>
<AppShell.Navbar
p="md"
bg={navbarBgColor}
style={{ display: "flex", flexDirection: "column" }}
>
<div style={{ flex: 1, overflowY: "auto" }}>
<Sidebar />
</div>
</AppShell.Navbar>
<AppShell.Main bg={mainBgColor}>
<BumdesPage />
</AppShell.Main>
</AppShell>
);
} }

View File

@@ -1,9 +1,51 @@
import { AppShell, Burger, Group, useMantineColorScheme } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { createFileRoute } from "@tanstack/react-router"; import { createFileRoute } from "@tanstack/react-router";
import { Header } from "@/components/header";
import { Sidebar } from "@/components/sidebar";
import KeamananPage from "@/components/keamanan-page";
export const Route = createFileRoute("/keamanan")({ export const Route = createFileRoute("/keamanan")({
component: RouteComponent, component: KeamananRoute,
}); });
function RouteComponent() { function KeamananRoute() {
return <div>Hello "/keamanan"!</div>; const [opened, { toggle }] = useDisclosure();
const { colorScheme } = useMantineColorScheme();
const headerBgColor = colorScheme === "dark" ? "#11192D" : "#19355E";
const navbarBgColor = colorScheme === "dark" ? "#11192D" : "white";
const mainBgColor = colorScheme === "dark" ? "#11192D" : "#edf3f8ff";
return (
<AppShell
header={{ height: 60 }}
navbar={{
width: 300,
breakpoint: "sm",
collapsed: { mobile: !opened },
}}
padding="md"
>
<AppShell.Header bg={headerBgColor}>
<Group h="100%" px="md">
<Burger opened={opened} onClick={toggle} hiddenFrom="sm" size="sm" />
<Header />
</Group>
</AppShell.Header>
<AppShell.Navbar
p="md"
bg={navbarBgColor}
style={{ display: "flex", flexDirection: "column" }}
>
<div style={{ flex: 1, overflowY: "auto" }}>
<Sidebar />
</div>
</AppShell.Navbar>
<AppShell.Main bg={mainBgColor}>
<KeamananPage />
</AppShell.Main>
</AppShell>
);
} }

View File

@@ -1,9 +1,51 @@
import { AppShell, Burger, Group, useMantineColorScheme } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { createFileRoute } from "@tanstack/react-router"; import { createFileRoute } from "@tanstack/react-router";
import { Header } from "@/components/header";
import { Sidebar } from "@/components/sidebar";
import SosialPage from "@/components/sosial-page";
export const Route = createFileRoute("/sosial")({ export const Route = createFileRoute("/sosial")({
component: RouteComponent, component: SosialRoute,
}); });
function RouteComponent() { function SosialRoute() {
return <div>Hello "/sosial"!</div>; const [opened, { toggle }] = useDisclosure();
const { colorScheme } = useMantineColorScheme();
const headerBgColor = colorScheme === "dark" ? "#11192D" : "#19355E";
const navbarBgColor = colorScheme === "dark" ? "#11192D" : "white";
const mainBgColor = colorScheme === "dark" ? "#11192D" : "#edf3f8ff";
return (
<AppShell
header={{ height: 60 }}
navbar={{
width: 300,
breakpoint: "sm",
collapsed: { mobile: !opened },
}}
padding="md"
>
<AppShell.Header bg={headerBgColor}>
<Group h="100%" px="md">
<Burger opened={opened} onClick={toggle} hiddenFrom="sm" size="sm" />
<Header />
</Group>
</AppShell.Header>
<AppShell.Navbar
p="md"
bg={navbarBgColor}
style={{ display: "flex", flexDirection: "column" }}
>
<div style={{ flex: 1, overflowY: "auto" }}>
<Sidebar />
</div>
</AppShell.Navbar>
<AppShell.Main bg={mainBgColor}>
<SosialPage />
</AppShell.Main>
</AppShell>
);
} }