diff --git a/src/app/admin/(dashboard)/ekonomi/program-kemiskinan/[id]/edit/page.tsx b/src/app/admin/(dashboard)/ekonomi/program-kemiskinan/[id]/edit/page.tsx
index f80b293c..6dbb6b03 100644
--- a/src/app/admin/(dashboard)/ekonomi/program-kemiskinan/[id]/edit/page.tsx
+++ b/src/app/admin/(dashboard)/ekonomi/program-kemiskinan/[id]/edit/page.tsx
@@ -55,9 +55,9 @@ function EditProgramKemiskinan() {
useEffect(() => {
if (!id) return;
- stateProgram.findUnique
- .load(id)
- .then(() => {
+ const loadData = async () => {
+ try {
+ await stateProgram.findUnique.load(id);
const data = stateProgram.findUnique.data;
if (data) {
setFormData({
@@ -70,12 +70,16 @@ function EditProgramKemiskinan() {
},
});
}
- })
- .catch((err) => {
+ } catch (err) {
console.error('Error load data:', err);
toast.error('Gagal mengambil data program');
- });
- }, [id, stateProgram.findUnique]);
+ }
+ };
+
+ loadData();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [id]); // ✅ hanya trigger saat id berubah
+
// generic handler untuk field top-level
const handleChange = useCallback(
diff --git a/src/app/darmasaba/(pages)/desa/berita/[kategori]/[id]/page.tsx b/src/app/darmasaba/(pages)/desa/berita/[kategori]/[id]/page.tsx
index 37ea41a5..031608aa 100644
--- a/src/app/darmasaba/(pages)/desa/berita/[kategori]/[id]/page.tsx
+++ b/src/app/darmasaba/(pages)/desa/berita/[kategori]/[id]/page.tsx
@@ -62,11 +62,23 @@ function Page() {
Informasi dan Pelayanan Administrasi Digital
-
+
-
+
diff --git a/src/app/darmasaba/(pages)/desa/layanan/[id]/page.tsx b/src/app/darmasaba/(pages)/desa/layanan/[id]/page.tsx
index bb24c934..a2c4e9bc 100644
--- a/src/app/darmasaba/(pages)/desa/layanan/[id]/page.tsx
+++ b/src/app/darmasaba/(pages)/desa/layanan/[id]/page.tsx
@@ -186,12 +186,11 @@ function Page() {
stateCreate.create.form.kategoriId = '';
}
}}
- searchable
+ // searchable
clearable
nothingFoundMessage="Tidak ditemukan"
required
/>
-
diff --git a/src/app/darmasaba/(pages)/kesehatan/data-kesehatan-warga/fasilitas-kesehatan-page/[id]/page.tsx b/src/app/darmasaba/(pages)/kesehatan/data-kesehatan-warga/fasilitas-kesehatan-page/[id]/page.tsx
index 774742de..6aa24dfd 100644
--- a/src/app/darmasaba/(pages)/kesehatan/data-kesehatan-warga/fasilitas-kesehatan-page/[id]/page.tsx
+++ b/src/app/darmasaba/(pages)/kesehatan/data-kesehatan-warga/fasilitas-kesehatan-page/[id]/page.tsx
@@ -240,15 +240,8 @@ function Page() {
-
-
-
-
-
-
-
-
+ Fasilitas Pendukung
@@ -264,8 +257,7 @@ function Page() {
)}
-
-
+
Layanan & Tarif
@@ -303,10 +295,11 @@ function Page() {
)}
+
-
+
diff --git a/src/app/darmasaba/(pages)/kesehatan/data-kesehatan-warga/jadwal-kegiatan-page/[id]/page.tsx b/src/app/darmasaba/(pages)/kesehatan/data-kesehatan-warga/jadwal-kegiatan-page/[id]/page.tsx
index 129c00fc..f5af70e8 100644
--- a/src/app/darmasaba/(pages)/kesehatan/data-kesehatan-warga/jadwal-kegiatan-page/[id]/page.tsx
+++ b/src/app/darmasaba/(pages)/kesehatan/data-kesehatan-warga/jadwal-kegiatan-page/[id]/page.tsx
@@ -4,14 +4,16 @@ import BackButton from '@/app/darmasaba/(pages)/desa/layanan/_com/BackButto';
import colors from '@/con/colors';
import {
Box,
+ Button,
Divider,
Group,
+ Modal,
Paper,
Skeleton,
Stack,
Text
} from '@mantine/core';
-import { useShallowEffect } from '@mantine/hooks';
+import { useDisclosure, useShallowEffect } from '@mantine/hooks';
import { IconMail, IconPhone, IconUser } from '@tabler/icons-react';
import { useParams } from 'next/navigation';
import { useProxy } from 'valtio/utils';
@@ -21,6 +23,7 @@ import CreatePendaftaran from '../create/page';
function Page() {
const params = useParams();
const state = useProxy(jadwalkegiatanState);
+ const [opened, { open, close }] = useDisclosure(false);
useShallowEffect(() => {
state.findUnique.load(params?.id as string);
@@ -66,28 +69,38 @@ function Page() {
Deskripsi Kegiatan
-
+ Layanan yang Tersedia
-
+ Syarat & Ketentuan
-
+ Dokumen yang Perlu Dibawa
-
+
-
+
+ Pendaftaran Kegiatan
+
+
+
+
+
+
+
+
+
diff --git a/src/app/darmasaba/(pages)/lingkungan/edukasi-lingkungan/page.tsx b/src/app/darmasaba/(pages)/lingkungan/edukasi-lingkungan/page.tsx
index d4b6ee5f..aecb80d6 100644
--- a/src/app/darmasaba/(pages)/lingkungan/edukasi-lingkungan/page.tsx
+++ b/src/app/darmasaba/(pages)/lingkungan/edukasi-lingkungan/page.tsx
@@ -49,12 +49,10 @@ function Page() {
-
+ } position="top" withArrow>
-
- {tujuan.data?.judul}
-
+
diff --git a/src/app/darmasaba/(pages)/pendidikan/beasiswa-desa/page.tsx b/src/app/darmasaba/(pages)/pendidikan/beasiswa-desa/page.tsx
index 1c8e2303..05d7bcb2 100644
--- a/src/app/darmasaba/(pages)/pendidikan/beasiswa-desa/page.tsx
+++ b/src/app/darmasaba/(pages)/pendidikan/beasiswa-desa/page.tsx
@@ -74,7 +74,7 @@ function Page() {
Wujudkan Mimpi Pendidikanmu di Desa Darmasaba
-
+
Program beasiswa untuk mendukung pendidikan berkualitas bagi generasi muda Desa Darmasaba.
diff --git a/src/app/darmasaba/(pages)/pendidikan/beasiswa-desa/pelajari-lebih-lanjut/page.tsx b/src/app/darmasaba/(pages)/pendidikan/beasiswa-desa/pelajari-lebih-lanjut/page.tsx
index 0f45651d..f4bc8999 100644
--- a/src/app/darmasaba/(pages)/pendidikan/beasiswa-desa/pelajari-lebih-lanjut/page.tsx
+++ b/src/app/darmasaba/(pages)/pendidikan/beasiswa-desa/pelajari-lebih-lanjut/page.tsx
@@ -15,7 +15,7 @@ import {
Timeline,
Title
} from '@mantine/core';
-import { IconArrowLeft } from '@tabler/icons-react';
+import { IconArrowLeft, IconChecklist, IconInfoCircle, IconQuote, IconSchool, IconTimeline, IconUserPlus } from '@tabler/icons-react';
import { useRouter } from 'next/navigation';
import { useDisclosure } from '@mantine/hooks';
import { useProxy } from 'valtio/utils';
@@ -69,10 +69,11 @@ export default function BeasiswaPage() {
{/* Hero Section */}
-
- Program Beasiswa Pendidikan Desa Darmasaba
-
-
+
+
+ Program Beasiswa Pendidikan Desa Darmasaba
+
+
Program ini bertujuan untuk mendukung pendidikan generasi muda di Desa Darmasaba
agar dapat melanjutkan studi ke jenjang lebih tinggi dengan dukungan finansial dan pendampingan.
@@ -81,21 +82,35 @@ export default function BeasiswaPage() {
{/* Tentang Program */}
-
- Tentang Program
-
+
+
+ Tentang Program
+
Program Beasiswa Desa Darmasaba adalah inisiatif pemerintah desa untuk meningkatkan akses
pendidikan bagi siswa berprestasi dan kurang mampu. Melalui program ini, desa memberikan bantuan
biaya sekolah, bimbingan akademik, serta pelatihan soft skill bagi peserta terpilih.
+
+ {/* Tambahkan info tahun berjalan di sini */}
+
+
+ 📅 Periode Beasiswa Tahun 2025
+
+
+ Pendaftaran beasiswa dibuka mulai 1 Januari 2025 dan ditutup pada
+ 31 Mei 2025.
+ Pengumuman hasil seleksi akan diumumkan pada pertengahan Juni 2025 melalui website resmi Desa Darmasaba.
+
+
{/* Syarat dan Ketentuan */}
-
- Syarat Pendaftaran
-
+
+
+ Syarat Pendaftaran
+
@@ -123,42 +138,61 @@ export default function BeasiswaPage() {
{/* Proses Seleksi */}
-
- Proses Seleksi
-
+
+
+ Proses Seleksi
+
Calon peserta mengisi formulir pendaftaran dan mengunggah dokumen pendukung.
+
+ ⏰ Estimasi waktu: 1 Februari – 31 Mei 2025
+
Panitia memverifikasi kelengkapan dan validitas berkas.
+
+ ⏰ Estimasi waktu: 5–7 hari kerja setelah penutupan pendaftaran
+
Peserta yang lolos administrasi akan diundang untuk wawancara langsung dengan tim seleksi.
+
+ ⏰ Estimasi waktu: 7–10 hari kerja setelah pengumuman seleksi administrasi
+
Daftar penerima beasiswa diumumkan melalui website resmi Desa Darmasaba.
+
+ ⏰ Estimasi waktu: 5 hari kerja setelah tahap wawancara selesai
+
+
+
+ 🗓️ Total estimasi keseluruhan proses: sekitar 3–4 minggu setelah penutupan pendaftaran
+
+
{/* Testimoni */}
-
- Cerita Sukses Penerima Beasiswa
-
+
+
+ Cerita Sukses Penerima Beasiswa
+
@@ -183,7 +217,10 @@ export default function BeasiswaPage() {
{/* CTA Akhir */}
- Siap Bergabung dengan Program Ini?
+
+
+ Siap Bergabung dengan Program Ini?
+
Segera daftar dan wujudkan mimpimu bersama Desa Darmasaba.
diff --git a/src/app/darmasaba/(pages)/pendidikan/pendidikan-non-formal/page.tsx b/src/app/darmasaba/(pages)/pendidikan/pendidikan-non-formal/page.tsx
index 6709e947..4c3b8e45 100644
--- a/src/app/darmasaba/(pages)/pendidikan/pendidikan-non-formal/page.tsx
+++ b/src/app/darmasaba/(pages)/pendidikan/pendidikan-non-formal/page.tsx
@@ -43,7 +43,7 @@ function Page() {
Pendidikan Non Formal
- Bentuk pendidikan di luar sekolah yang terstruktur, bertujuan memberikan keterampilan, pengetahuan, dan pengembangan karakter masyarakat dari berbagai usia serta latar belakang.
+ Pendidikan non formal merupakan bentuk pendidikan di luar sekolah yang terstruktur, bertujuan untuk memberikan keterampilan, pengetahuan, serta pengembangan karakter masyarakat dari berbagai usia dan latar belakang.
void;
@@ -45,11 +40,12 @@ export default function ModalPeminjaman({
}: ModalPeminjamanProps) {
const snap = useSnapshot(perpustakaanDigitalState.peminjamanBuku);
- // reset form setiap modal dibuka
+ const BATAS_HARI_PINJAM = 4;
+
+ // Reset form setiap modal dibuka
useEffect(() => {
if (opened && buku) {
perpustakaanDigitalState.peminjamanBuku.create.form = {
- ...perpustakaanDigitalState.peminjamanBuku.create.form,
bukuId: buku.id,
nama: '',
noTelp: '',
@@ -99,7 +95,14 @@ export default function ModalPeminjaman({
)}
-
+
@@ -112,7 +115,8 @@ export default function ModalPeminjaman({
leftSection={}
value={snap.create.form.nama}
onChange={(e) =>
- (perpustakaanDigitalState.peminjamanBuku.create.form.nama = e.currentTarget.value)
+ (perpustakaanDigitalState.peminjamanBuku.create.form.nama =
+ e.currentTarget.value)
}
required
/>
@@ -123,7 +127,8 @@ export default function ModalPeminjaman({
leftSection={}
value={snap.create.form.noTelp}
onChange={(e) =>
- (perpustakaanDigitalState.peminjamanBuku.create.form.noTelp = e.currentTarget.value)
+ (perpustakaanDigitalState.peminjamanBuku.create.form.noTelp =
+ e.currentTarget.value)
}
required
/>
@@ -134,11 +139,13 @@ export default function ModalPeminjaman({
leftSection={}
value={snap.create.form.alamat}
onChange={(e) =>
- (perpustakaanDigitalState.peminjamanBuku.create.form.alamat = e.currentTarget.value)
+ (perpustakaanDigitalState.peminjamanBuku.create.form.alamat =
+ e.currentTarget.value)
}
required
/>
+ {/* === OTOMATIS SET BATAS DAN TANGGAL KEMBALI === */}
{
- perpustakaanDigitalState.peminjamanBuku.create.form.tanggalPinjam =
- date ? new Date(date).toISOString() : '';
+ if (date) {
+ const tanggalPinjam = new Date(date);
+
+ // simpan tanggal pinjam
+ perpustakaanDigitalState.peminjamanBuku.create.form.tanggalPinjam =
+ tanggalPinjam.toISOString();
+
+ // hitung batas +4 hari
+ const batasKembali = new Date(tanggalPinjam);
+ batasKembali.setDate(batasKembali.getDate() + BATAS_HARI_PINJAM);
+
+ // set batas & tanggal kembali otomatis
+ perpustakaanDigitalState.peminjamanBuku.create.form.batasKembali =
+ batasKembali.toISOString();
+ perpustakaanDigitalState.peminjamanBuku.create.form.tanggalKembali =
+ batasKembali.toISOString();
+
+ toast.info(
+ `Batas pengembalian otomatis diset ke ${batasKembali.toLocaleDateString('id-ID')} (+${BATAS_HARI_PINJAM} hari).`
+ );
+ } else {
+ perpustakaanDigitalState.peminjamanBuku.create.form.tanggalPinjam = '';
+ perpustakaanDigitalState.peminjamanBuku.create.form.batasKembali = '';
+ perpustakaanDigitalState.peminjamanBuku.create.form.tanggalKembali = '';
+ }
}}
required
/>
- Catatan
+ Catatan
- (perpustakaanDigitalState.peminjamanBuku.create.form.catatan = e)
+ onChange={(val) =>
+ (perpustakaanDigitalState.peminjamanBuku.create.form.catatan =
+ val)
}
/>
- {
- perpustakaanDigitalState.peminjamanBuku.create.form.tanggalKembali =
- date ? new Date(date).toISOString() : '';
- }}
- required
- />
-
{
- perpustakaanDigitalState.peminjamanBuku.create.form.batasKembali =
- date ? new Date(date).toISOString() : '';
- }}
- required
+ disabled
+ readOnly
/>
+
}
radius="xl"
+ style={{
+ background: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
+ color: '#fff',
+ boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
+ }}
>
Pinjam Buku
diff --git a/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/page.tsx b/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/page.tsx
index b97db6c8..9e134b39 100644
--- a/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/page.tsx
+++ b/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/page.tsx
@@ -3,8 +3,8 @@
import indeksKepuasanState from "@/app/admin/(dashboard)/_state/landing-page/indeks-kepuasan";
import colors from "@/con/colors";
import { BarChart, PieChart } from '@mantine/charts';
-import { Box, Button, Center, Container, Flex, Group, Modal, Paper, Select, SimpleGrid, Skeleton, Stack, Text, TextInput, Title } from "@mantine/core";
-import { useDisclosure, useMediaQuery, useShallowEffect } from "@mantine/hooks";
+import { Box, Button, Center, Container, Flex, Modal, Paper, Select, SimpleGrid, Skeleton, Stack, Text, TextInput, Title } from "@mantine/core";
+import { useDisclosure, useShallowEffect } from "@mantine/hooks";
import { useState } from "react";
import { useProxy } from "valtio/utils";
@@ -18,14 +18,13 @@ interface ChartDataItem {
function Kepuasan() {
- const state = useProxy(indeksKepuasanState.responden);
+const state = useProxy(indeksKepuasanState.responden);
const { data, loading } = state.findMany;
const [donutDataJenisKelamin, setDonutDataJenisKelamin] = useState([]);
const [donutDataRating, setDonutDataRating] = useState([]);
const [donutDataKelompokUmur, setDonutDataKelompokUmur] = useState([]);
- const [barChartData, setBarChartData] = useState>([]);
- const [opened, { open, close }] = useDisclosure(false);
- const isMobile = useMediaQuery("(max-width: 768px)");
+ const [barChartData, setBarChartData] = useState>([]);
+ const [opened, { open, close }] = useDisclosure(false)
const resetForm = () => {
state.create.form = {
@@ -122,18 +121,18 @@ function Kepuasan() {
// Convert map to array and sort by date
const barData = Array.from(monthYearMap.entries())
- .map(([key, count]) => {
+ .map(([key, Responden]) => {
const [year, month] = key.split('-');
const monthName = new Date(Number(year), Number(month) - 1, 1)
.toLocaleString('id-ID', { month: 'long' });
return {
month: `${monthName} ${year}`,
- count,
+ Responden,
sortKey: parseInt(`${year}${String(month).padStart(2, '0')}`, 10)
};
})
.sort((a, b) => a.sortKey - b.sortKey)
- .map(({ month, count }) => ({ month, count }));
+ .map(({ month, Responden }) => ({ month, Responden }));
setBarChartData(barData);
}
@@ -141,12 +140,12 @@ function Kepuasan() {
if ((loading && !data) || !data) {
return (
-
-
-
-
-
-
+
+
+
+
+
+
);
@@ -157,10 +156,16 @@ function Kepuasan() {
- Indeks Kepuasan Masyarakat
+ Indeks Kepuasan Masyarakat
+ Ukur kebahagiaan warga, tingkatkan layanan desa! Dengan partisipasi aktif masyarakat, kami berkomitmen untuk terus memperbaiki layanan agar lebih transparan, efektif, dan sesuai dengan kebutuhan warga. Kepuasan Anda adalah prioritas utama kami dalam membangun desa yang lebih baik!
+ Ukur kebahagiaan warga, tingkatkan layanan desa! Dengan partisipasi aktif masyarakat, kami berkomitmen untuk terus memperbaiki layanan agar lebih transparan, efektif, dan sesuai dengan kebutuhan warga. Kepuasan Anda adalah prioritas utama kami dalam membangun desa yang lebih baik!
+
+
+
-
-
-
-
-
- Pelayanan Terhadap Publik Desa Darmasaba
-
- Total Responden
-
- {state.findMany.total.toLocaleString("id-ID")}
+
+
+
+
+
+
+ Pelayanan Terhadap Publik Desa Darmasaba
+
+
+ Total Responden
+
+ {state.findMany.total.toLocaleString('id-ID')}
-
-
+
+
{/* Chart Jenis Kelamin */}
@@ -457,17 +475,28 @@ function Kepuasan() {
Belum ada data untuk ditampilkan dalam grafik
) : (
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ {donutDataJenisKelamin.map((entry) => (
+
+
+ {entry.name}: {entry.value}
+
+ ))}
+
+
)}
@@ -482,18 +511,35 @@ function Kepuasan() {
Belum ada data untuk ditampilkan dalam grafik
) : (
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ {donutDataRating.map((entry) => (
+
+
+
+ {entry.name}: {entry.value}
+
+
+ ))}
+
+
+
)}
@@ -508,18 +554,35 @@ function Kepuasan() {
Belum ada data untuk ditampilkan dalam grafik
) : (
-
-
-