diff --git a/src/components/bumdes-page.tsx b/src/components/bumdes-page.tsx index 605a8e8..b518f25 100644 --- a/src/components/bumdes-page.tsx +++ b/src/components/bumdes-page.tsx @@ -1,13 +1,23 @@ +import { + Badge, + Button, + Card, + Grid, + GridCol, + Group, + Select, + Stack, + Table, + Text, + Title, + useMantineColorScheme, +} from "@mantine/core"; import { IconBuildingStore, IconCategory, IconCurrency, IconUsers, - IconTrendingUp, - IconTrendingDown, - IconChevronDown, } from "@tabler/icons-react"; -import { useMantineColorScheme } from "@mantine/core"; import { useState } from "react"; const BumdesPage = () => { @@ -15,98 +25,69 @@ const BumdesPage = () => { const dark = colorScheme === "dark"; const [timeFilter, setTimeFilter] = useState("bulan"); - const [categoryFilter, setCategoryFilter] = useState("semua"); - // KPI Data + // Sample data for KPI cards const kpiData = [ { title: "UMKM Aktif", - value: "45", - subtitle: "Beroperasi", - icon: IconUsers, + value: 45, + icon: , + color: "darmasaba-blue", }, { title: "UMKM Terdaftar", - value: "68", - subtitle: "Total terdaftar", - icon: IconBuildingStore, + value: 68, + icon: , + color: "darmasaba-success", }, { title: "Omzet", - value: "48 JT", - subtitle: "Bulan ini", - icon: IconCurrency, + value: "Rp 48.000.000", + icon: , + color: "darmasaba-warning", }, { title: "Kategori UMKM", - value: "34", - subtitle: "Jenis produk", - icon: IconCategory, + value: 34, + icon: , + color: "darmasaba-danger", }, ]; - // Mini stats data - const miniStats = [ - { - title: "Total Penjualan", - value: "Rp 30.900.000", - subtitle: "+18% vs bulan lalu", - isPositive: true, - }, - { - title: "Produk Aktif", - value: "7", - subtitle: "Kategori produk", - }, - { - title: "Total Transaksi", - value: "500", - subtitle: "Transaksi bulan ini", - }, - ]; - - // Top 3 products data + // Sample data for top products const topProducts = [ { rank: 1, name: "Beras Premium Organik", - umkmOwner: "Kelompok Tani Subak", - sales: "Rp 8.500.000", - volume: "650 Kg Terjual", - growth: "+15%", + umkmOwner: "Warung Pak Joko", + growth: "+12%", }, { rank: 2, name: "Keripik Singkong", umkmOwner: "Ibu Sari Snack", - sales: "Rp 4.200.000", - volume: "320 Kg Terjual", growth: "+8%", }, { rank: 3, name: "Madu Alami", umkmOwner: "Peternakan Lebah", - sales: "Rp 3.750.000", - volume: "150 Liter Terjual", growth: "+5%", }, ]; - // Product sales data + // Sample data for product sales const productSales = [ { produk: "Beras Premium Organik", - umkm: "Kelompok Tani Subak", penjualanBulanIni: "Rp 8.500.000", - bulanLalu: "Rp 7.400.000", - trend: 15, + bulanLalu: "Rp 8.500.000", + trend: 10, volume: "650 Kg", stok: "850 Kg", }, { produk: "Keripik Singkong", - umkm: "Ibu Sari Snack", penjualanBulanIni: "Rp 4.200.000", bulanLalu: "Rp 3.800.000", trend: 10, @@ -115,7 +96,6 @@ const BumdesPage = () => { }, { produk: "Madu Alami", - umkm: "Peternakan Lebah", penjualanBulanIni: "Rp 3.750.000", bulanLalu: "Rp 4.100.000", trend: -8, @@ -124,7 +104,6 @@ const BumdesPage = () => { }, { produk: "Kecap Tradisional", - umkm: "Bu Darmi", penjualanBulanIni: "Rp 2.800.000", bulanLalu: "Rp 2.500.000", trend: 12, @@ -133,457 +112,278 @@ const BumdesPage = () => { }, ]; - const cardStyle = { - backgroundColor: dark ? "#1E293B" : "white", - border: `1px solid ${dark ? "#1E293B" : "white"}`, - }; - - const textStyle = { - color: dark ? "white" : "#1F2937", - }; - - const subtitleStyle = { - color: dark ? "#9CA3AF" : "#6B7280", - }; - return ( -
-
- {/* Row 1: Top 4 Metrics Cards */} -
- {kpiData.map((kpi, index) => ( -
+ {/* KPI Cards */} + + {kpiData.map((kpi, index) => ( + + -
-
-

+ + + {kpi.title} -

-

- {kpi.value} -

-

- {kpi.subtitle} -

-
-
-
- -
-
-
-
- ))} -
+ + + {typeof kpi.value === "number" + ? kpi.value.toLocaleString() + : kpi.value} + + + + {kpi.icon} + + + + + ))} + - {/* Row 2: Sales Update Header */} -
-
-

- Update Penjualan Produk -

-
- - -
-
-
- - {/* Row 3: Main Content Grid */} -
- {/* Left Column (30%) */} -
- {/* Produk Unggulan Section */} -
+ + + Update Penjualan Produk + + + + + + + - {/* Mini Stats Cards */} -
- {miniStats.map((stat, index) => ( -
+ {/* Produk Unggulan (Left Column) */} + + + {/* Total Penjualan, Produk Aktif, Total Transaksi */} + + + + + Total Penjualan + + + Rp 28.500.000 + + + + + Produk Aktif + + + 124 Produk + + + + + Total Transaksi + + + 1.240 Transaksi + + + + + + {/* Top 3 Produk Terlaris */} + + + Top 3 Produk Terlaris + + + {topProducts.map((product) => ( + -

+ + {product.rank} + + + + {product.name} + + + {product.umkmOwner} + + + + - {stat.title} -

-

- {stat.value} -

- {stat.subtitle && ( -

+ + ))} + + + + + + {/* Detail Penjualan Produk (Right Column) */} + + + + + Detail Penjualan Produk + + setCategoryFilter(e.target.value)} - className="appearance-none px-4 py-2 pr-8 rounded-lg text-sm font-medium border-0 focus:ring-2 focus:ring-[#1F3A5F] cursor-pointer" - style={{ - backgroundColor: dark ? "#334155" : "#F9FAFB", - color: dark ? "white" : "#1F2937", - }} - > - - - - - - -

-
- - {/* Data Table */} -
- - - - - - - - - - - - - - {productSales.map((product, index) => ( - - - - - - - - - - ))} - -
- Produk - - Penjualan Bulan Ini - - Bulan Lalu - - Trend - - Volume - - Stok - - Aksi -
-

- {product.produk} -

-

- {product.umkm} -

-
-

- {product.penjualanBulanIni} -

-
-

- {product.bulanLalu} -

-
-
= 0 ? "#22C55E" : "#EF4444", - }} - > - {product.trend >= 0 ? ( - - ) : ( - - )} - {product.trend >= 0 ? "+" : ""} - {product.trend}% -
-
-

- {product.volume} -

-
- 200 ? "#DCFCE7" : "#FEE2E2", - color: parseInt(product.stok) > 200 ? "#166534" : "#991B1B", - }} - > - {product.stok} - - - -
-
-
-
-
-
-
+ + + + + + ); }; -export default BumdesPage; +export default BumdesPage; \ No newline at end of file diff --git a/src/components/dashboard-content.tsx b/src/components/dashboard-content.tsx index 888caf4..30349ee 100644 --- a/src/components/dashboard-content.tsx +++ b/src/components/dashboard-content.tsx @@ -1,5 +1,4 @@ import { - Briefcase, Calendar, CheckCircle, FileText, @@ -28,9 +27,7 @@ import { Card, // Added for icon containers Grid, Group, - Image, Progress, - SimpleGrid, Stack, Text, ThemeIcon, @@ -69,19 +66,6 @@ const eventData = [ { date: "19 Oktober 2025", title: "Rapat Koordinasi" }, ]; -const apbdesData = [ - { name: "Belanja", value: 390, label: "390M" }, - { name: "Pendapatan", value: 470, label: "470M" }, - { name: "Pembiayaan", value: 290, label: "290M" }, -]; - -const sdgsData = [ - { label: "Desa Berenergi Bersih Dan Terbarukan", value: 99.64, image: "/SDGS-7.png" }, - { label: "Desa Damai Berkeadilan", value: 78.65, image: "/SDGS-16.png" }, - { label: "Desa Sehat Dan Sejahtera", value: 77.37, image: "/SDGS-3.png" }, - { label: "Desa Tanpa Kemiskinan", value: 52.62, image: "/SDGS-1.png" } -]; - export function DashboardContent() { const { colorScheme } = useMantineColorScheme(); const dark = colorScheme === "dark"; @@ -119,7 +103,7 @@ export function DashboardContent() { variant="filled" size="xl" radius="xl" - color={dark ? "gray" : "darmasaba-navy"} + color={dark ? "gray" : "darmasaba-blue"} > @@ -153,7 +137,7 @@ export function DashboardContent() { variant="filled" size="xl" radius="xl" - color={dark ? "gray" : "darmasaba-navy"} + color={dark ? "gray" : "darmasaba-blue"} > @@ -190,7 +174,7 @@ export function DashboardContent() { variant="filled" size="xl" radius="xl" - color={dark ? "gray" : "darmasaba-navy"} + color={dark ? "gray" : "darmasaba-blue"} > @@ -224,7 +208,7 @@ export function DashboardContent() { variant="filled" size="xl" radius="xl" - color={dark ? "gray" : "darmasaba-navy"} + color={dark ? "gray" : "darmasaba-blue"} > @@ -292,7 +276,7 @@ export function DashboardContent() { @@ -385,7 +369,46 @@ export function DashboardContent() { {/* Original SVG icon */} - + + + + + + Divisi Teraktif @@ -404,7 +427,7 @@ export function DashboardContent() { value={(divisi.value / 37) * 100} size="sm" radius="xl" - color="#1E3A5F" + color="blue" /> ))} @@ -430,7 +453,7 @@ export function DashboardContent() { @@ -457,60 +480,44 @@ export function DashboardContent() { Grafik APBDes - {apbdesData.map((data, index) => ( - - - - {data.name} - - - - - - - - {data.label} - - - - ))} + + + Belanja + + + + + + Pendapatan + + + + + + Pembangunan + + + - - {/* SDGS Desa */} - - - SDGS Desa - - - {sdgsData.map((data, index) => ( - - - - - - {data.label} - - - {data.value} - - - - - ))} - - ); -} +} \ No newline at end of file diff --git a/src/components/demografi-pekerjaan.tsx b/src/components/demografi-pekerjaan.tsx index 81776ef..8adffd2 100644 --- a/src/components/demografi-pekerjaan.tsx +++ b/src/components/demografi-pekerjaan.tsx @@ -1,544 +1,411 @@ +import { BarChart, PieChart } from "@mantine/charts"; +import { + Box, + Card, + Grid, + Group, + Stack, + Table, + Text, + Title, + useMantineColorScheme, +} from "@mantine/core"; import { IconArrowDown, IconArrowUp, IconBabyCarriage, IconSkull, - IconUsers, - IconHome, - IconExclamationCircle, } from "@tabler/icons-react"; -import { useMantineColorScheme } from "@mantine/core"; -import { - Bar, - BarChart, - CartesianGrid, - Cell, - Pie, - PieChart, - ResponsiveContainer, - Tooltip, - XAxis, - YAxis, -} from "recharts"; +import React from "react"; + +// Sample Data +const kpiData = [ + { + id: 1, + title: "Total Penduduk", + value: "5.634", + sub: "Aktif terdaftar", + icon: ( + + Total Penduduk + + + ), + }, + { + id: 2, + title: "Kepala Keluarga", + value: "1.354", + sub: "Total KK", + icon: ( + + Kepala Keluarga + + + ), + }, + { + id: 3, + title: "Kelahiran", + value: "23", + sub: "Tahun ini", + icon: ( + + ), + }, + { + id: 4, + title: "Kemiskinan", + value: "324", + delta: "-10% dari tahun lalu", + deltaType: "positive", + icon: ( + + Kemiskinan + + + ), + }, +]; + +const ageDistributionData = [ + { ageRange: "17-25", total: 850 }, + { ageRange: "26-35", total: 1200 }, + { ageRange: "36-45", total: 1100 }, + { ageRange: "46-55", total: 950 }, + { ageRange: "56-65", total: 750 }, + { ageRange: "65+", total: 484 }, +]; + +const jobDistributionData = [ + { job: "Sipil", total: 1200 }, + { job: "Guru", total: 850 }, + { job: "Petani", total: 950 }, + { job: "Pedagang", total: 750 }, + { job: "Wiraswasta", total: 984 }, +]; + +const religionData = [ + { religion: "Hindu", total: 4234, color: "red" }, + { religion: "Islam", total: 856, color: "blue" }, + { religion: "Kristen", total: 412, color: "green" }, + { religion: "Buddha", total: 202, color: "yellow" }, +]; + +const banjarData = [ + { banjar: "Banjar Darmasaba", population: 1200, kk: 300, poor: 45 }, + { banjar: "Banjar Manesa", population: 950, kk: 240, poor: 32 }, + { banjar: "Banjar Cabe", population: 800, kk: 200, poor: 28 }, + { banjar: "Banjar Penenjoan", population: 1100, kk: 280, poor: 38 }, + { banjar: "Banjar Baler Pasar", population: 984, kk: 250, poor: 42 }, + { banjar: "Banjar Bucu", population: 600, kk: 184, poor: 25 }, +]; + +const dynamicStats = [ + { + title: "Kelahiran", + value: "23", + icon: , + color: "green", + }, + { + title: "Kematian", + value: "12", + icon: , + color: "red", + }, + { + title: "Pindah Masuk", + value: "45", + icon: , + color: "blue", + }, + { + title: "Pindah Keluar", + value: "32", + icon: , + color: "orange", + }, +]; const DemografiPekerjaan = () => { const { colorScheme } = useMantineColorScheme(); const dark = colorScheme === "dark"; - - // KPI Data - const kpiData = [ - { - id: 1, - title: "Total Penduduk", - value: "5.634", - subtitle: "Aktif terdaftar", - icon: IconUsers, - }, - { - id: 2, - title: "Kepala Keluarga", - value: "1.354", - subtitle: "Total KK", - icon: IconHome, - }, - { - id: 3, - title: "Kelahiran", - value: "23", - subtitle: "Tahun ini", - icon: IconBabyCarriage, - }, - { - id: 4, - title: "Kemiskinan", - value: "324", - subtitle: "-10% dari tahun lalu", - icon: IconExclamationCircle, - }, - ]; - - // Age distribution data - const ageDistributionData = [ - { ageRange: "17-25", total: 850 }, - { ageRange: "26-35", total: 1200 }, - { ageRange: "36-45", total: 1100 }, - { ageRange: "46-55", total: 950 }, - { ageRange: "56-65", total: 750 }, - { ageRange: "65+", total: 484 }, - ]; - - // Job distribution data - const jobDistributionData = [ - { job: "Sipil", total: 1200 }, - { job: "Guru", total: 850 }, - { job: "Petani", total: 950 }, - { job: "Pedagang", total: 750 }, - { job: "Wiraswasta", total: 984 }, - ]; - - // Religion data - const religionData = [ - { religion: "Hindu", total: 4234, color: "#EF4444" }, - { religion: "Islam", total: 856, color: "#3B82F6" }, - { religion: "Kristen", total: 412, color: "#10B981" }, - { religion: "Buddha", total: 202, color: "#F59E0B" }, - ]; - - // Banjar data - const banjarData = [ - { banjar: "Banjar Darmasaba", population: 1200, kk: 300, poor: 45 }, - { banjar: "Banjar Manesa", population: 950, kk: 240, poor: 32 }, - { banjar: "Banjar Cabe", population: 800, kk: 200, poor: 28 }, - { banjar: "Banjar Penenjoan", population: 1100, kk: 280, poor: 38 }, - { banjar: "Banjar Baler Pasar", population: 984, kk: 250, poor: 42 }, - { banjar: "Banjar Bucu", population: 600, kk: 184, poor: 25 }, - ]; - - // Dynamic stats - const dynamicStats = [ - { - title: "Kelahiran", - value: "23", - icon: IconBabyCarriage, - color: "#10B981", - }, - { - title: "Kematian", - value: "12", - icon: IconSkull, - color: "#EF4444", - }, - { - title: "Pindah Masuk", - value: "45", - icon: IconArrowDown, - color: "#3B82F6", - }, - { - title: "Pindah Keluar", - value: "32", - icon: IconArrowUp, - color: "#F59E0B", - }, - ]; - - const COLORS = ["#1E3A5F", "#3B82F6", "#60A5FA", "#93C5FD", "#DBEAFE"]; - - const cardStyle = { - backgroundColor: dark ? "#141D34" : "white", - border: `1px solid ${dark ? "#141D34" : "white"}`, - }; - - const textStyle = { - color: dark ? "white" : "#1F2937", - }; - - const subtitleStyle = { - color: dark ? "#9CA3AF" : "#6B7280", - }; - return ( -
-
- {/* Row 1: 4 Statistic Cards */} -
+ + + {/* KPI Cards */} + {kpiData.map((kpi) => ( -
-
-
-

- {kpi.title} -

-

- {kpi.value} -

-

- {kpi.subtitle} -

-
-
-
- -
-
-
-
- ))} -
- - {/* Row 2: 2 Chart Cards */} -
- {/* Age Distribution Bar Chart */} -
-

- Grafik Pengelompokan Umur -

- - - - - - - - {ageDistributionData.map((entry, index) => ( - - ))} - - - -
- - {/* Job Distribution Bar Chart */} -
-

- Demografi Pekerjaan -

- - - - - - - - {jobDistributionData.map((entry, index) => ( - - ))} - - - -
-
- - {/* Row 3: 3 Insight Cards */} -
- {/* Religion Distribution Pie Chart */} -
-

- Distribusi Agama -

- - - - `${name}: ${percent ? (percent * 100).toFixed(0) : 0}%` - } - > - {religionData.map((entry, index) => ( - - ))} - - - - -
- - {/* Population per Banjar Table */} -
-

- Data per Banjar -

-
- - - - - - - - - - - {banjarData.map((item, index) => ( - - - - - - - ))} - -
- Banjar - - Penduduk - - KK - - Miskin -
- {item.banjar} - - {item.population.toLocaleString()} - - {item.kk.toLocaleString()} - - {item.poor.toLocaleString()} -
-
-
-
- - {/* Population Dynamics Stats */} -
-

- Statistik Dinamika Penduduk -

-
- {dynamicStats.map((stat, index) => ( -
+ -
-
-

- {stat.title} -

-

- {stat.value} -

-
-
+ + {kpi.title} + + {React.cloneElement(kpi.icon, { + className: "h-6 w-6", + color: dark + ? "var(--mantine-color-dark-3)" + : "var(--mantine-color-dimmed)", + })} + + + {kpi.value} + + {kpi.delta && ( + - -
-
-
+ {kpi.delta} + + )} + {kpi.sub && ( + + {kpi.sub} + + )} + + + ))} + + + {/* Charts Section */} + + {/* Grafik Pengelompokan Umur */} + + + + Grafik Pengelompokan Umur + + + + + + {/* Demografi Pekerjaan */} + + + + Demografi Pekerjaan + + + + + + + {/* Agama & Data per Banjar */} + + {/* Distribusi Agama */} + + + + Distribusi Agama + + ({ + name: item.religion, + value: item.total, + color: item.color, + }))} + withLabels + withLabelsLine + labelsPosition="outside" + labelsType="percent" + /> + + + + {/* Data per Banjar */} + + + + Data per Banjar + + + + + + Banjar + + + Penduduk + + + KK + + + Miskin + + + + + {banjarData.map((item, index) => ( + + + {item.banjar} + + + + {item.population.toLocaleString()} + + + + + {item.kk.toLocaleString()} + + + + + {item.poor.toLocaleString()} + + + + ))} + +
+
+
+
+ + {/* Statistik Dinamika Penduduk */} + + + Statistik Dinamika Penduduk + + + {dynamicStats.map((stat, index) => ( + + + + + + {stat.title} + + + {stat.value} + + + {stat.icon} + + + ))} -
-
-
-
+ + + +
); }; -export default DemografiPekerjaan; +export default DemografiPekerjaan; \ No newline at end of file diff --git a/src/components/header.tsx b/src/components/header.tsx index 7109674..b66f355 100644 --- a/src/components/header.tsx +++ b/src/components/header.tsx @@ -1,72 +1,121 @@ import { ActionIcon, + Avatar, Badge, Box, + Divider, Group, Text, + Title, useMantineColorScheme, } from "@mantine/core"; -import { useLocation } from "@tanstack/react-router"; -import { Bell, Moon, Sun } from "lucide-react"; +import { IconUserShield } from "@tabler/icons-react"; +import { useLocation, useNavigate } from "@tanstack/react-router"; +import { Bell, Moon, Sun, User as UserIcon } from "lucide-react"; // Renamed User to UserIcon to avoid conflict with Mantine's User component if it exists export function Header() { const location = useLocation(); const { colorScheme, toggleColorScheme } = useMantineColorScheme(); const dark = colorScheme === "dark"; + const navigate = useNavigate(); - const title = - location.pathname === "/" - ? "Desa Darmasaba" - : "Desa Darmasaba"; + // Define page titles based on route + const getPageTitle = () => { + switch (location.pathname) { + case "/": + return "Beranda"; + case "/kinerja-divisi": + return "Kinerja Divisi"; + case "/pengaduan-layanan-publik": + return "Pengaduan & Layanan Publik"; + case "/jenna-analytic": + return "Jenna Analytic"; + case "/demografi-pekerjaan": + return "Demografi & Kependudukan"; + case "/keuangan-anggaran": + return "Keuangan & Anggaran"; + case "/bumdes": + return "Bumdes & UMKM Desa"; + case "/sosial": + return "Sosial"; + case "/keamanan": + return "Keamanan"; + case "/bantuan": + return "Bantuan"; + case "/pengaturan": + case "/pengaturan/umum": + case "/pengaturan/notifikasi": + case "/pengaturan/keamanan": + case "/pengaturan/akses-dan-tim": + return "Pengaturan"; + default: + return "Desa Darmasaba"; + } + }; return ( - - {/* LEFT SPACER (burger sudah di luar) */} - + + {/* Title */} + + {getPageTitle()} + - {/* CENTER TITLE */} - - {title} - + {/* Right Section */} + + {/* User Info */} + + + + I. B. Surya Prabhawa M... + + + Kepala Desa + + + + + + - {/* RIGHT ICONS */} - - - {dark ? : } - + {/* Divider */} + - - - + toggleColorScheme()} + variant="subtle" + size="lg" + radius="xl" + aria-label="Toggle color scheme" > - 10 - - + {dark ? ( + + ) : ( + + )} + + + + + 10 + + + + navigate({ to: "/signin" })} + /> + + - + ); -} +} \ No newline at end of file diff --git a/src/components/help-page.tsx b/src/components/help-page.tsx index cbcea3c..2e3f2e5 100644 --- a/src/components/help-page.tsx +++ b/src/components/help-page.tsx @@ -142,7 +142,14 @@ const HelpPage = () => { }; return ( - + + + Pusat Bantuan + + + Temukan jawaban untuk pertanyaan Anda atau hubungi tim support kami + + {/* Statistics Section */} {stats.map((stat, index) => ( @@ -425,4 +432,4 @@ const HelpPage = () => { ); }; -export default HelpPage; +export default HelpPage; \ No newline at end of file diff --git a/src/components/jenna-analytic.tsx b/src/components/jenna-analytic.tsx index 4fc8032..519fac6 100644 --- a/src/components/jenna-analytic.tsx +++ b/src/components/jenna-analytic.tsx @@ -1,328 +1,283 @@ +import { BarChart } from "@mantine/charts"; import { - IconAlertTriangle, - IconClock, - IconMessageChatbot, - IconSparkles, -} from "@tabler/icons-react"; -import { useMantineColorScheme } from "@mantine/core"; -import { - Bar, - BarChart, - CartesianGrid, - Cell, - ResponsiveContainer, - Tooltip, - XAxis, - YAxis, -} from "recharts"; + Badge, + Box, + Button, + Card, + Grid, + Group, + Progress, + Stack, + Text, + Title, + useMantineColorScheme, +} from "@mantine/core"; +import React from "react"; + +// Sample Data +const kpiData = [ + { + id: 1, + title: "Interaksi Hari Ini", + value: "61", + delta: "+15% dari kemarin", + deltaType: "positive", + icon: ( + + + + ), + }, + { + id: 2, + title: "Jawaban Otomatis", + value: "87%", + sub: "53 dari 61 interaksi", + icon: ( + + + + ), + }, + { + id: 3, + title: "Belum Ditindak", + value: "8", + sub: "Perlu respon manual", + deltaType: "negative", + icon: ( + + + + ), + }, + { + id: 4, + title: "Waktu Respon", + value: "2.3 sec", + sub: "Rata-rata", + icon: ( + + + + ), + }, +]; + +const chartData = [ + { day: "Sen", total: 100 }, + { day: "Sel", total: 120 }, + { day: "Rab", total: 90 }, + { day: "Kam", total: 150 }, + { day: "Jum", total: 110 }, + { day: "Sab", total: 80 }, + { day: "Min", total: 130 }, +]; + +const topTopics = [ + { topic: "Cara mengurus KTP", count: 89 }, + { topic: "Syarat Kartu Keluarga", count: 76 }, + { topic: "Jadwal Posyandu", count: 64 }, + { topic: "Pengaduan jalan rusak", count: 52 }, + { topic: "Info program bansos", count: 48 }, +]; + +const busyHours = [ + { period: "Pagi (08–12)", percentage: 30 }, + { period: "Siang (12–16)", percentage: 40 }, + { period: "Sore (16–20)", percentage: 20 }, + { period: "Malam (20–08)", percentage: 10 }, +]; const JennaAnalytic = () => { const { colorScheme } = useMantineColorScheme(); const dark = colorScheme === "dark"; - // KPI Data - const kpiData = [ - { - id: 1, - title: "Interaksi Hari Ini", - value: "61", - subtitle: "+15% dari kemarin", - icon: IconMessageChatbot, - }, - { - id: 2, - title: "Jawaban Otomatis", - value: "87%", - subtitle: "53 dari 61 interaksi", - icon: IconSparkles, - }, - { - id: 3, - title: "Belum Ditindak", - value: "8", - subtitle: "Perlu respon manual", - icon: IconAlertTriangle, - }, - { - id: 4, - title: "Waktu Respon", - value: "2.3s", - subtitle: "Rata-rata", - icon: IconClock, - }, - ]; - - // Weekly chatbot interaction data - const weeklyData = [ - { day: "Sen", interactions: 100 }, - { day: "Sel", interactions: 120 }, - { day: "Rab", interactions: 90 }, - { day: "Kam", interactions: 150 }, - { day: "Jum", interactions: 110 }, - { day: "Sab", interactions: 80 }, - { day: "Min", interactions: 130 }, - ]; - - // Top topics data - const topTopics = [ - { topic: "Cara mengurus KTP", count: 89 }, - { topic: "Syarat Kartu Keluarga", count: 76 }, - { topic: "Jadwal Posyandu", count: 64 }, - { topic: "Pengaduan jalan rusak", count: 52 }, - { topic: "Info program bansos", count: 48 }, - ]; - - // Busy hour distribution - const busyHours = [ - { period: "Pagi (08–12)", percentage: 30 }, - { period: "Siang (12–16)", percentage: 40 }, - { period: "Sore (16–20)", percentage: 20 }, - { period: "Malam (20–08)", percentage: 10 }, - ]; - - const COLORS = ["#1E3A5F", "#3B82F6", "#60A5FA", "#93C5FD"]; - - const cardStyle = { - backgroundColor: dark ? "#141D34" : "white", - border: `1px solid ${dark ? "#141D34" : "white"}`, - }; - - const textStyle = { - color: dark ? "white" : "#1F2937", - }; - - const subtitleStyle = { - color: dark ? "#9CA3AF" : "#6B7280", - }; - return ( -
-
- {/* Row 1: 4 Statistic Cards */} -
+ + + {/* KPI Cards */} + {kpiData.map((kpi) => ( -
-
-
-

+ + + + {kpi.title} -

-

+ {React.cloneElement(kpi.icon, { + className: "h-6 w-6", // Keeping classes for now, can be replaced by Mantine Icon component if available or styled with sx prop + color: "var(--mantine-color-dimmed)", // Set color via prop + })} + + + {kpi.value} + + {kpi.delta && ( + - {kpi.value} -

-

- {kpi.subtitle} -

-
-
-
- -
-
-
-
+ {kpi.delta} + + )} + {kpi.sub && ( + + {kpi.sub} + + )} + + ))} -
+ - {/* Row 2: Full Width Weekly Bar Chart */} -
-

- Interaksi Chatbot Mingguan -

- - - - - - - - {weeklyData.map((entry, index) => ( - + + Interaksi Chatbot + + + + + {/* Charts and Lists Section */} + + {/* Grafik Interaksi Chatbot (now Bar Chart) */} + + + + Jam Tersibuk + + + {busyHours.map((item, index) => ( + + {item.period} + + + + {item.percentage}% + + + ))} - - - -
+ + + - {/* Row 3: Two Insight Cards */} -
- {/* Left: Frequently Asked Topics */} -
-

- Topik Pertanyaan Terbanyak -

-
- {topTopics.map((item, index) => ( -
- - {item.topic} - - - {item.count}x - -
- ))} -
-
+ {/* Topik Pertanyaan Terbanyak & Jam Tersibuk */} + + + {/* Topik Pertanyaan Terbanyak */} + + + Topik Pertanyaan Terbanyak + + + {topTopics.map((item, index) => ( + + + {item.topic} + + + {item.count}x + + + ))} + + - {/* Right: Busy Hour Distribution */} -
-

- Distribusi Jam Tersibuk -

-
- {busyHours.map((item, index) => ( -
-
- - {item.period} - - - {item.percentage}% - -
-
-
-
-
- ))} -
-
-
-
-
+ {/* Jam Tersibuk */} + + + + + ); }; - -export default JennaAnalytic; +export default JennaAnalytic; \ No newline at end of file diff --git a/src/components/keamanan-page.tsx b/src/components/keamanan-page.tsx index 0233b51..bd58882 100644 --- a/src/components/keamanan-page.tsx +++ b/src/components/keamanan-page.tsx @@ -118,6 +118,13 @@ const KeamananPage = () => { return ( + {/* Page Header */} + + + Keamanan Lingkungan Desa + + + {/* KPI Cards */} {kpiData.map((kpi, index) => ( @@ -315,4 +322,4 @@ const KeamananPage = () => { ); }; -export default KeamananPage; +export default KeamananPage; \ No newline at end of file diff --git a/src/components/keuangan-anggaran.tsx b/src/components/keuangan-anggaran.tsx index ff35706..d271534 100644 --- a/src/components/keuangan-anggaran.tsx +++ b/src/components/keuangan-anggaran.tsx @@ -1,568 +1,357 @@ +import { BarChart } from "@mantine/charts"; +import { + Badge, + Box, + Button, + Card, + Grid, + Group, + Progress, + Stack, + Text, + Title, + useMantineColorScheme, +} from "@mantine/core"; import { IconCurrency, IconTrendingDown, IconTrendingUp, - IconCheck, - IconClock, } from "@tabler/icons-react"; -import { useMantineColorScheme } from "@mantine/core"; -import { - Bar, - BarChart, - CartesianGrid, - Cell, - Line, - LineChart, - ResponsiveContainer, - Tooltip, - XAxis, - YAxis, -} from "recharts"; +import React from "react"; + +// Sample Data +const kpiData = [ + { + id: 1, + title: "Total APBDes", + value: "Rp 5.2M", + sub: "Tahun 2025", + icon: , + }, + { + id: 2, + title: "Realisasi", + value: "68%", + sub: "Rp 3.5M dari 5.2M", + icon: ( + + + + ), + }, + { + id: 3, + title: "Pemasukan", + value: "Rp 580jt", + sub: "Bulan ini", + delta: "+8%", + deltaType: "positive", + icon: , + }, + { + id: 4, + title: "Pengeluaran", + value: "Rp 520jt", + sub: "Bulan ini", + icon: , + }, +]; + +const incomeExpenseData = [ + { month: "Apr", income: 450, expense: 380 }, + { month: "Mei", income: 520, expense: 420 }, + { month: "Jun", income: 480, expense: 500 }, + { month: "Jul", income: 580, expense: 450 }, + { month: "Agu", income: 550, expense: 520 }, + { month: "Sep", income: 600, expense: 480 }, + { month: "Okt", income: 580, expense: 520 }, +]; + +const allocationData = [ + { sector: "Pembangunan", amount: 1200 }, + { sector: "Kesehatan", amount: 800 }, + { sector: "Pendidikan", amount: 650 }, + { sector: "Sosial", amount: 550 }, + { sector: "Kebudayaan", amount: 400 }, + { sector: "Teknologi", amount: 300 }, +]; + +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 apbdReport = { + income: [ + { category: "Dana Desa", amount: 1800 }, + { category: "Alokasi Dana Desa", amount: 480 }, + { category: "Bagi Hasil Pajak & Retribusi", amount: 300 }, + { category: "Pendapatan Asli Desa", amount: 200 }, + { category: "Hibah Bantuan", amount: 300 }, + ], + expenses: [ + { category: "Penyelenggaraan Pemerintah", amount: 425 }, + { category: "Pembangunan Desa", amount: 850 }, + { category: "Pembinaan Kemasyarakatan", amount: 320 }, + { category: "Pemberdayaan Masyarakat", amount: 380 }, + { category: "Penanggulangan Bencana", amount: 180 }, + ], + totalIncome: 3080, + totalExpenses: 2155, +}; const KeuanganAnggaran = () => { const { colorScheme } = useMantineColorScheme(); const dark = colorScheme === "dark"; - - // KPI Data - const kpiData = [ - { - id: 1, - title: "Total APBDes", - value: "Rp 5.2M", - subtitle: "Tahun 2025", - icon: IconCurrency, - }, - { - id: 2, - title: "Realisasi", - value: "68%", - subtitle: "Rp 3.5M dari 5.2M", - icon: IconCheck, - }, - { - id: 3, - title: "Pemasukan", - value: "Rp 580jt", - subtitle: "Bulan ini", - delta: "+8%", - icon: IconTrendingUp, - }, - { - id: 4, - title: "Pengeluaran", - value: "Rp 520jt", - subtitle: "Bulan ini", - icon: IconTrendingDown, - }, - ]; - - // Income vs Expense data - const incomeExpenseData = [ - { month: "Apr", income: 450, expense: 380 }, - { month: "Mei", income: 520, expense: 420 }, - { month: "Jun", income: 480, expense: 500 }, - { month: "Jul", income: 580, expense: 450 }, - { month: "Agu", income: 550, expense: 520 }, - { month: "Sep", income: 600, expense: 480 }, - { month: "Okt", income: 580, expense: 520 }, - ]; - - // Allocation data - const allocationData = [ - { sector: "Pembangunan", amount: 1200 }, - { sector: "Kesehatan", amount: 800 }, - { sector: "Pendidikan", amount: 650 }, - { sector: "Sosial", amount: 550 }, - { sector: "Kebudayaan", amount: 400 }, - { sector: "Teknologi", amount: 300 }, - ]; - - // Assistance fund 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" }, - ]; - - // APBDes Report data - const apbdReport = { - income: [ - { category: "Dana Desa", amount: 1800 }, - { category: "Alokasi Dana Desa", amount: 480 }, - { category: "Bagi Hasil Pajak & Retribusi", amount: 300 }, - { category: "Pendapatan Asli Desa", amount: 200 }, - { category: "Hibah Bantuan", amount: 300 }, - ], - expenses: [ - { category: "Penyelenggaraan Pemerintah", amount: 425 }, - { category: "Pembangunan Desa", amount: 850 }, - { category: "Pembinaan Kemasyarakatan", amount: 320 }, - { category: "Pemberdayaan Masyarakat", amount: 380 }, - { category: "Penanggulangan Bencana", amount: 180 }, - ], - totalIncome: 3080, - totalExpenses: 2155, - }; - - const COLORS = ["#1E3A5F", "#3B82F6", "#60A5FA", "#93C5FD", "#DBEAFE"]; - - const cardStyle = { - backgroundColor: dark ? "#1E293B" : "white", - border: `1px solid ${dark ? "#1E293B" : "white"}`, - }; - - const textStyle = { - color: dark ? "white" : "#1F2937", - }; - - const subtitleStyle = { - color: dark ? "#9CA3AF" : "#6B7280", - }; - return ( -
-
- {/* Row 1: 4 Summary Metrics Cards */} -
+ + + {/* KPI Cards */} + {kpiData.map((kpi) => ( -
-
-
-

+ + + + {kpi.title} -

-

+ {React.cloneElement(kpi.icon, { + className: "h-6 w-6", + color: "var(--mantine-color-dimmed)", + })} + + + {kpi.value} + + {kpi.delta && ( + - {kpi.value} -

-

- {kpi.subtitle} -

- {kpi.delta && ( -

- {kpi.delta} -

- )} -
-
-
- -
-
-
-
+ {kpi.delta} + + )} + {kpi.sub && ( + + {kpi.sub} + + )} + + ))} -
+ - {/* Row 2: Line Chart Section */} -
-

- Pemasukan vs Pengeluaran -

- - - - + {/* Grafik Pemasukan vs Pengeluaran */} + + + + Pemasukan vs Pengeluaran + + - `${value}jt`} - /> - - - - - + + - {/* Legend */} -
-
-
- - Pemasukan - -
-
-
- - Pengeluaran - -
-
-
- - {/* Row 3: Analytics Section */} - - -
- {/* Left: Horizontal Bar Chart */} -
-

+ - Alokasi Anggaran Per Sektor -

- - - - `${value}jt`} - /> - - - - {allocationData.map((entry, index) => ( - + + Alokasi Anggaran Per Sektor + + + + + + + + {/* Dana Bantuan & Hibah */} + + + + Dana Bantuan & Hibah + + + {assistanceFundData.map((fund, index) => ( + + + + {fund.source} + + + Rp {fund.amount.toLocaleString()}jt + + + + {fund.status} + + + ))} + + + + + {/* Laporan APBDes */} + + + + Laporan APBDes + + + + + Pendapatan + + + {apbdReport.income.map((item, index) => ( + + {item.category} + + Rp {item.amount.toLocaleString()}jt + + ))} - - - -
- {/* Right: Assistance Funds List */} -
-

- Dana Bantuan dan Hibah -

-
- {assistanceFundData.map((fund, index) => ( -
-
-

- {fund.source} -

-

- Rp {fund.amount.toLocaleString()}jt -

-
- - {fund.status === "cair" ? ( - - ) : ( - - )} - {fund.status} - -
- ))} -
-
+ + Total Pendapatan: + + Rp {apbdReport.totalIncome.toLocaleString()}jt + + + + -
- {/* Row 4: Report Section */} -
-

- Laporan APBDes -

-
- {/* Left: Pendapatan */} -
-

+ + Belanja + + + {apbdReport.expenses.map((item, index) => ( + + {item.category} + + Rp {item.amount.toLocaleString()}jt + + + ))} + + Total Belanja: + + Rp {apbdReport.totalExpenses.toLocaleString()}jt + + + + + + - Pendapatan -

-
- {apbdReport.income.map((item, index) => ( -
+ Saldo: + apbdReport.totalExpenses + ? "green" + : "red" + } > - - {item.category} - - - Rp {item.amount.toLocaleString()}jt - -
- ))} -
- - Total Pendapatan - - - Rp {apbdReport.totalIncome.toLocaleString()}jt - -
-
-
- - {/* Right: Belanja */} -
-

- Belanja -

-
- {apbdReport.expenses.map((item, index) => ( -
- - {item.category} - - - Rp {item.amount.toLocaleString()}jt - -
- ))} -
- - Total Belanja - - - Rp {apbdReport.totalExpenses.toLocaleString()}jt - -
-
-
-
- - {/* Footer: Balance */} -
- - Saldo - - apbdReport.totalExpenses - ? "#22C55E" - : "#EF4444", - }} - > - Rp{" "} - {( - apbdReport.totalIncome - apbdReport.totalExpenses - ).toLocaleString()} - jt - -
-
- -
-
+ Rp{" "} + {( + apbdReport.totalIncome - apbdReport.totalExpenses + ).toLocaleString()} + jt + + + + + + + + ); }; -export default KeuanganAnggaran; +export default KeuanganAnggaran; \ No newline at end of file diff --git a/src/components/kinerja-divisi.tsx b/src/components/kinerja-divisi.tsx index 4f64037..e56e27d 100644 --- a/src/components/kinerja-divisi.tsx +++ b/src/components/kinerja-divisi.tsx @@ -1,3 +1,21 @@ +import { + ActionIcon, + Box, + Card, + Divider, + Grid, + GridCol, + Group, + List, + Badge as MantineBadge, + Progress as MantineProgress, + Skeleton, + Stack, + Text, + ThemeIcon, + Title, + useMantineColorScheme, +} from "@mantine/core"; import { Bar, BarChart, @@ -10,381 +28,518 @@ import { XAxis, YAxis, } from "recharts"; -import { useMantineColorScheme } from "@mantine/core"; -import { IconMessage } from "@tabler/icons-react"; +import { Button } from "@/components/ui/button"; const KinerjaDivisi = () => { const { colorScheme } = useMantineColorScheme(); const dark = colorScheme === "dark"; - // Top row - 4 activity cards - const activities = [ + // Data for division progress chart + const divisionProgressData = [ + { name: "Sekretariat", selesai: 12, berjalan: 5, tertunda: 2 }, + { name: "Keuangan", selesai: 8, berjalan: 7, tertunda: 1 }, + { name: "Sosial", selesai: 10, berjalan: 3, tertunda: 4 }, + { name: "Humas", selesai: 6, berjalan: 9, tertunda: 3 }, + ]; + + // Division task summaries + const divisionTasks = [ { - title: "Rakor 2025", - progress: 100, - date: "15 Jan 2025", + name: "Sekretariat", + tasks: [ + { title: "Laporan Bulanan", status: "selesai" }, + { title: "Arsip Dokumen", status: "berjalan" }, + { title: "Undangan Rapat", status: "tertunda" }, + ], }, { - title: "Pemutakhiran Indeks Desa", - progress: 100, - date: "20 Feb 2025", + name: "Keuangan", + tasks: [ + { title: "Laporan APBDes", status: "selesai" }, + { title: "Verifikasi Dana", status: "tertunda" }, + { title: "Pengeluaran Harian", status: "berjalan" }, + ], }, { - title: "Mengurus akta cerai warga", - progress: 100, - date: "5 Mar 2025", + name: "Sosial", + tasks: [ + { title: "Program Bantuan", status: "selesai" }, + { title: "Kegiatan Posyandu", status: "berjalan" }, + { title: "Monitoring Stunting", status: "tertunda" }, + ], }, { - title: "Pasek 7 desa adat", + name: "Humas", + tasks: [ + { title: "Publikasi Kegiatan", status: "selesai" }, + { title: "Koordinasi Media", status: "berjalan" }, + { title: "Laporan Kegiatan", status: "tertunda" }, + ], + }, + ]; + + // Archive items + const archiveItems = [ + { name: "Surat Keputusan", count: 12 }, + { name: "Laporan Keuangan", count: 8 }, + { name: "Dokumentasi", count: 24 }, + { name: "Notulensi Rapat", count: 15 }, + ]; + + // Activity progress + const activityProgress = [ + { + name: "Pembangunan Jalan", + progress: 75, + date: "15 Feb 2026", + status: "berjalan", + }, + { + name: "Posyandu Bulanan", progress: 100, - date: "10 Mar 2025", + date: "10 Feb 2026", + status: "selesai", + }, + { + name: "Vaksinasi Massal", + progress: 45, + date: "20 Feb 2026", + status: "berjalan", + }, + { + name: "Festival Budaya", + progress: 20, + date: "5 Mar 2026", + status: "berjalan", }, ]; // Document statistics const documentStats = [ - { name: "Gambar", value: 300, color: "#FAC858" }, - { name: "Dokumen", value: 310, color: "#92CC76" }, + { name: "Gambar", value: 42 }, + { name: "Dokumen", value: 87 }, ]; // Activity progress statistics const activityProgressStats = [ - { name: "Selesai", value: 83.33, fill: "#92CC76" }, - { name: "Dikerjakan", value: 16.67, fill: "#FAC858" }, - { name: "Segera Dikerjakan", value: 0, fill: "#5470C6" }, - { name: "Dibatalkan", value: 0, fill: "#EE6767" }, + { name: "Selesai", value: 12 }, + { name: "Dikerjakan", value: 8 }, + { name: "Segera Dikerjakan", value: 5 }, + { name: "Dibatalkan", value: 2 }, ]; + const COLORS = ["#10B981", "#F59E0B", "#EF4444", "#6B7280"]; + const STATUS_COLORS: Record = { + selesai: "green", + berjalan: "blue", + tertunda: "red", + proses: "yellow", + }; + // Discussion data const discussions = [ { title: "Pembahasan APBDes 2026", sender: "Kepala Desa", - date: "10 Mar 2025", + timestamp: "2 jam yang lalu", }, { title: "Kegiatan Posyandu", sender: "Divisi Sosial", - date: "9 Mar 2025", + timestamp: "5 jam yang lalu", }, { title: "Festival Budaya", sender: "Divisi Humas", - date: "8 Mar 2025", + timestamp: "1 hari yang lalu", }, ]; + // Today's agenda + const todayAgenda = [ + { time: "09:00", event: "Rapat Evaluasi Bulanan" }, + { time: "14:00", event: "Koordinasi Program Bantuan" }, + ]; + return ( -
- {/* Top Row - 4 Activity Cards */} -
+ {/* Grafik Progres Tugas per Divisi */} + - {activities.map((activity, index) => ( -
- {/* Dark blue title bar */} -
+ Grafik Progres Tugas per Divisi + + + + + + + + + + + + + + + {/* Ringkasan Tugas per Divisi */} + + {divisionTasks.map((division, index) => ( + + -

{activity.title}

-
- - {/* Orange progress bar */} -
-
-
- - {/* Date and badge */} -
- - {activity.date} - - - Selesai - -
-
- ))} -
- - {/* Second Row - Charts */} -
- {/* Left Card - Jumlah Dokumen (Bar Chart) */} -
-

- Jumlah Dokumen -

- - - - - - - - {documentStats.map((entry, index) => ( - + + {division.name} + + + {division.tasks.map((task, taskIndex) => ( + + + + {task.title} + + + {task.status} + + + ))} - - - -
+ + + + ))} + - {/* Right Card - Progres Kegiatan (Pie Chart) */} -
-

- Progres Kegiatan -

- - - item.value > 0)} - cx="50%" - cy="50%" - outerRadius={80} - dataKey="value" - label={({ name, percent }) => - `${name}: ${percent ? (percent * 100).toFixed(0) : 0}%` - } - > - {activityProgressStats - .filter(item => item.value > 0) - .map((entry, index) => ( - - ))} - - - - - - {/* Legend */} -
-
-
- - Segera Dikerjakan - -
-
-
- - Dikerjakan - -
-
-
- - Selesai - -
-
-
- - Dibatalkan - -
-
-
-
- - {/* Bottom Row */} -
- {/* Left Card - Diskusi */} -
-

- Diskusi -

-
- {discussions.map((discussion, index) => ( -
+ Arsip Digital Perangkat Desa + + + {archiveItems.map((item, index) => ( + + -
-
- -
-
-
-

- {discussion.title} -

-

- {discussion.sender} • {discussion.date} -

-
-
- ))} -
-
+ + + {item.name} + + + {item.count} + + + + + ))} + + - {/* Right Card - Acara Hari Ini */} -
-

- Acara Hari Ini -

-
-

+ + Progres Kegiatan / Program + + + {activityProgress.map((activity, index) => ( + - Tidak ada acara hari ini -

-
-
-
-
+ + + {activity.name} + + + {activity.status} + + + + + + {activity.progress}% + + + + {activity.date} + + + ))} + + + + {/* Statistik Dokumen & Progres Kegiatan */} + + + + + Jumlah Dokumen + + + + + + + + + + + + + + + + + Progres Kegiatan + + + + + `${name}: ${percent ? (percent * 100).toFixed(0) : "0"}%` + } + > + {activityProgressStats.map((entry, index) => ( + + ))} + + + + + + + + + {/* Diskusi Internal */} + + + Diskusi Internal + + + {discussions.map((discussion, index) => ( + + + + {discussion.title} + + + {discussion.timestamp} + + + + {discussion.sender} + + + ))} + + + + {/* Agenda / Acara Hari Ini */} + + + Agenda / Acara Hari Ini + + {todayAgenda.length > 0 ? ( + + {todayAgenda.map((agenda, index) => ( + + + {agenda.time} + + + + {agenda.event} + + + ))} + + ) : ( + + Tidak ada acara hari ini + + )} + + ); }; -export default KinerjaDivisi; +export default KinerjaDivisi; \ No newline at end of file diff --git a/src/components/pengaduan-layanan-publik.tsx b/src/components/pengaduan-layanan-publik.tsx index ef3ccab..58787ae 100644 --- a/src/components/pengaduan-layanan-publik.tsx +++ b/src/components/pengaduan-layanan-publik.tsx @@ -1,16 +1,36 @@ import { - IconMessage, + ActionIcon, + Badge, + Box, + Button, + Card, + Divider, + Grid, + GridCol, + Group, + List, + Select, + Stack, + Table, + Text, + Textarea, + TextInput, + Title, + useMantineColorScheme, +} from "@mantine/core"; +import { IconAlertTriangle, - IconClock, IconCheck, IconChevronRight, + IconClock, + IconMessage, } from "@tabler/icons-react"; -import { useMantineColorScheme } from "@mantine/core"; +import type React from "react"; +import { useState } from "react"; import { Bar, BarChart, CartesianGrid, - Cell, Line, LineChart, ResponsiveContainer, @@ -23,463 +43,801 @@ const PengaduanLayananPublik = () => { const { colorScheme } = useMantineColorScheme(); const dark = colorScheme === "dark"; - // Statistic cards data - const statsData = [ + // Summary data + const summaryData = { + total: 42, + baru: 14, + diproses: 14, + selesai: 14, + }; + + // Tren pengaduan data + const trenData = [ + { bulan: "Jan", jumlah: 30 }, + { bulan: "Feb", jumlah: 50 }, + { bulan: "Mar", jumlah: 42 }, + { bulan: "Apr", jumlah: 38 }, + { bulan: "Mei", jumlah: 45 }, + { bulan: "Jun", jumlah: 42 }, + ]; + + // Surat terbanyak data + const suratData = [ + { jenis: "KTP", jumlah: 24 }, + { jenis: "KK", jumlah: 18 }, + { jenis: "Domisili", jumlah: 15 }, + { jenis: "Usaha", jumlah: 12 }, + { jenis: "Lainnya", jumlah: 8 }, + ]; + + // Pengajuan terbaru data + const pengajuanTerbaru = [ { - title: "Total Pengaduan", - value: 156, - subtitle: "+12% dari bulan lalu", - icon: IconMessage, + nama: "Budi Santoso", + jenis: "Ketertiban Umum", + waktu: "2 jam yang lalu", + status: "baru", }, { - title: "Pengaduan Baru", - value: 24, - subtitle: "Perlu tindakan segera", - icon: IconAlertTriangle, + nama: "Siti Rahayu", + jenis: "Pelayanan Kesehatan", + waktu: "5 jam yang lalu", + status: "diproses", }, { - title: "Sedang Diproses", - value: 48, - subtitle: "Dalam penanganan", - icon: IconClock, + nama: "Ahmad Fauzi", + jenis: "Infrastruktur", + waktu: "1 hari yang lalu", + status: "selesai", }, { - title: "Selesai", - value: 84, - subtitle: "92% tingkat kepuasan", - icon: IconCheck, + nama: "Dewi Lestari", + jenis: "Administrasi", + waktu: "1 hari yang lalu", + status: "baru", + }, + { + nama: "Joko Widodo", + jenis: "Keamanan", + waktu: "2 hari yang lalu", + status: "diproses", }, ]; - // Line chart data for complaint trends - const trendData = [ - { month: "Jan", complaints: 32 }, - { month: "Feb", complaints: 45 }, - { month: "Mar", complaints: 38 }, - { month: "Apr", complaints: 52 }, - { month: "Mei", complaints: 48 }, - { month: "Jun", complaints: 61 }, + // Ide inovatif data + const ideInovatif = [ + { + nama: "Andi Prasetyo", + judul: "Penerapan Smart Village", + kategori: "Teknologi", + }, + { + nama: "Rina Kusuma", + judul: "Program Ekowisata Desa", + kategori: "Ekonomi", + }, + { + nama: "Bambang Suryono", + judul: "Peningkatan Sanitasi", + kategori: "Kesehatan", + }, + { + nama: "Lina Marlina", + judul: "Pusat Kreatif Anak Muda", + kategori: "Pendidikan", + }, ]; - // Horizontal bar chart data for most requested documents - const documentData = [ - { name: "KTP", count: 145 }, - { name: "Kartu Keluarga", count: 128 }, - { name: "Surat Domisili", count: 96 }, - { name: "Surat Usaha", count: 74 }, - { name: "SKCK", count: 52 }, - ]; + const [activeTab, setActiveTab] = useState<"complaints" | "services">( + "complaints", + ); + const [newComplaint, setNewComplaint] = useState({ + title: "", + category: "", + description: "", + }); - // Recent applications data - const recentApplications = [ + // Sample data for complaints + const complaints = [ { id: 1, - name: "Budi Santoso", - type: "KTP Elektronik", - date: "10 Mar 2025", - status: "Selesai", - statusBg: "bg-darmasaba-success-100", - statusText: "text-darmasaba-success-800", + title: "Jalan Rusak di Jalan Raya", + category: "Infrastruktur", + status: "Pending", + priority: "High", + date: "2024-02-01", + reporter: "Bapak Ahmad", }, { id: 2, - name: "Siti Aminah", - type: "Surat Domisili", - date: "10 Mar 2025", - status: "Diproses", - statusBg: "bg-darmasaba-warning-100", - statusText: "text-darmasaba-warning-800", + title: "Pemadaman Listrik Berkelanjutan", + category: "Utilitas", + status: "In Progress", + priority: "Medium", + date: "2024-02-03", + reporter: "Ibu Sari", }, { id: 3, - name: "Ahmad Fauzi", - type: "Kartu Keluarga", - date: "9 Mar 2025", - status: "Baru", - statusBg: "bg-darmasaba-blue-100", - statusText: "text-darmasaba-blue-800", - }, - { - id: 4, - name: "Dewi Lestari", - type: "Surat Usaha", - date: "9 Mar 2025", - status: "Selesai", - statusBg: "bg-darmasaba-success-100", - statusText: "text-darmasaba-success-800", - }, - { - id: 5, - name: "Joko Widodo", - type: "SKCK", - date: "8 Mar 2025", - status: "Diproses", - statusBg: "bg-darmasaba-warning-100", - statusText: "text-darmasaba-warning-800", - }, - ]; - - // Innovation ideas data - const innovationIdeas = [ - { - id: 1, - title: "Sistem Antrian Online", - submitter: "Andi Prasetyo", - category: "Teknologi", - }, - { - id: 2, - title: "Layanan Jemput Dokumen", - submitter: "Rina Kusuma", - category: "Pelayanan", - }, - { - id: 3, - title: "Digitalisasi Arsip Desa", - submitter: "Bambang Suryono", + title: "Pelayanan Administrasi Lambat", category: "Administrasi", + status: "Resolved", + priority: "Low", + date: "2024-01-28", + reporter: "Pak Joko", }, { id: 4, - title: "Aplikasi Pengaduan Mobile", - submitter: "Lina Marlina", - category: "Teknologi", + title: "Kebersihan Lingkungan", + category: "Sanitasi", + status: "Pending", + priority: "Medium", + date: "2024-02-05", + reporter: "Bu Dewi", }, ]; - const COLORS = ["#1E3A5F", "#3B82F6", "#60A5FA", "#93C5FD", "#DBEAFE"]; + // Sample data for public services + const services = [ + { + id: 1, + name: "Pembuatan KTP", + description: + "Pelayanan pembuatan Kartu Tanda Penduduk baru atau perpanjangan", + status: "Available", + category: "Administrasi", + lastUpdated: "2024-02-01", + }, + { + id: 2, + name: "Pembuatan Surat Keterangan Usaha", + description: "Surat keterangan untuk keperluan usaha atau perizinan", + status: "Available", + category: "Administrasi", + lastUpdated: "2024-02-02", + }, + { + id: 3, + name: "Pelayanan Kesehatan", + description: "Pelayanan kesehatan dasar di puskesmas desa", + status: "Available", + category: "Kesehatan", + lastUpdated: "2024-01-30", + }, + { + id: 4, + name: "Program Bantuan Sosial", + description: + "Informasi dan pendaftaran program bantuan sosial dari pemerintah", + status: "Limited", + category: "Sosial", + lastUpdated: "2024-02-04", + }, + ]; - const cardStyle = { - backgroundColor: dark ? "#141D34" : "white", - border: `1px solid ${dark ? "#141D34" : "white"}`, + const handleInputChange = ( + e: React.ChangeEvent, + ) => { + const { name, value } = e.target; + setNewComplaint((prev) => ({ + ...prev, + [name]: value, + })); }; - const textStyle = { - color: dark ? "white" : "#1F2937", + const handleSelectChange = (value: string | null) => { + setNewComplaint((prev) => ({ + ...prev, + category: value || "", // Ensure category is always a string + })); }; - const subtitleStyle = { - color: dark ? "#9CA3AF" : "#6B7280", + const handleSubmitComplaint = (e: React.FormEvent) => { + e.preventDefault(); + console.log("Submitting complaint:", newComplaint); + // Here you would typically send the complaint to your backend + alert("Pengaduan berhasil dikirim!"); + setNewComplaint({ title: "", category: "", description: "" }); + }; + + // Render complaint table rows + const complaintRows = complaints.map((complaint) => ( + + + {complaint.title} + + + {complaint.category} + + + + {complaint.status} + + + + + {complaint.priority} + + + + {complaint.date} + + + )); + + // Status badge color mapping + const getStatusColor = (status: string) => { + switch (status) { + case "baru": + return "red"; + case "diproses": + return "yellow"; + case "selesai": + return "green"; + default: + return "gray"; + } }; return ( -
-
- {/* Row 1: 4 Statistic Cards */} -
- {statsData.map((stat, index) => ( -
-
-
-

+ {activeTab === "complaints" ? ( + <> + {/* Summary Cards */} + + + + + + + Total Pengaduan + + + {summaryData.total} + + + - {stat.title} -

-

- {stat.value} -

-

- {stat.subtitle} -

-
-
-
- -
-
-
-
- ))} -
+ + + + + - {/* Row 2: Full Width Line Chart */} -
-

- Tren Pengaduan Warga -

- - - - - - - - - -
+ + + + + + Baru + + + {summaryData.baru} + + + + + + + + - {/* Row 3: 3 Column Grid */} -
- {/* Left: Most Requested Documents (Horizontal Bar Chart) */} -
+ + + + + Diproses + + + {summaryData.diproses} + + + + + + + + + + + + + + + Selesai + + + {summaryData.selesai} + + + + + + + + + + + {/* Grafik Tren Pengaduan */} + -

- Dokumen Paling Banyak Diminta -

- - + + Grafik Tren Pengaduan + + + - - {documentData.map((entry, index) => ( - - ))} - - + + -
+ - {/* Middle: Recent Applications */} -
-

- Pengajuan Terbaru -

-
- {recentApplications.map((app) => ( -
-
-

- {app.name} -

-

- {app.type} -

-
-
- - {app.status} - -

- {app.date} -

-
-
- ))} -
-
+ {/* Surat Terbanyak & Pengajuan Terbaru & Ide Inovatif */} + + {/* Surat Terbanyak */} + + + + Surat Terbanyak + + + + + + + + + + + + - {/* Right: Innovation Ideas */} -
-

- Ide Inovatif Warga -

-
- {innovationIdeas.map((idea) => ( -
-
-
-

- {idea.title} -

-

- {idea.submitter} -

-
-
- - {idea.category} - - -
-
-
- ))} -
-
-
-
-
+ {/* Pengajuan Terbaru */} + + + + Pengajuan Terbaru + + {pengajuanTerbaru.map((item, index) => ( + + + + + {item.nama} + + + {item.jenis} + + + + + {item.status} + + + {item.waktu} + + + + + + ))} + + + + {/* Ajuan Ide Inovatif */} + + + + Ajuan Ide Inovatif + + {ideInovatif.map((item, index) => ( + + + + + {item.judul} + + + {item.nama} + + + + + {item.kategori} + + + + + + + + + ))} + + + + + {/* Complaint Submission Form and List */} + + {/* Complaint Submission Form */} + + + + + Ajukan Pengaduan + + + +
+ + + +