147 lines
8.5 KiB
TypeScript
147 lines
8.5 KiB
TypeScript
import { cookies } from 'next/headers'
|
|
import { redirect } from 'next/navigation'
|
|
import { supabase } from '@/lib/supabase'
|
|
import { LogoutButton } from '@/components/logout-button'
|
|
import { ArrowLeft, Users, Search, Eye, Baby, Phone } from 'lucide-react'
|
|
import Link from 'next/link'
|
|
|
|
export default async function KelolaAkunPenggunaPage() {
|
|
const cookieStore = await cookies()
|
|
const sessionCookie = cookieStore.get('user_session')
|
|
|
|
if (!sessionCookie) redirect('/')
|
|
|
|
const session = JSON.parse(sessionCookie.value)
|
|
if (session.role !== 'admin') redirect('/dashboard')
|
|
|
|
const { data: pengguna, error } = await supabase
|
|
.from('akun_balita')
|
|
.select('id, nama_orang_tua, nama_anak, no_whatsapp, username, tanggal_lahir, created_at')
|
|
.order('created_at', { ascending: false })
|
|
|
|
if (error) {
|
|
return <div className="p-8 text-red-500">Gagal memuat data pengguna.</div>
|
|
}
|
|
|
|
return (
|
|
<div className="min-h-screen bg-white font-sans text-black flex flex-col">
|
|
{/* Header */}
|
|
<header className="flex justify-between items-center px-8 py-6 border-b border-gray-100">
|
|
<div className="flex items-center gap-4">
|
|
<Link href="/dashboard/manajemen-akun" className="group flex items-center gap-2 text-sm font-bold hover:text-gray-600 transition-colors">
|
|
<div className="p-2 rounded-full border border-black flex items-center justify-center group-hover:bg-black group-hover:text-white transition-all">
|
|
<ArrowLeft className="h-5 w-5" />
|
|
</div>
|
|
<span className="hidden md:block">Kembali</span>
|
|
</Link>
|
|
<div className="h-8 w-px bg-gray-200 mx-2 hidden md:block"></div>
|
|
<div className="flex flex-col justify-center">
|
|
<h1 className="text-xl font-bold leading-none">Kelola Akun Pengguna</h1>
|
|
<p className="text-[10px] text-gray-500 tracking-widest uppercase mt-0.5">DAFTAR PENGGUNA TERDAFTAR</p>
|
|
</div>
|
|
</div>
|
|
<LogoutButton />
|
|
</header>
|
|
|
|
<main className="p-8 max-w-6xl mx-auto flex-1 w-full">
|
|
|
|
{/* Stats Bar */}
|
|
<div className="flex items-center justify-between mb-6">
|
|
<div className="flex items-center gap-3">
|
|
<div className="w-10 h-10 rounded-full bg-blue-50 border-2 border-blue-200 flex items-center justify-center text-blue-600">
|
|
<Users className="w-5 h-5" />
|
|
</div>
|
|
<div>
|
|
<p className="text-2xl font-bold leading-none">{pengguna?.length ?? 0}</p>
|
|
<p className="text-xs text-gray-500">Total Pengguna</p>
|
|
</div>
|
|
</div>
|
|
<div className="flex items-center gap-2 px-4 py-2 border-2 border-gray-200 rounded-lg text-sm text-gray-500">
|
|
<Search className="w-4 h-4" />
|
|
<span>Cari melalui halaman detail</span>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Table */}
|
|
<div className="rounded-xl border-2 border-black shadow-[6px_6px_0px_0px_rgba(0,0,0,1)] overflow-hidden">
|
|
<div className="overflow-x-auto">
|
|
<div className="min-w-[800px] md:min-w-full">
|
|
{/* Table Header */}
|
|
<div className="grid grid-cols-[2fr_2fr_1.5fr_1.5fr_auto] bg-black text-white px-6 py-4 text-xs font-bold uppercase tracking-widest">
|
|
<span>Nama Orang Tua</span>
|
|
<span>Nama Anak</span>
|
|
<span>No. WhatsApp</span>
|
|
<span>Username</span>
|
|
<span className="text-center">Aksi</span>
|
|
</div>
|
|
|
|
{/* Table Rows */}
|
|
{!pengguna || pengguna.length === 0 ? (
|
|
<div className="flex flex-col items-center justify-center py-16 gap-3 text-gray-400 bg-white">
|
|
<Users className="w-12 h-12 opacity-30" />
|
|
<p className="font-semibold">Belum ada pengguna terdaftar</p>
|
|
</div>
|
|
) : (
|
|
pengguna.map((user, idx) => (
|
|
<div
|
|
key={user.id}
|
|
className={`grid grid-cols-[2fr_2fr_1.5fr_1.5fr_auto] items-center px-6 py-4 border-b border-gray-100 hover:bg-gray-50 transition-colors ${idx % 2 === 0 ? 'bg-white' : 'bg-gray-50/50'}`}
|
|
>
|
|
{/* Nama Orang Tua */}
|
|
<div className="flex items-center gap-3">
|
|
<div className="w-9 h-9 rounded-full bg-blue-100 border border-blue-200 flex items-center justify-center text-blue-700 text-xs font-bold flex-shrink-0">
|
|
{user.nama_orang_tua?.charAt(0).toUpperCase() ?? '?'}
|
|
</div>
|
|
<div>
|
|
<p className="font-semibold text-sm leading-none">{user.nama_orang_tua ?? '-'}</p>
|
|
<p className="text-[10px] text-gray-400 mt-0.5">
|
|
{user.created_at ? new Date(user.created_at).toLocaleDateString('id-ID', { day: '2-digit', month: 'short', year: 'numeric' }) : '-'}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Nama Anak */}
|
|
<div className="flex items-center gap-2">
|
|
<Baby className="w-3.5 h-3.5 text-gray-400 flex-shrink-0" />
|
|
<span className="text-sm truncate">{user.nama_anak ?? '-'}</span>
|
|
</div>
|
|
|
|
{/* No WA */}
|
|
<div className="flex items-center gap-2">
|
|
<Phone className="w-3.5 h-3.5 text-gray-400 flex-shrink-0" />
|
|
<span className="text-sm text-gray-600">{user.no_whatsapp ?? '-'}</span>
|
|
</div>
|
|
|
|
{/* Username */}
|
|
<div>
|
|
<span className="inline-block bg-gray-100 border border-gray-200 text-gray-700 text-xs font-mono px-2 py-1 rounded">
|
|
@{user.username}
|
|
</span>
|
|
</div>
|
|
|
|
{/* Aksi */}
|
|
<div className="flex justify-center">
|
|
<Link
|
|
href={`/dashboard/manajemen-akun/pengguna/${user.id}`}
|
|
className="flex items-center gap-1.5 px-4 py-2 bg-black text-white text-xs font-bold rounded-lg hover:bg-gray-800 transition-all shadow-[2px_2px_0px_0px_rgba(0,0,0,0.3)] hover:shadow-none hover:translate-x-[1px] hover:translate-y-[1px]"
|
|
>
|
|
<Eye className="w-3.5 h-3.5" />
|
|
Detail
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
))
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Footer note */}
|
|
<p className="text-xs text-gray-400 text-center mt-4">
|
|
Klik <strong>Detail</strong> untuk melihat dan mengedit data pengguna
|
|
</p>
|
|
</main>
|
|
</div>
|
|
)
|
|
}
|