From 158a2db4359b6204a308c36c6402a5ece309501a Mon Sep 17 00:00:00 2001 From: nico Date: Tue, 17 Mar 2026 21:41:03 +0700 Subject: [PATCH] Fix New UI Pengaduan --- Pengaduan-New.md | 168 +++ src/components/pengaduan-layanan-publik.tsx | 1150 ++++++------------- 2 files changed, 537 insertions(+), 781 deletions(-) create mode 100644 Pengaduan-New.md diff --git a/Pengaduan-New.md b/Pengaduan-New.md new file mode 100644 index 0000000..5340e0a --- /dev/null +++ b/Pengaduan-New.md @@ -0,0 +1,168 @@ +Create a modern analytics dashboard UI for a village complaint system (Pengaduan Dashboard). + +Tech stack: +- React 19 + Vite (Bun runtime) +- Mantine UI (core components) +- TailwindCSS (layout & spacing only) +- Recharts (charts) +- TanStack Router +- Icons: lucide-react +- State: Valtio +- Date: dayjs + +--- + +## 🎨 DESIGN STYLE + +- Clean, minimal, and soft dashboard +- Background: light gray (#f3f4f6) +- Card: white with subtle shadow +- Border radius: 16px–24px (rounded-2xl) +- Typography: medium contrast (not too bold) +- Primary color: navy blue (#1E3A5F) +- Accent: soft blue + neutral gray +- Icons inside circular solid background + +Spacing: +- Use gap-6 consistently +- Internal padding: p-5 or p-6 +- Layout must feel breathable (no clutter) + +--- + +## 🧱 LAYOUT STRUCTURE + +### 🔹 TOP SECTION (4 STAT CARDS - GRID) +Grid: 4 columns (responsive → 2 / 1) + +Each card contains: +- Title (small, muted) +- Big number (bold, large) +- Subtitle (small gray text) +- Right side: circular icon container + +Example: +- Total Pengaduan → 42 → "Bulan ini" +- Baru → 14 → "Belum diproses" +- Diproses → 14 → "Sedang ditangani" +- Selesai → 14 → "Terselesaikan" + +Use: +- Mantine Card +- Group justify="space-between" +- Icon inside circle (bg navy, icon white) + +--- + +## 📈 MAIN CHART (FULL WIDTH) +Title: "Tren Pengaduan" + +- Use Recharts LineChart +- Smooth line (monotone) +- Show dots on each point +- Data: Apr → Okt +- Value range: 30–60 + +Style: +- Minimal grid (light dashed) +- No heavy colors (use gray/blue line) +- Rounded container card +- Add small top-right icon (expand) + +--- + +## 📊 BOTTOM SECTION (3 COLUMN GRID) + +### 🔹 LEFT: "Surat Terbanyak" +- Horizontal bar chart (Recharts) +- Categories: + - KTP + - KK + - Domisili + - Usaha + - Lainnya + +Style: +- Dark blue bars +- Rounded edges +- Clean axis + +--- + +### 🔹 CENTER: "Pengajuan Terbaru" +List of activity cards: + +Each item: +- Name (bold) +- Subtitle (jenis surat) +- Time (small text) +- Status badge (kanan) + +Status: +- baru → red +- proses → blue +- selesai → green + +Style: +- Card per item +- Soft border +- Rounded +- Compact spacing + +--- + +### 🔹 RIGHT: "Ajuan Ide Inovatif" +List mirip dengan pengajuan terbaru: + +Each item: +- Nama +- Judul ide +- Waktu +- Button kecil "Detail" + +Style: +- Right-aligned action button +- Light border +- Clean spacing + +--- + +## ⚙️ COMPONENT STRUCTURE + +components/ +- StatCard.tsx +- LineChartCard.tsx +- BarChartCard.tsx +- ActivityList.tsx +- IdeaList.tsx + +routes/ +- dashboard.tsx + +--- + +## ✨ INTERACTIONS (IMPORTANT) + +- Hover card → scale(1.02) +- Transition: 150ms ease +- Icon circle slightly pop on hover +- List item hover → subtle bg change + +--- + +## 🎯 UX DETAILS + +- Numbers must be visually dominant +- Icons must balance layout (not too big) +- Avoid heavy borders +- Keep everything aligned perfectly +- No clutter + +--- + +## 🚀 OUTPUT + +- Modular React components (NOT one file) +- Clean code (production-ready) +- Use Mantine properly (no hacky inline styles unless needed) +- Use Tailwind only for layout/grid/spacing \ No newline at end of file diff --git a/src/components/pengaduan-layanan-publik.tsx b/src/components/pengaduan-layanan-publik.tsx index cafff0d..21a4173 100644 --- a/src/components/pengaduan-layanan-publik.tsx +++ b/src/components/pengaduan-layanan-publik.tsx @@ -1,32 +1,16 @@ import { - ActionIcon, Badge, - Box, Button, Card, - Divider, Grid, - GridCol, Group, - List, - Select, Stack, - Table, Text, - Textarea, - TextInput, + ThemeIcon, Title, - useMantineColorScheme, + useMantineColorScheme } from "@mantine/core"; -import { - IconAlertTriangle, - IconCheck, - IconChevronRight, - IconClock, - IconMessage, -} from "@tabler/icons-react"; -import type React from "react"; -import { useState } from "react"; +import { CheckCircle, Clock, FileText, MessageCircle } from "lucide-react"; import { Bar, BarChart, @@ -39,803 +23,407 @@ import { YAxis, } from "recharts"; +// Summary data +const summaryData = [ + { + title: "Total Pengaduan", + value: 42, + subtitle: "Bulan ini", + icon: MessageCircle, + color: "#1E3A5F", + }, + { + title: "Baru", + value: 14, + subtitle: "Belum diproses", + icon: FileText, + color: "#1E3A5F", + }, + { + title: "Diproses", + value: 14, + subtitle: "Sedang ditangani", + icon: Clock, + color: "#1E3A5F", + }, + { + title: "Selesai", + value: 14, + subtitle: "Terselesaikan", + icon: CheckCircle, + color: "#1E3A5F", + }, +]; + +// Tren pengaduan data +const trenData = [ + { bulan: "Apr", jumlah: 35 }, + { bulan: "Mei", jumlah: 48 }, + { bulan: "Jun", jumlah: 42 }, + { bulan: "Jul", jumlah: 55 }, + { bulan: "Agu", jumlah: 50 }, + { bulan: "Sep", jumlah: 58 }, + { bulan: "Okt", jumlah: 52 }, +]; + +// 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 = [ + { + nama: "Budi Santoso", + jenis: "Ketertiban Umum", + waktu: "2 jam yang lalu", + status: "baru", + }, + { + nama: "Siti Rahayu", + jenis: "Pelayanan Kesehatan", + waktu: "5 jam yang lalu", + status: "proses", + }, + { + nama: "Ahmad Fauzi", + jenis: "Infrastruktur", + waktu: "1 hari yang lalu", + status: "selesai", + }, + { + nama: "Dewi Lestari", + jenis: "Administrasi", + waktu: "1 hari yang lalu", + status: "baru", + }, + { + nama: "Joko Widodo", + jenis: "Keamanan", + waktu: "2 hari yang lalu", + status: "proses", + }, +]; + +// Ide inovatif data +const ideInovatif = [ + { + nama: "Andi Prasetyo", + judul: "Penerapan Smart Village", + waktu: "3 hari yang lalu", + kategori: "Teknologi", + }, + { + nama: "Rina Kusuma", + judul: "Program Ekowisata Desa", + waktu: "5 hari yang lalu", + kategori: "Ekonomi", + }, + { + nama: "Bambang Suryono", + judul: "Peningkatan Sanitasi", + waktu: "1 minggu yang lalu", + kategori: "Kesehatan", + }, + { + nama: "Lina Marlina", + judul: "Pusat Kreatif Anak Muda", + waktu: "2 minggu yang lalu", + kategori: "Pendidikan", + }, +]; + +const getStatusColor = (status: string) => { + switch (status) { + case "baru": + return "red"; + case "proses": + return "blue"; + case "selesai": + return "green"; + default: + return "gray"; + } +}; + const PengaduanLayananPublik = () => { const { colorScheme } = useMantineColorScheme(); const dark = colorScheme === "dark"; - // 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 = [ - { - nama: "Budi Santoso", - jenis: "Ketertiban Umum", - waktu: "2 jam yang lalu", - status: "baru", - }, - { - nama: "Siti Rahayu", - jenis: "Pelayanan Kesehatan", - waktu: "5 jam yang lalu", - status: "diproses", - }, - { - nama: "Ahmad Fauzi", - jenis: "Infrastruktur", - waktu: "1 hari yang lalu", - status: "selesai", - }, - { - nama: "Dewi Lestari", - jenis: "Administrasi", - waktu: "1 hari yang lalu", - status: "baru", - }, - { - nama: "Joko Widodo", - jenis: "Keamanan", - waktu: "2 hari yang lalu", - status: "diproses", - }, - ]; - - // 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", - }, - ]; - - const [activeTab, setActiveTab] = useState<"complaints" | "services">( - "complaints", - ); - const [newComplaint, setNewComplaint] = useState({ - title: "", - category: "", - description: "", - }); - - // Sample data for complaints - const complaints = [ - { - id: 1, - title: "Jalan Rusak di Jalan Raya", - category: "Infrastruktur", - status: "Pending", - priority: "High", - date: "2024-02-01", - reporter: "Bapak Ahmad", - }, - { - id: 2, - title: "Pemadaman Listrik Berkelanjutan", - category: "Utilitas", - status: "In Progress", - priority: "Medium", - date: "2024-02-03", - reporter: "Ibu Sari", - }, - { - id: 3, - title: "Pelayanan Administrasi Lambat", - category: "Administrasi", - status: "Resolved", - priority: "Low", - date: "2024-01-28", - reporter: "Pak Joko", - }, - { - id: 4, - title: "Kebersihan Lingkungan", - category: "Sanitasi", - status: "Pending", - priority: "Medium", - date: "2024-02-05", - reporter: "Bu Dewi", - }, - ]; - - // 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 handleInputChange = ( - e: React.ChangeEvent, - ) => { - const { name, value } = e.target; - setNewComplaint((prev) => ({ - ...prev, - [name]: value, - })); - }; - - const handleSelectChange = (value: string | null) => { - setNewComplaint((prev) => ({ - ...prev, - category: value || "", // Ensure category is always a string - })); - }; - - 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 ( - {activeTab === "complaints" ? ( - <> - {/* Summary Cards */} - - - - - - - Total Pengaduan - - - {summaryData.total} - - - - - - - - + {/* TOP SECTION - 4 STAT CARDS */} + + {summaryData.map((item, index) => ( + + + + + + {item.title} + + + {item.value} + + + {item.subtitle} + + + + + + + + + ))} + - - - - - - Baru - - - {summaryData.baru} - - - - - - - - + {/* MAIN CHART - TREN PENGADUAN */} + + + + Tren Pengaduan + + + + + + + + + + + + - - - - - - Diproses - - - {summaryData.diproses} - - - - - - - - - - - - - - - Selesai - - - {summaryData.selesai} - - - - - - - - - - - {/* Grafik Tren Pengaduan */} + {/* BOTTOM SECTION - 3 COLUMNS */} + + {/* LEFT: SURAT TERBANYAK */} + - - Grafik Tren Pengaduan + <Title order={4} c={dark ? "white" : "gray.9"} mb="md"> + Surat Terbanyak - - + + - - + + + - {/* Surat Terbanyak & Pengajuan Terbaru & Ide Inovatif */} - - {/* Surat Terbanyak */} - - - - Surat Terbanyak - - - - - - - - - - - - - - {/* 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 - - - -
- - - -