239 lines
8.6 KiB
TypeScript
239 lines
8.6 KiB
TypeScript
"use client";
|
|
|
|
import { useRouter } from "@/i18n/routing";
|
|
import { useParams } from "next/navigation";
|
|
import { Card } from "@/components/ui/card";
|
|
import { Button } from "@/components/ui/button";
|
|
import { getUserDetail } from "@/service/management-user/management-user";
|
|
import { useEffect, useState } from "react";
|
|
import { formatDateToIndonesian } from "@/utils/globals";
|
|
|
|
export default function UserDetailPage() {
|
|
const router = useRouter();
|
|
const params = useParams();
|
|
const userId = params?.id ? Number(params.id) : undefined;
|
|
const [user, setUser] = useState<any>(null);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
async function loadUserDetail() {
|
|
if (!userId) return;
|
|
|
|
try {
|
|
setLoading(true);
|
|
const response = await getUserDetail(userId);
|
|
if (response && !response.error && response.data.data) {
|
|
setUser(response.data.data);
|
|
} else {
|
|
console.error("Gagal mengambil detail user:", response?.message || "Unknown error");
|
|
}
|
|
} catch (error) {
|
|
console.error("Error loading user detail:", error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}
|
|
|
|
loadUserDetail();
|
|
}, [userId]);
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className="container mx-auto py-6">
|
|
<Card className="p-6">
|
|
<div className="flex items-center justify-center py-8">
|
|
<div className="text-center">
|
|
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900 mx-auto mb-4"></div>
|
|
<p>Loading user detail...</p>
|
|
</div>
|
|
</div>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (!user) {
|
|
return (
|
|
<div className="container mx-auto py-6">
|
|
<Card className="p-6">
|
|
<div className="text-center">
|
|
<p className="text-red-500 mb-4">User tidak ditemukan</p>
|
|
<Button onClick={() => router.push("/admin/management-user")}>
|
|
Kembali ke Management User
|
|
</Button>
|
|
</div>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="container mx-auto py-6">
|
|
<Card className="p-6">
|
|
<div className="flex justify-between items-center mb-6">
|
|
<h1 className="text-2xl font-semibold">Detail User</h1>
|
|
<div className="flex gap-2">
|
|
<Button
|
|
variant="outline"
|
|
onClick={() => router.push(`/admin/management-user/edit/${userId}`)}
|
|
>
|
|
Edit User
|
|
</Button>
|
|
<Button onClick={() => router.push("/admin/management-user")}>
|
|
Kembali
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
{/* Basic Information */}
|
|
<div className="space-y-4">
|
|
<h2 className="text-lg font-semibold border-b pb-2">Informasi Dasar</h2>
|
|
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">ID</label>
|
|
<p className="text-lg font-mono">{user.id}</p>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">Nama Lengkap</label>
|
|
<p className="text-lg font-semibold">{user.fullname}</p>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">Username</label>
|
|
<p className="text-lg font-mono">{user.username}</p>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">Email</label>
|
|
<p className="text-lg">{user.email}</p>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">No. HP</label>
|
|
<p className="text-lg">{user.phoneNumber}</p>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">Alamat</label>
|
|
<p className="text-lg">{user.address || "-"}</p>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">Tanggal Lahir</label>
|
|
<p className="text-lg">{user.dateOfBirth ? formatDateToIndonesian(user.dateOfBirth) : "-"}</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* System Information */}
|
|
<div className="space-y-4">
|
|
<h2 className="text-lg font-semibold border-b pb-2">Informasi Sistem</h2>
|
|
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">User Role ID</label>
|
|
<p className="text-lg font-mono">{user.userRoleId}</p>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">User Level ID</label>
|
|
<p className="text-lg font-mono">{user.userLevelId}</p>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">Level Group</label>
|
|
<p className="text-lg">{user.userLevelGroup || "-"}</p>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">Status ID</label>
|
|
<p className="text-lg font-mono">{user.statusId}</p>
|
|
</div>
|
|
|
|
{/* <div>
|
|
<label className="text-sm font-medium text-gray-600">Keycloak ID</label>
|
|
<p className="text-xs font-mono break-all p-2 rounded">{user.keycloakId}</p>
|
|
</div> */}
|
|
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">Dibuat Oleh</label>
|
|
<p className="text-lg">{user.createdById ? `User ID: ${user.createdById}` : "System"}</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Status & Timeline */}
|
|
<div className="space-y-4">
|
|
<h2 className="text-lg font-semibold border-b pb-2">Status & Timeline</h2>
|
|
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">Status Aktif</label>
|
|
<div className="flex items-center gap-2">
|
|
<div className={`w-3 h-3 rounded-full ${user.isActive ? 'bg-green-500' : 'bg-red-500'}`}></div>
|
|
<p className={`text-lg font-semibold ${user.isActive ? 'text-green-600' : 'text-red-600'}`}>
|
|
{user.isActive ? 'Aktif' : 'Tidak Aktif'}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">Tanggal Dibuat</label>
|
|
<p className="text-lg">{formatDateToIndonesian(user.createdAt)}</p>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">Tanggal Terakhir Diupdate</label>
|
|
<p className="text-lg">{formatDateToIndonesian(user.updatedAt)}</p>
|
|
</div>
|
|
|
|
{/* <div>
|
|
<label className="text-sm font-medium text-gray-600">Foto Profil</label>
|
|
<p className="text-lg">{user.profilePicturePath ? "Tersedia" : "Tidak ada"}</p>
|
|
</div> */}
|
|
</div>
|
|
|
|
{/* Additional Information (only show if data exists) */}
|
|
{(user.genderType || user.identityType || user.identityNumber || user.lastEducation || user.workType) && (
|
|
<div className="space-y-4">
|
|
<h2 className="text-lg font-semibold border-b pb-2">Informasi Tambahan</h2>
|
|
|
|
{user.genderType && (
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">Jenis Kelamin</label>
|
|
<p className="text-lg">{user.genderType}</p>
|
|
</div>
|
|
)}
|
|
|
|
{user.identityType && (
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">Tipe Identitas</label>
|
|
<p className="text-lg">{user.identityType}</p>
|
|
</div>
|
|
)}
|
|
|
|
{user.identityNumber && (
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">Nomor Identitas</label>
|
|
<p className="text-lg font-mono">{user.identityNumber}</p>
|
|
</div>
|
|
)}
|
|
|
|
{user.lastEducation && (
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">Pendidikan Terakhir</label>
|
|
<p className="text-lg">{user.lastEducation}</p>
|
|
</div>
|
|
)}
|
|
|
|
{user.workType && (
|
|
<div>
|
|
<label className="text-sm font-medium text-gray-600">Jenis Pekerjaan</label>
|
|
<p className="text-lg">{user.workType}</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</Card>
|
|
</div>
|
|
);
|
|
} |