import React, { useEffect, useState } from 'react'; import { Plus, Search, Edit, Trash2, X } from 'lucide-react'; import { userService, User } from '../../services/api'; import { toast } from 'react-toastify'; import Loading from '../../components/common/Loading'; import Pagination from '../../components/common/Pagination'; import useAuthStore from '../../store/useAuthStore'; const UserManagementPage: React.FC = () => { const { userInfo } = useAuthStore(); const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [showModal, setShowModal] = useState(false); const [editingUser, setEditingUser] = useState(null); const [filters, setFilters] = useState({ search: '', role: '', status: '', }); const [currentPage, setCurrentPage] = useState(1); const [totalPages, setTotalPages] = useState(1); const [totalItems, setTotalItems] = useState(0); const itemsPerPage = 5; const [formData, setFormData] = useState({ full_name: '', email: '', phone_number: '', password: '', role: 'customer', status: 'active', }); useEffect(() => { setCurrentPage(1); }, [filters]); useEffect(() => { fetchUsers(); }, [filters, currentPage]); const fetchUsers = async () => { try { setLoading(true); console.log('Fetching users with filters:', filters, 'page:', currentPage); const response = await userService.getUsers({ ...filters, page: currentPage, limit: itemsPerPage, }); console.log('Users response:', response); setUsers(response.data.users); if (response.data.pagination) { setTotalPages(response.data.pagination.totalPages); setTotalItems(response.data.pagination.total); } } catch (error: any) { console.error('Error fetching users:', error); toast.error(error.response?.data?.message || 'Unable to load users list'); } finally { setLoading(false); } }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); try { if (editingUser) { // When updating, only send password if changed const updateData: any = { full_name: formData.full_name, email: formData.email, phone_number: formData.phone_number, role: formData.role, status: formData.status, }; // Only add password if user entered a new one if (formData.password && formData.password.trim() !== '') { updateData.password = formData.password; } console.log('Updating user:', editingUser.id, 'with data:', updateData); const response = await userService.updateUser(editingUser.id, updateData); console.log('Update response:', response); toast.success('User updated successfully'); } else { // When creating new, need complete information if (!formData.password || formData.password.trim() === '') { toast.error('Please enter password'); return; } console.log('Creating user with data:', formData); const response = await userService.createUser(formData); console.log('Create response:', response); toast.success('User added successfully'); } // Close modal and reset form first setShowModal(false); resetForm(); // Reload users list after a bit to ensure DB is updated setTimeout(() => { fetchUsers(); }, 300); } catch (error: any) { console.error('Error submitting user:', error); toast.error(error.response?.data?.message || 'An error occurred'); } }; const handleEdit = (user: User) => { setEditingUser(user); setFormData({ full_name: user.full_name, email: user.email, phone_number: user.phone_number || '', password: '', role: user.role, status: user.status || 'active', }); setShowModal(true); }; const handleDelete = async (id: number) => { // Prevent self-deletion if (userInfo?.id === id) { toast.error('You cannot delete your own account'); return; } if (!window.confirm('Are you sure you want to delete this user?')) return; try { console.log('Deleting user:', id); await userService.deleteUser(id); toast.success('User deleted successfully'); fetchUsers(); } catch (error: any) { console.error('Error deleting user:', error); toast.error(error.response?.data?.message || 'Unable to delete user'); } }; const resetForm = () => { setEditingUser(null); setFormData({ full_name: '', email: '', phone_number: '', password: '', role: 'customer', status: 'active', }); }; const getRoleBadge = (role: string) => { const badges: Record = { admin: { bg: 'bg-gradient-to-r from-rose-50 to-red-50', text: 'text-rose-800', label: 'Admin', border: 'border-rose-200' }, staff: { bg: 'bg-gradient-to-r from-blue-50 to-indigo-50', text: 'text-blue-800', label: 'Staff', border: 'border-blue-200' }, customer: { bg: 'bg-gradient-to-r from-emerald-50 to-green-50', text: 'text-emerald-800', label: 'Customer', border: 'border-emerald-200' }, }; const badge = badges[role] || badges.customer; return ( {badge.label} ); }; if (loading) { return ; } return (
{/* Luxury Header */}

User Management

Manage accounts and permissions

{/* Luxury Filter Card */}
setFilters({ ...filters, search: e.target.value })} className="w-full pl-12 pr-4 py-3.5 bg-white border-2 border-slate-200 rounded-xl focus:border-amber-400 focus:ring-4 focus:ring-amber-100 transition-all duration-200 text-slate-700 placeholder-slate-400 font-medium shadow-sm hover:shadow-md" />
{/* Luxury Table Card */}
{users.map((user, index) => ( ))}
Name Email Phone Role Created Date Actions
{user.full_name}
{user.email}
{user.phone_number || 'N/A'}
{getRoleBadge(user.role)}
{user.created_at ? new Date(user.created_at).toLocaleDateString('en-US') : 'N/A'}
{/* Luxury Modal */} {showModal && (
{/* Modal Header */}

{editingUser ? 'Update User' : 'Add New User'}

{editingUser ? 'Modify user information' : 'Create a new user account'}

{/* Modal Content */}
setFormData({ ...formData, full_name: e.target.value })} className="w-full px-4 py-3 bg-white border-2 border-slate-200 rounded-xl focus:border-amber-400 focus:ring-4 focus:ring-amber-100 transition-all duration-200 text-slate-700 font-medium shadow-sm" required />
setFormData({ ...formData, email: e.target.value })} className="w-full px-4 py-3 bg-white border-2 border-slate-200 rounded-xl focus:border-amber-400 focus:ring-4 focus:ring-amber-100 transition-all duration-200 text-slate-700 font-medium shadow-sm" required />
setFormData({ ...formData, phone_number: e.target.value })} className="w-full px-4 py-3 bg-white border-2 border-slate-200 rounded-xl focus:border-amber-400 focus:ring-4 focus:ring-amber-100 transition-all duration-200 text-slate-700 font-medium shadow-sm" />
setFormData({ ...formData, password: e.target.value })} className="w-full px-4 py-3 bg-white border-2 border-slate-200 rounded-xl focus:border-amber-400 focus:ring-4 focus:ring-amber-100 transition-all duration-200 text-slate-700 font-medium shadow-sm" required={!editingUser} />
)}
); }; export default UserManagementPage;