Files
lcbp3.np-dms.work/frontend/app/(protected)/admin/users/page.jsx

161 lines
5.8 KiB
JavaScript
Executable File

// File: frontend/app/(protected)/admin/users/page.jsx
'use client';
import { useState, useEffect } from 'react';
import { PlusCircle, MoreHorizontal } from 'lucide-react';
import { api } from '@/lib/api';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuTrigger } from '@/components/ui/dropdown-menu';
import { Badge } from '@/components/ui/badge';
// Import components ที่เราเพิ่งสร้าง
import { UserFormDialog } from '../_components/user-form-dialog';
import { ConfirmDeleteDialog } from '../_components/confirm-delete-dialog';
export default function UsersPage() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
// State สำหรับควบคุม Dialog ทั้งหมด
const [isFormOpen, setIsFormOpen] = useState(false);
const [isDeleteOpen, setIsDeleteOpen] = useState(false);
const [selectedUser, setSelectedUser] = useState(null);
const [isSubmitting, setIsSubmitting] = useState(false);
// Function สำหรับดึงข้อมูลใหม่
const fetchUsers = async () => {
try {
setLoading(true);
const res = await api.get('/users');
setUsers(res.data);
} catch (error) {
console.error("Failed to fetch users", error);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchUsers();
}, []);
// Handlers สำหรับเปิด Dialog
const handleCreate = () => {
setSelectedUser(null);
setIsFormOpen(true);
};
const handleEdit = (user) => {
setSelectedUser(user);
setIsFormOpen(true);
};
const handleDelete = (user) => {
setSelectedUser(user);
setIsDeleteOpen(true);
};
// Function ที่จะทำงานเมื่อยืนยันการลบ
const confirmDeactivate = async () => {
if (!selectedUser) return;
setIsSubmitting(true);
try {
await api.delete(`/users/${selectedUser.id}`);
fetchUsers(); // Refresh ข้อมูล
setIsDeleteOpen(false);
} catch (error) {
console.error("Failed to deactivate user", error);
// ควรมี Alert แจ้งเตือน
} finally {
setIsSubmitting(false);
}
};
return (
<>
<Card>
<CardHeader>
<div className="flex items-center justify-between">
<div>
<CardTitle>User Accounts</CardTitle>
<CardDescription>Manage all user accounts and their roles.</CardDescription>
</div>
<Button onClick={handleCreate}>
<PlusCircle className="w-4 h-4 mr-2" /> Add User
</Button>
</div>
</CardHeader>
<CardContent>
<Table>
<TableHeader>
<TableRow>
<TableHead>Username</TableHead>
<TableHead>Email</TableHead>
<TableHead>Roles</TableHead>
<TableHead>Status</TableHead>
<TableHead><span className="sr-only">Actions</span></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{loading ? (
<TableRow><TableCell colSpan={5} className="text-center">Loading...</TableCell></TableRow>
) : (
users.map((user) => (
<TableRow key={user.id}>
<TableCell className="font-medium">{user.username}</TableCell>
<TableCell>{user.email}</TableCell>
<TableCell>
<div className="flex flex-wrap gap-1">
{user.Roles?.map(role => <Badge key={role.id} variant="secondary">{role.name}</Badge>)}
</div>
</TableCell>
<TableCell>
<Badge variant={user.is_active ? 'default' : 'destructive'}>
{user.is_active ? 'Active' : 'Inactive'}
</Badge>
</TableCell>
<TableCell>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="w-8 h-8 p-0"><MoreHorizontal className="w-4 h-4" /></Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuLabel>Actions</DropdownMenuLabel>
<DropdownMenuItem onClick={() => handleEdit(user)}>Edit</DropdownMenuItem>
<DropdownMenuItem onClick={() => handleDelete(user)} className="text-red-500">
Deactivate
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</TableCell>
</TableRow>
))
)}
</TableBody>
</Table>
</CardContent>
</Card>
{/* Render Dialogs ที่นี่ (มันจะไม่แสดงผลจนกว่า state จะเป็น true) */}
<UserFormDialog
user={selectedUser}
isOpen={isFormOpen}
setIsOpen={setIsFormOpen}
onSuccess={fetchUsers}
/>
<ConfirmDeleteDialog
isOpen={isDeleteOpen}
setIsOpen={setIsDeleteOpen}
isLoading={isSubmitting}
title="Are you sure?"
description={`This will deactivate the user "${selectedUser?.username}". They will no longer be able to log in.`}
onConfirm={confirmDeactivate}
/>
</>
);
}