From 96ecb499b9110893daaf9948642c177ea6a3ff77 Mon Sep 17 00:00:00 2001 From: panggilsajarey <150323912+raynard05@users.noreply.github.com> Date: Tue, 17 Mar 2026 09:42:21 +0700 Subject: [PATCH] add all task that i have done today --- .../kelola-jadwal/InstantScheduleModal.tsx | 6 +- app/dashboard/kelola-jadwal/JadwalTable.tsx | 184 +++++++------- .../manajemen-akun/pengguna/page.tsx | 134 +++++----- .../ManajemenPosyanduTable.tsx | 238 +++++++++--------- app/dashboard/page.tsx | 6 +- .../trend-stunting/StuntingChart.tsx | 197 ++++++++------- app/page.tsx | 12 +- .../[id]/PosyanduDetailClient.tsx | 81 +++++- .../lokasi-posyandu/[id]/page.tsx | 4 +- app/user-dashboard/page.tsx | 6 +- app/user-dashboard/perkembangan/page.tsx | 10 +- .../trend-stunting/StuntingChart.tsx | 157 ++++++------ components/dashboard-footer.tsx | 2 +- components/feature-card.tsx | 8 +- 14 files changed, 577 insertions(+), 468 deletions(-) diff --git a/app/dashboard/kelola-jadwal/InstantScheduleModal.tsx b/app/dashboard/kelola-jadwal/InstantScheduleModal.tsx index 23aa1b7..febfc0e 100644 --- a/app/dashboard/kelola-jadwal/InstantScheduleModal.tsx +++ b/app/dashboard/kelola-jadwal/InstantScheduleModal.tsx @@ -65,7 +65,7 @@ export function InstantScheduleModal({ isOpen, onClose, adminName }: Props) {
- +
@@ -74,7 +74,7 @@ export function InstantScheduleModal({ isOpen, onClose, adminName }: Props) { Penjadwalan harus dilakukan minimal 1 hari sebelumnya.

- Sesi tetap: 08:00 - 11:00 WIB (Selingan 1 Jam). + Sesi: 08-10, 11-13, 14-16 (Selingan 1 Jam).

@@ -104,7 +104,7 @@ export function InstantScheduleModal({ isOpen, onClose, adminName }: Props) {
- 11:00 + 10:00
Fixed Slot diff --git a/app/dashboard/kelola-jadwal/JadwalTable.tsx b/app/dashboard/kelola-jadwal/JadwalTable.tsx index abe07e9..0df1eae 100644 --- a/app/dashboard/kelola-jadwal/JadwalTable.tsx +++ b/app/dashboard/kelola-jadwal/JadwalTable.tsx @@ -222,97 +222,101 @@ export function JadwalTable({ data, userName }: Props) { {/* Table */} -
- - - - - - - - - - - - {filteredData.length === 0 ? ( - - - - ) : ( - filteredData.map((j, idx) => ( - - - - - - +
+
+
+
NoWaktu & SesiDetail PosyanduOleh AdminAksi
-
-
- -
-
-

Belum ada jadwal ditemukan

-

Gunakan Penjadwalan Instan untuk membuat jadwal otomatis.

-
-
-
- {idx + 1} - -
-
- - {j.jam_mulai.slice(0, 5)} - {j.jam_selesai.slice(0, 5)} -
- - {new Date(j.tanggal).toLocaleDateString('id-ID', { weekday: 'long', day: 'numeric', month: 'long' })} - -
-
-
- - {j.detail_posyandu.nama_posyandu} - -
- - {j.detail_posyandu.alamat} -
-
-
-
-
- {j.diedit_oleh.replace('[HISTORY] ', '').charAt(0).toUpperCase()} -
- {j.diedit_oleh.replace('[HISTORY] ', '')} -
-
-
- - - -
-
+ + + + + + + - )) - )} - -
NoWaktu & SesiDetail PosyanduOleh AdminAksi
+ + + {filteredData.length === 0 ? ( + + +
+
+ +
+
+

Belum ada jadwal ditemukan

+

Gunakan Penjadwalan Instan untuk membuat jadwal otomatis.

+
+
+ + + ) : ( + filteredData.map((j, idx) => ( + + + {idx + 1} + + +
+
+ + {j.jam_mulai.slice(0, 5)} - {j.jam_selesai.slice(0, 5)} +
+ + {new Date(j.tanggal).toLocaleDateString('id-ID', { weekday: 'long', day: 'numeric', month: 'long' })} + +
+ + +
+ + {j.detail_posyandu.nama_posyandu} + +
+ + {j.detail_posyandu.alamat} +
+
+ + +
+
+ {j.diedit_oleh.replace('[HISTORY] ', '').charAt(0).toUpperCase()} +
+ {j.diedit_oleh.replace('[HISTORY] ', '')} +
+ + +
+ + + +
+ + + )) + )} + + +
+ - {/* Table Header */} -
- Nama Orang Tua - Nama Anak - No. WhatsApp - Username - Aksi -
- - {/* Table Rows */} - {!pengguna || pengguna.length === 0 ? ( -
- -

Belum ada pengguna terdaftar

-
- ) : ( - pengguna.map((user, idx) => ( -
- {/* Nama Orang Tua */} -
-
- {user.nama_orang_tua?.charAt(0).toUpperCase() ?? '?'} -
-
-

{user.nama_orang_tua ?? '-'}

-

- {user.created_at ? new Date(user.created_at).toLocaleDateString('id-ID', { day: '2-digit', month: 'short', year: 'numeric' }) : '-'} -

-
-
- - {/* Nama Anak */} -
- - {user.nama_anak ?? '-'} -
- - {/* No WA */} -
- - {user.no_whatsapp ?? '-'} -
- - {/* Username */} -
- - @{user.username} - -
- - {/* Aksi */} -
- - - Detail - -
+
+
+ {/* Table Header */} +
+ Nama Orang Tua + Nama Anak + No. WhatsApp + Username + Aksi
- )) - )} + + {/* Table Rows */} + {!pengguna || pengguna.length === 0 ? ( +
+ +

Belum ada pengguna terdaftar

+
+ ) : ( + pengguna.map((user, idx) => ( +
+ {/* Nama Orang Tua */} +
+
+ {user.nama_orang_tua?.charAt(0).toUpperCase() ?? '?'} +
+
+

{user.nama_orang_tua ?? '-'}

+

+ {user.created_at ? new Date(user.created_at).toLocaleDateString('id-ID', { day: '2-digit', month: 'short', year: 'numeric' }) : '-'} +

+
+
+ + {/* Nama Anak */} +
+ + {user.nama_anak ?? '-'} +
+ + {/* No WA */} +
+ + {user.no_whatsapp ?? '-'} +
+ + {/* Username */} +
+ + @{user.username} + +
+ + {/* Aksi */} +
+ + + Detail + +
+
+ )) + )} +
+
{/* Footer note */} diff --git a/app/dashboard/manajemen-posyandu/ManajemenPosyanduTable.tsx b/app/dashboard/manajemen-posyandu/ManajemenPosyanduTable.tsx index 06befcd..c1b4898 100644 --- a/app/dashboard/manajemen-posyandu/ManajemenPosyanduTable.tsx +++ b/app/dashboard/manajemen-posyandu/ManajemenPosyanduTable.tsx @@ -96,124 +96,128 @@ export function ManajemenPosyanduTable({ data }: Props) { {/* Table */} -
- - - - - - - - - - - - {filteredData.length === 0 ? ( - - - - ) : ( - filteredData.map((p, idx) => ( - - - - - - +
+
+
+
NoInformasi PosyanduPetugas & KontakLokasiAksi
-
- -

Tidak ada data posyandu ditemukan

-
-
- {idx + 1} - -
- {p.nama_posyandu} -
- - {p.alamat} -
-
-
-
- {p.petugas && p.petugas.length > 0 ? ( - p.petugas.map((petugas, i) => ( -
-
- - {petugas.nama_petugas} - - {petugas.jabatan && ( - - {petugas.jabatan} - - )} -
- {petugas.nomor_hp && ( -
- - {petugas.nomor_hp} -
- )} -
- )) - ) : ( -
- - Belum ada petugas -
- )} -
-
- {p.link_google_maps ? ( - - - Cek Maps - - ) : ( - Belum diset - )} - -
- - -
- -
-
+ + + + + + + - )) - )} - -
NoInformasi PosyanduPetugas & KontakLokasiAksi
+ + + {filteredData.length === 0 ? ( + + +
+ +

Tidak ada data posyandu ditemukan

+
+ + + ) : ( + filteredData.map((p, idx) => ( + + + {idx + 1} + + +
+ {p.nama_posyandu} +
+ + {p.alamat} +
+
+ + +
+ {p.petugas && p.petugas.length > 0 ? ( + p.petugas.map((petugas, i) => ( +
+
+ + {petugas.nama_petugas} + + {petugas.jabatan && ( + + {petugas.jabatan} + + )} +
+ {petugas.nomor_hp && ( +
+ + {petugas.nomor_hp} +
+ )} +
+ )) + ) : ( +
+ + Belum ada petugas +
+ )} +
+ + + {p.link_google_maps ? ( + + + Cek Maps + + ) : ( + Belum diset + )} + + +
+ + +
+ +
+ + + )) + )} + + +
+ {isModalOpen && ( diff --git a/app/dashboard/page.tsx b/app/dashboard/page.tsx index 6495976..33b61e5 100644 --- a/app/dashboard/page.tsx +++ b/app/dashboard/page.tsx @@ -33,7 +33,7 @@ export default async function DashboardPage() { return (
{/* Header */} -
+
@@ -46,12 +46,12 @@ export default async function DashboardPage() {
-
+
{/* Main Single Frame */}
{/* Top Section - Welcome & Clock */} -
+

diff --git a/app/dashboard/trend-stunting/StuntingChart.tsx b/app/dashboard/trend-stunting/StuntingChart.tsx index eb3dbf2..f31e301 100644 --- a/app/dashboard/trend-stunting/StuntingChart.tsx +++ b/app/dashboard/trend-stunting/StuntingChart.tsx @@ -240,45 +240,49 @@ export function StuntingChart({ data, availableYears }: Props) {

Tidak ada data untuk tahun {selectedYear}

) : ( - - {chartType === 'bar' ? ( - - - - - } /> - val === 'stunting' ? 'Stunting' : 'Normal'} - /> - - - - ) : ( - - - - - - - - - - - - - - - } /> - val === 'stunting' ? 'Stunting' : 'Normal'} - /> - - - - )} - +
+
+ + {chartType === 'bar' ? ( + + + + + } cursor={{ fill: '#f8fafc' }} /> + val === 'stunting' ? 'Stunting' : 'Normal'} + /> + + + + ) : ( + + + + + + + + + + + + + + + } /> + val === 'stunting' ? 'Stunting' : 'Normal'} + /> + + + + )} + +
+
)}
@@ -295,63 +299,66 @@ export function StuntingChart({ data, availableYears }: Props) {

Tidak ada data untuk ditampilkan

) : ( - - - - - - - - - - - `${v}%`} - domain={[0, 100]} - /> - { - if (active && payload && payload.length) { - const val = payload[0]?.value as number - return ( -
-

{label}

-
- - Prevalensi: - = 20 ? 'text-red-600' : 'text-emerald-600'}`}>{val}% -
-

- {val >= 20 ? '⚠️ Di atas ambang batas (20%)' : '✓ Di bawah ambang batas (20%)'} -

-
- ) - } - return null - }} - /> - {/* Reference line 20% */} - ( - = 20 ? '#ef4444' : '#10b981'} - stroke="white" - strokeWidth={2} +
+
+ + + + + + + + + + + `${v}%`} + domain={[0, 100]} /> - )} - activeDot={{ r: 7, stroke: '#f59e0b', strokeWidth: 2 }} - /> - - + { + if (active && payload && payload.length) { + const val = payload[0]?.value as number + return ( +
+

{label} {selectedYear}

+
+ + Prevalensi: + = 20 ? 'text-red-600' : 'text-emerald-600'}`}>{val}% +
+

+ {val >= 20 ? '⚠️ Di atas ambang batas (20%)' : '✓ Di bawah ambang batas (20%)'} +

+
+ ) + } + return null + }} + /> + ( + = 20 ? '#ef4444' : '#10b981'} + stroke="white" + strokeWidth={2} + /> + )} + activeDot={{ r: 8, stroke: '#f59e0b', strokeWidth: 2 }} + /> + + +
+
)}

● Merah = prevalensi ≥ 20% (tinggi)  |  ● Hijau = prevalensi < 20% (aman) diff --git a/app/page.tsx b/app/page.tsx index 9c8c91e..8376c85 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -28,7 +28,7 @@ export default function LoginPage() {

HealthPortal

- +

SISTEM INFORMASI KESEHATAN

Panduan Login

@@ -84,8 +84,8 @@ export default function LoginPage() { {/* Right Side - Login Form */} -
-
+
+
{/* Decorative Elements for Card style */}
@@ -169,11 +169,11 @@ export default function LoginPage() {
-
+
Privasi - + Ketentuan - + Bantuan
diff --git a/app/user-dashboard/lokasi-posyandu/[id]/PosyanduDetailClient.tsx b/app/user-dashboard/lokasi-posyandu/[id]/PosyanduDetailClient.tsx index a44b110..08c3825 100644 --- a/app/user-dashboard/lokasi-posyandu/[id]/PosyanduDetailClient.tsx +++ b/app/user-dashboard/lokasi-posyandu/[id]/PosyanduDetailClient.tsx @@ -1,7 +1,7 @@ 'use client' import { useState, useEffect } from 'react' -import { MapPin, Phone, User, ExternalLink, Map as MapIcon, Star, Send, Loader2, Building2 } from 'lucide-react' +import { MapPin, Phone, User, ExternalLink, Map as MapIcon, Star, Send, Loader2, Building2, Calendar, Clock } from 'lucide-react' import { supabase } from '@/lib/supabase' import { submitReview } from '../action-review' import { showSwal } from '@/lib/swal' @@ -19,6 +19,12 @@ interface Posyandu { nomor_hp: string | null jabatan: string | null }[] + jadwal?: { + id: string + tanggal: string + jam_mulai: string + jam_selesai: string + }[] } interface Review { @@ -119,6 +125,79 @@ export default function PosyanduDetailClient({ data, userId }: Props) {
+ {/* Jadwal Pelaksanaan Card */} +
+
+

+ + Jadwal Pelaksanaan +

+
+
+
+
+ + + + + + + + + + {data.jadwal && data.jadwal.length > 0 ? ( + data.jadwal.map((j) => { + const scheduleDate = new Date(j.tanggal) + const today = new Date() + today.setHours(0, 0, 0, 0) + const isUpcoming = scheduleDate >= today + + return ( + + + + + + ) + }) + ) : ( + + + + )} + +
Hari / TanggalWaktuStatus
+
+ + {scheduleDate.toLocaleDateString('id-ID', { weekday: 'long' })} + + + {scheduleDate.toLocaleDateString('id-ID', { day: 'numeric', month: 'long', year: 'numeric' })} + +
+
+
+ + {j.jam_mulai.slice(0, 5)} - {j.jam_selesai.slice(0, 5)} +
+
+ {isUpcoming ? ( + + Mendatang + + ) : ( + + Selesai + + )} +
+ Belum ada jadwal pelaksanaan yang terdaftar. +
+
+
+
+
+ {/* Petugas Card */}
diff --git a/app/user-dashboard/lokasi-posyandu/[id]/page.tsx b/app/user-dashboard/lokasi-posyandu/[id]/page.tsx index 37ead55..8115dfa 100644 --- a/app/user-dashboard/lokasi-posyandu/[id]/page.tsx +++ b/app/user-dashboard/lokasi-posyandu/[id]/page.tsx @@ -23,9 +23,11 @@ export default async function PosyanduDetailPage({ params }: Props) { .from('detail_posyandu') .select(` *, - petugas:petugas_posyandu_lokal(*) + petugas:petugas_posyandu_lokal(*), + jadwal:jadwal_posyandu(*) `) .eq('id', id) + .order('tanggal', { foreignTable: 'jadwal_posyandu', ascending: false }) .single() if (error || !posyandu) { diff --git a/app/user-dashboard/page.tsx b/app/user-dashboard/page.tsx index 2a70ae4..02aaa59 100644 --- a/app/user-dashboard/page.tsx +++ b/app/user-dashboard/page.tsx @@ -53,7 +53,7 @@ export default async function UserDashboardPage() { return (
{/* Header */} -
+
@@ -66,12 +66,12 @@ export default async function UserDashboardPage() {
-
+
{/* Main Single Frame */}
{/* Top Section - Welcome & Clock */} -
+

diff --git a/app/user-dashboard/perkembangan/page.tsx b/app/user-dashboard/perkembangan/page.tsx index 54a2125..727e1a8 100644 --- a/app/user-dashboard/perkembangan/page.tsx +++ b/app/user-dashboard/perkembangan/page.tsx @@ -97,7 +97,7 @@ export default async function UserPerkembanganPage() { return (
{/* Header */} -
+
@@ -114,10 +114,10 @@ export default async function UserPerkembanganPage() {
-
+
{/* Hero Profile Section */} -
+
{/* Background Decorative Element */}
@@ -181,7 +181,7 @@ export default async function UserPerkembanganPage() { {/* Chart Column */}
-
+
@@ -190,7 +190,7 @@ export default async function UserPerkembanganPage() { {/* Bottom Row: Full Width Table */}
-
+
diff --git a/app/user-dashboard/trend-stunting/StuntingChart.tsx b/app/user-dashboard/trend-stunting/StuntingChart.tsx index a1e1f26..9714653 100644 --- a/app/user-dashboard/trend-stunting/StuntingChart.tsx +++ b/app/user-dashboard/trend-stunting/StuntingChart.tsx @@ -210,39 +210,43 @@ export function StuntingChart({ data, availableYears }: Props) {

Data belum tersedia untuk tahun {selectedYear}

) : ( - - {chartType === 'bar' ? ( - - - - - } cursor={{ fill: '#f8fafc' }} /> - - - - - ) : ( - - - - - - - - - - - - - - - } /> - - - - - )} - +
+
+ + {chartType === 'bar' ? ( + + + + + } cursor={{ fill: '#f8fafc' }} /> + + + + + ) : ( + + + + + + + + + + + + + + + } /> + + + + + )} + +
+
)}
@@ -258,48 +262,53 @@ export function StuntingChart({ data, availableYears }: Props) {

Belum ada data prevalensi

) : ( - - - - - - { - if (active && payload && payload.length) { - const val = payload[0].value as number - return ( -
-

{label} {selectedYear}

-
- = 20 ? 'bg-red-500' : 'bg-emerald-500'}`} /> - {val}% -
-

- {val >= 20 ? '🛑 Tinggi' : '✅ Aman'} -

-
- ) - } - return null - }} - /> - ( - = 20 ? '#ef4444' : '#10b981'} - stroke="white" - strokeWidth={2} +
+
+ + + + + + { + if (active && payload && payload.length) { + const val = payload[0].value as number + return ( +
+

{label} {selectedYear}

+
+ = 20 ? 'bg-red-500' : 'bg-emerald-500'}`} /> + {val}% +
+

+ {val >= 20 ? '🛑 Tinggi' : '✅ Aman'} +

+
+ ) + } + return null + }} /> - )} - /> -
-
+ ( + = 20 ? '#ef4444' : '#10b981'} + stroke="white" + strokeWidth={2} + /> + )} + activeDot={{ r: 8, stroke: '#f59e0b', strokeWidth: 2 }} + /> + + +
+
)}
diff --git a/components/dashboard-footer.tsx b/components/dashboard-footer.tsx index fe24624..fce8fbf 100644 --- a/components/dashboard-footer.tsx +++ b/components/dashboard-footer.tsx @@ -11,7 +11,7 @@ export function DashboardFooter() { } return ( -