diff --git a/src/components/dashboard/stat-card.tsx b/src/components/dashboard/stat-card.tsx index 25de1d5..5c8a711 100644 --- a/src/components/dashboard/stat-card.tsx +++ b/src/components/dashboard/stat-card.tsx @@ -25,7 +25,7 @@ export function StatCard({ trend, trendValue, icon, - iconColor = "darmasaba-blue", + iconColor = "#1E3A5F", }: StatCardProps) { const { colorScheme } = useMantineColorScheme(); const dark = colorScheme === "dark"; @@ -77,6 +77,7 @@ export function StatCard({ size="xl" radius="xl" color={dark ? "gray" : iconColor} + bg={dark ? "gray" : iconColor} > {icon} diff --git a/src/components/help-page.tsx b/src/components/help-page.tsx index 1450a18..b7e6fe6 100644 --- a/src/components/help-page.tsx +++ b/src/components/help-page.tsx @@ -181,7 +181,7 @@ const HelpPage = () => { } + icon={} title="Panduan Memulai" h="100%" > @@ -211,7 +211,7 @@ const HelpPage = () => { } + icon={} title="Video Tutorial" h="100%" > @@ -241,7 +241,7 @@ const HelpPage = () => { } + icon={} title="FAQ" h="100%" > @@ -273,7 +273,7 @@ const HelpPage = () => { } + icon={} title="Hubungi Support" h="100%" > @@ -308,7 +308,7 @@ const HelpPage = () => { } + icon={} title="Dokumentasi" h="100%" > @@ -340,7 +340,7 @@ const HelpPage = () => { } + icon={} title="Jenna - Virtual Assistant" h="100%" > diff --git a/src/components/keamanan-page.tsx b/src/components/keamanan-page.tsx index b1dd262..8937a27 100644 --- a/src/components/keamanan-page.tsx +++ b/src/components/keamanan-page.tsx @@ -125,10 +125,51 @@ const KeamananPage = () => { - {/* KPI Cards */} + + - {kpiData.map((kpi, index) => ( - + {/* Peta Keamanan CCTV */} + + + {/* KPI Cards */} + + {kpiData.map((kpi, index) => ( + + + + + + {kpi.subtitle} + + + + {kpi.value} + + + {kpi.title} + + + + + {kpi.icon} + + + + + ))} + { style={{ borderColor: dark ? "#141D34" : "white" }} h="100%" > - - - - {kpi.subtitle} - - - - {kpi.value} - - - {kpi.title} - - - - - {kpi.icon} - - - - - ))} - - - - {/* Peta Keamanan CCTV */} - - - - Peta Keamanan CCTV - - - Titik Lokasi CCTV - - - {/* Placeholder for map */} - - - - Peta Lokasi CCTV - - Integrasi dengan Google Maps atau Mapbox akan ditampilkan di - sini - - - - - {/* CCTV Locations List */} - - - Daftar CCTV + <Title order={3} mb="md" c={dark ? "dark.0" : "black"}> + Peta Keamanan CCTV - {cctvLocations.map((cctv, index) => ( - - - - - - {cctv.id} + + Titik Lokasi CCTV + + + {/* Placeholder for map */} + + + + Peta Lokasi CCTV + + Integrasi dengan Google Maps atau Mapbox akan ditampilkan di + sini + + + + + {/* CCTV Locations List */} + + + Daftar CCTV + + {cctvLocations.map((cctv, index) => ( + + + + + + {cctv.id} + + + {cctv.status === "active" ? "Online" : "Offline"} + + + + {cctv.location} + + + + + + {cctv.lastSeen} - - {cctv.status === "active" ? "Online" : "Offline"} - - - {cctv.location} - - - - - - {cctv.lastSeen} - - - - ))} - - + + ))} + + + {/* Daftar Laporan Keamanan */} diff --git a/src/components/sosial-page.tsx b/src/components/sosial-page.tsx index c313fac..24c2fd6 100644 --- a/src/components/sosial-page.tsx +++ b/src/components/sosial-page.tsx @@ -1,463 +1,45 @@ -import { - Badge, - Card, - Grid, - GridCol, - Group, - List, - Progress, - Stack, - Text, - ThemeIcon, - Title, - useMantineColorScheme, -} from "@mantine/core"; -import { - IconAward, - IconBabyCarriage, - IconBook, - IconCalendarEvent, - IconHeartbeat, - IconMedicalCross, - IconSchool, - IconStethoscope, -} from "@tabler/icons-react"; -import { useState } from "react"; +import { Grid, GridCol, Stack } from "@mantine/core"; +import { SummaryCards } from "./sosial/summary-cards"; +import { HealthStats } from "./sosial/health-stats"; +import { PosyanduSchedule } from "./sosial/posyandu-schedule"; +import { Pendidikan } from "./sosial/pendidikan"; +import { Beasiswa } from "./sosial/beasiswa"; +import { EventCalendar } from "./sosial/event-calendar"; const SosialPage = () => { - const { colorScheme } = useMantineColorScheme(); - const dark = colorScheme === "dark"; - - // Sample data for health statistics - const healthStats = { - ibuHamil: 87, - balita: 342, - alertStunting: 12, - posyanduAktif: 8, - }; - - // Sample data for health progress - const healthProgress = [ - { label: "Imunisasi Lengkap", value: 92, color: "green" }, - { label: "Pemeriksaan Rutin", value: 88, color: "blue" }, - { label: "Gizi Baik", value: 86, color: "teal" }, - { label: "Target Stunting", value: 14, color: "red" }, - ]; - - // Sample data for posyandu schedule - const posyanduSchedule = [ - { - nama: "Posyandu Mawar", - tanggal: "Senin, 15 Feb 2026", - jam: "08:00 - 11:00", - }, - { - nama: "Posyandu Melati", - tanggal: "Selasa, 16 Feb 2026", - jam: "08:00 - 11:00", - }, - { - nama: "Posyandu Dahlia", - tanggal: "Rabu, 17 Feb 2026", - jam: "08:00 - 11:00", - }, - { - nama: "Posyandu Anggrek", - tanggal: "Kamis, 18 Feb 2026", - jam: "08:00 - 11:00", - }, - ]; - - // Sample data for education stats - const educationStats = { - siswa: { - tk: 125, - sd: 480, - smp: 210, - sma: 150, - }, - sekolah: { - jumlah: 8, - guru: 42, - }, - }; - - // Sample data for scholarships - const scholarshipData = { - penerima: 45, - dana: "Rp 1.200.000.000", - tahunAjaran: "2025/2026", - }; - - // Sample data for cultural events - const culturalEvents = [ - { - nama: "Hari Kesaktian Pancasila", - tanggal: "1 Oktober 2025", - lokasi: "Balai Desa", - }, - { - nama: "Festival Budaya Desa", - tanggal: "20 Mei 2026", - lokasi: "Lapangan Desa", - }, - { - nama: "Perayaan HUT Desa", - tanggal: "17 Agustus 2026", - lokasi: "Balai Desa", - }, - ]; - return ( - {/* Health Statistics Cards */} + {/* Top Summary Cards - 4 Grid */} + + + {/* Second Row - 2 Column Grid */} - - - - - - Ibu Hamil Aktif - - - {healthStats.ibuHamil} - - - - - - - + {/* Left - Statistik Kesehatan */} + + - - - - - - Balita Terdaftar - - - {healthStats.balita} - - - - - - - - - - - - - - - Alert Stunting - - - {healthStats.alertStunting} - - - - - - - - - - - - - - - Posyandu Aktif - - - {healthStats.posyanduAktif} - - - - - - - + {/* Right - Jadwal Posyandu */} + + - {/* Health Progress Bars */} - - - Statistik Kesehatan - - - {healthProgress.map((item, index) => ( -
- - - {item.label} - - - {item.value}% - - - -
- ))} -
-
- + {/* Third Row - 2 Column Grid */} - {/* Jadwal Posyandu */} + {/* Left - Pendidikan */} - - - Jadwal Posyandu - - - {posyanduSchedule.map((item, index) => ( - - - - - {item.nama} - - - {item.tanggal} - - - - {item.jam} - - - - ))} - - + - {/* Pendidikan */} + {/* Right - Beasiswa Desa */} - - - Pendidikan - - - - - TK / PAUD - - - {educationStats.siswa.tk} - - - - - SD - - - {educationStats.siswa.sd} - - - - - SMP - - - {educationStats.siswa.smp} - - - - - SMA - - - {educationStats.siswa.sma} - - - - - - - Jumlah Lembaga Pendidikan - - - {educationStats.sekolah.jumlah} - - - - - Jumlah Tenaga Pengajar - - - {educationStats.sekolah.guru} - - - - - + - - {/* Beasiswa Desa */} - - - - - - Beasiswa Desa - - - Penerima: {scholarshipData.penerima} - - - - - - - - Dana Tersalurkan:{" "} - - {scholarshipData.dana} - - - - Tahun Ajaran: {scholarshipData.tahunAjaran} - - - - - {/* Kalender Event Budaya */} - - - - Kalender Event Budaya - - - {culturalEvents.map((event, index) => ( - - - - } - > - - - {event.nama} - - - {event.lokasi} - - - - {event.tanggal} - - - ))} - - - - + {/* Bottom Section - Event Budaya */} +
); }; diff --git a/src/components/sosial/beasiswa.tsx b/src/components/sosial/beasiswa.tsx new file mode 100644 index 0000000..79ab93c --- /dev/null +++ b/src/components/sosial/beasiswa.tsx @@ -0,0 +1,69 @@ +import { Card, Group, Stack, Text, ThemeIcon, Title } from "@mantine/core"; +import { useMantineColorScheme } from "@mantine/core"; +import { IconAward } from "@tabler/icons-react"; + +interface ScholarshipData { + penerima: number; + dana: string; + tahunAjaran: string; +} + +interface BeasiswaProps { + data?: ScholarshipData; +} + +export const Beasiswa = ({ data }: BeasiswaProps) => { + const { colorScheme } = useMantineColorScheme(); + const dark = colorScheme === "dark"; + + const defaultData: ScholarshipData = { + penerima: 45, + dana: "Rp 1.200.000.000", + tahunAjaran: "2025/2026", + }; + + const displayData = data || defaultData; + + return ( + + + + + Beasiswa Desa + + + Penerima: {displayData.penerima} + + + + + + + + + Dana Tersalurkan: + + {displayData.dana} + + + + Tahun Ajaran: + {displayData.tahunAjaran} + + + + ); +}; diff --git a/src/components/sosial/event-calendar.tsx b/src/components/sosial/event-calendar.tsx new file mode 100644 index 0000000..92d72ee --- /dev/null +++ b/src/components/sosial/event-calendar.tsx @@ -0,0 +1,94 @@ +import { Card, Group, Stack, Text, Title, ThemeIcon } from "@mantine/core"; +import { useMantineColorScheme } from "@mantine/core"; +import { IconCalendarEvent } from "@tabler/icons-react"; + +interface EventItem { + id: string; + nama: string; + tanggal: string; + lokasi: string; +} + +interface EventCalendarProps { + data?: EventItem[]; +} + +export const EventCalendar = ({ data }: EventCalendarProps) => { + const { colorScheme } = useMantineColorScheme(); + const dark = colorScheme === "dark"; + + const defaultData: EventItem[] = [ + { + id: "1", + nama: "Hari Kesaktian Pancasila", + tanggal: "1 Oktober 2025", + lokasi: "Balai Desa", + }, + { + id: "2", + nama: "Festival Budaya Desa", + tanggal: "20 Mei 2026", + lokasi: "Lapangan Desa", + }, + { + id: "3", + nama: "Perayaan HUT Desa", + tanggal: "17 Agustus 2026", + lokasi: "Balai Desa", + }, + ]; + + const displayData = data || defaultData; + + return ( + + + Kalender Event Budaya + + + {displayData.map((event) => ( + + + + + + + + {event.nama} + + + + {event.lokasi} + + + + + {event.tanggal} + + + + ))} + + + ); +}; diff --git a/src/components/sosial/health-stats.tsx b/src/components/sosial/health-stats.tsx new file mode 100644 index 0000000..8dca29d --- /dev/null +++ b/src/components/sosial/health-stats.tsx @@ -0,0 +1,66 @@ +import { Card, Group, Progress, Stack, Text, Title } from "@mantine/core"; +import { useMantineColorScheme } from "@mantine/core"; + +interface HealthProgressItem { + label: string; + value: number; + color: string; +} + +interface HealthStatsProps { + data?: HealthProgressItem[]; +} + +export const HealthStats = ({ data }: HealthStatsProps) => { + const { colorScheme } = useMantineColorScheme(); + const dark = colorScheme === "dark"; + + const defaultData: HealthProgressItem[] = [ + { label: "Imunisasi Lengkap", value: 92, color: "green" }, + { label: "Pemeriksaan Rutin", value: 88, color: "blue" }, + { label: "Gizi Baik", value: 86, color: "teal" }, + { label: "Target Stunting", value: 14, color: "red" }, + ]; + + const displayData = data || defaultData; + + return ( + + + Statistik Kesehatan + + + {displayData.map((item, index) => ( +
+ + + {item.label} + + + {item.value}% + + + +
+ ))} +
+
+ ); +}; diff --git a/src/components/sosial/pendidikan.tsx b/src/components/sosial/pendidikan.tsx new file mode 100644 index 0000000..b3afc60 --- /dev/null +++ b/src/components/sosial/pendidikan.tsx @@ -0,0 +1,114 @@ +import { Card, Group, Stack, Text, Title } from "@mantine/core"; +import { useMantineColorScheme } from "@mantine/core"; + +interface EducationData { + siswa: { + tk: number; + sd: number; + smp: number; + sma: number; + }; + sekolah: { + jumlah: number; + guru: number; + }; +} + +interface PendidikanProps { + data?: EducationData; +} + +export const Pendidikan = ({ data }: PendidikanProps) => { + const { colorScheme } = useMantineColorScheme(); + const dark = colorScheme === "dark"; + + const defaultData: EducationData = { + siswa: { + tk: 125, + sd: 480, + smp: 210, + sma: 150, + }, + sekolah: { + jumlah: 8, + guru: 42, + }, + }; + + const displayData = data || defaultData; + + return ( + + + Pendidikan + + + + + TK / PAUD + + + {displayData.siswa.tk} + + + + + SD + + + {displayData.siswa.sd} + + + + + SMP + + + {displayData.siswa.smp} + + + + + SMA + + + {displayData.siswa.sma} + + + + + + + Jumlah Lembaga Pendidikan + + + {displayData.sekolah.jumlah} + + + + + Jumlah Tenaga Pengajar + + + {displayData.sekolah.guru} + + + + + + ); +}; diff --git a/src/components/sosial/posyandu-schedule.tsx b/src/components/sosial/posyandu-schedule.tsx new file mode 100644 index 0000000..e180c4d --- /dev/null +++ b/src/components/sosial/posyandu-schedule.tsx @@ -0,0 +1,89 @@ +import { Badge, Card, Group, Stack, Text, Title } from "@mantine/core"; +import { useMantineColorScheme } from "@mantine/core"; + +interface PosyanduItem { + id: string; + nama: string; + tanggal: string; + jam: string; +} + +interface PosyanduScheduleProps { + data?: PosyanduItem[]; +} + +export const PosyanduSchedule = ({ data }: PosyanduScheduleProps) => { + const { colorScheme } = useMantineColorScheme(); + const dark = colorScheme === "dark"; + + const defaultData: PosyanduItem[] = [ + { + id: "1", + nama: "Posyandu Mawar", + tanggal: "Senin, 15 Feb 2026", + jam: "08:00 - 11:00", + }, + { + id: "2", + nama: "Posyandu Melati", + tanggal: "Selasa, 16 Feb 2026", + jam: "08:00 - 11:00", + }, + { + id: "3", + nama: "Posyandu Dahlia", + tanggal: "Rabu, 17 Feb 2026", + jam: "08:00 - 11:00", + }, + { + id: "4", + nama: "Posyandu Anggrek", + tanggal: "Kamis, 18 Feb 2026", + jam: "08:00 - 11:00", + }, + ]; + + const displayData = data || defaultData; + + return ( + + + Jadwal Posyandu + + + {displayData.map((item) => ( + + + + + {item.nama} + + + {item.tanggal} + + + + {item.jam} + + + + ))} + + + ); +}; diff --git a/src/components/sosial/summary-cards.tsx b/src/components/sosial/summary-cards.tsx new file mode 100644 index 0000000..1268969 --- /dev/null +++ b/src/components/sosial/summary-cards.tsx @@ -0,0 +1,132 @@ +import { Card, Grid, GridCol, Group, Stack, Text, ThemeIcon } from "@mantine/core"; +import { useMantineColorScheme } from "@mantine/core"; +import { + IconBabyCarriage, + IconHeartbeat, + IconMedicalCross, + IconStethoscope, +} from "@tabler/icons-react"; + +interface SummaryCardProps { + title: string; + value: number; + subtitle?: string; + icon: React.ReactNode; + color: string; + highlight?: boolean; + backgroundColor: string; +} + +const SummaryCard = ({ + title, + value, + subtitle, + icon, + color, + highlight = false, + backgroundColor, +}: SummaryCardProps) => { + const { colorScheme } = useMantineColorScheme(); + const dark = colorScheme === "dark"; + + return ( + + + + + {title} + + + {value} + + {subtitle && ( + + {subtitle} + + )} + + + {icon} + + + + ); +}; + +interface HealthSummaryData { + ibuHamil: number; + balita: number; + alertStunting: number; + posyanduAktif: number; +} + +interface SummaryCardsProps { + data?: HealthSummaryData; +} + +export const SummaryCards = ({ data }: SummaryCardsProps) => { + const defaultData: HealthSummaryData = { + ibuHamil: 87, + balita: 342, + alertStunting: 12, + posyanduAktif: 8, + }; + + const displayData = data || defaultData; + + return ( + + + } + color= "white" + backgroundColor= "#1E3A5F" + /> + + + } + color= "white" + backgroundColor= "#1E3A5F" + /> + + + } + color= "white" + backgroundColor= "#1E3A5F" + /> + + + } + color= "white" + backgroundColor= "#1E3A5F" + /> + + + ); +}; diff --git a/src/components/ui/help-card.tsx b/src/components/ui/help-card.tsx index 08f2448..30f1351 100644 --- a/src/components/ui/help-card.tsx +++ b/src/components/ui/help-card.tsx @@ -52,8 +52,8 @@ export const HelpCard = ({
({ + selectedYear: new Date().getFullYear().toString(), + filters: { + dusun: null, + kategori: null, + }, +}); + +export const setYear = (year: SelectedYear) => { + sosialStore.selectedYear = year; +}; + +export const setFilter = ( + key: keyof SosialState["filters"], + value: string | null, +) => { + sosialStore.filters[key] = value; +};