import React, { useState } from "react"; import { AlertTriangle, Edit, Plus, RefreshCw, Save, Search, Trash2, UserX, X, } from "lucide-react"; import { Card, CardContent } from "../components/ui/Card.tsx"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "../components/ui/Table.tsx"; import { Button } from "../components/ui/Button.tsx"; import { Input, PasswordInput, Select } from "../components/ui/Input.tsx"; import { useEmployees } from "../hooks/useEmployees.ts"; import { useDepartments } from "../hooks/useDepartments.ts"; import { useAuth } from "../contexts/authContext.ts"; import { api } from "../services/api.ts"; export const UsersPage: React.FC = () => { const [activeTab, setActiveTab] = useState< "list" | "add" | "edit" | "delete" >("list"); const [filterRole, setFilterRole] = useState(""); const [filterDept, setFilterDept] = useState(""); const [searchQuery, setSearchQuery] = useState(""); const { employees, loading, error, refresh, createEmployee, deleteEmployee, updateEmployee, } = useEmployees(); const { departments } = useDepartments(); const { user: currentUser } = useAuth(); // Form state const [formData, setFormData] = useState({ username: "", password: "", confirmPassword: "", name: "", email: "", role: "Employee", departmentId: "", contractorId: "", isActive: true, // New fields phoneNumber: "", aadharNumber: "", bankAccountNumber: "", bankName: "", bankIfsc: "", // Contractor-specific contractorAgreementNumber: "", pfNumber: "", esicNumber: "", }); const [formError, setFormError] = useState(""); const [formLoading, setFormLoading] = useState(false); const [contractors, setContractors] = useState([]); const [editingUserId, setEditingUserId] = useState(null); // Load contractors when role is Employee React.useEffect(() => { if (formData.role === "Employee") { api.getUsers({ role: "Contractor" }).then(setContractors).catch( console.error, ); } }, [formData.role]); // Check if current user can manage users const canManageUsers = currentUser?.role === "SuperAdmin" || currentUser?.role === "Supervisor"; const isSupervisor = currentUser?.role === "Supervisor"; // Filter departments for supervisors (only show their department) const filteredDepartments = isSupervisor ? departments.filter((d) => d.id === currentUser?.department_id) : departments; const roleOptions = [ { value: "", label: "All Roles" }, { value: "SuperAdmin", label: "Super Admin" }, { value: "Supervisor", label: "Supervisor" }, { value: "Contractor", label: "Contractor" }, { value: "Employee", label: "Employee" }, ]; const deptOptions = isSupervisor ? [{ value: String(currentUser?.department_id), label: filteredDepartments[0]?.name || "My Department", }] : [ { value: "", label: "All Departments" }, ...departments.map((d) => ({ value: String(d.id), label: d.name })), ]; const handleInputChange = ( e: React.ChangeEvent, ) => { const { name, value } = e.target; setFormData((prev) => ({ ...prev, [name]: value })); setFormError(""); }; const handleCreateUser = async () => { // Validation if ( !formData.username || !formData.password || !formData.name || !formData.email ) { setFormError("Please fill in all required fields"); return; } if (formData.password !== formData.confirmPassword) { setFormError("Passwords do not match"); return; } if (formData.password.length < 6) { setFormError("Password must be at least 6 characters"); return; } setFormLoading(true); setFormError(""); try { await createEmployee({ username: formData.username, password: formData.password, name: formData.name, email: formData.email, role: formData.role, departmentId: formData.departmentId ? parseInt(formData.departmentId) : null, contractorId: formData.contractorId ? parseInt(formData.contractorId) : null, // New fields phoneNumber: formData.phoneNumber || null, aadharNumber: formData.aadharNumber || null, bankAccountNumber: formData.bankAccountNumber || null, bankName: formData.bankName || null, bankIfsc: formData.bankIfsc || null, // Contractor-specific contractorAgreementNumber: formData.contractorAgreementNumber || null, pfNumber: formData.pfNumber || null, esicNumber: formData.esicNumber || null, }); // Reset form and switch to list setFormData({ username: "", password: "", confirmPassword: "", name: "", email: "", role: "Employee", departmentId: "", contractorId: "", isActive: true, phoneNumber: "", aadharNumber: "", bankAccountNumber: "", bankName: "", bankIfsc: "", contractorAgreementNumber: "", pfNumber: "", esicNumber: "", }); setActiveTab("list"); refresh(); } catch (err: any) { setFormError(err.message || "Failed to create user"); } finally { setFormLoading(false); } }; const handleDeleteUser = async (id: number, username: string) => { if (!confirm(`Are you sure you want to delete user "${username}"?`)) return; try { await deleteEmployee(id); refresh(); } catch (err: any) { alert(err.message || "Failed to delete user"); } }; const handleEditUser = (user: any) => { setFormData({ username: user.username, password: "", confirmPassword: "", name: user.name, email: user.email, role: user.role, departmentId: user.department_id ? String(user.department_id) : "", contractorId: user.contractor_id ? String(user.contractor_id) : "", isActive: user.is_active, phoneNumber: user.phone_number || "", aadharNumber: user.aadhar_number || "", bankAccountNumber: user.bank_account_number || "", bankName: user.bank_name || "", bankIfsc: user.bank_ifsc || "", contractorAgreementNumber: user.contractor_agreement_number || "", pfNumber: user.pf_number || "", esicNumber: user.esic_number || "", }); setEditingUserId(user.id); setActiveTab("edit"); setFormError(""); }; const handleUpdateUser = async () => { if (!formData.name || !formData.email) { setFormError("Please fill in all required fields"); return; } setFormLoading(true); setFormError(""); try { await updateEmployee(editingUserId!, { name: formData.name, email: formData.email, role: formData.role, departmentId: formData.departmentId ? parseInt(formData.departmentId) : null, contractorId: formData.contractorId ? parseInt(formData.contractorId) : null, isActive: formData.isActive, // New fields phoneNumber: formData.phoneNumber || null, aadharNumber: formData.aadharNumber || null, bankAccountNumber: formData.bankAccountNumber || null, bankName: formData.bankName || null, bankIfsc: formData.bankIfsc || null, contractorAgreementNumber: formData.contractorAgreementNumber || null, pfNumber: formData.pfNumber || null, esicNumber: formData.esicNumber || null, }); resetForm(); setActiveTab("list"); refresh(); } catch (err: any) { setFormError(err.message || "Failed to update user"); } finally { setFormLoading(false); } }; const resetForm = () => { setFormData({ username: "", password: "", confirmPassword: "", name: "", email: "", role: "Employee", departmentId: "", contractorId: "", isActive: true, phoneNumber: "", aadharNumber: "", bankAccountNumber: "", bankName: "", bankIfsc: "", contractorAgreementNumber: "", pfNumber: "", esicNumber: "", }); setEditingUserId(null); setFormError(""); }; // Auto-set filter for supervisors React.useEffect(() => { if (isSupervisor && currentUser?.department_id) { setFilterDept(String(currentUser.department_id)); } }, [isSupervisor, currentUser?.department_id]); // Filter employees const filteredEmployees = employees.filter((emp) => { // Search filter if (searchQuery) { const query = searchQuery.toLowerCase(); const matchesSearch = emp.name?.toLowerCase().includes(query) || emp.username?.toLowerCase().includes(query) || emp.email?.toLowerCase().includes(query) || emp.role?.toLowerCase().includes(query); if (!matchesSearch) return false; } if (filterRole && emp.role !== filterRole) return false; // For supervisors, always filter by their department if (isSupervisor && currentUser?.department_id) { if (emp.department_id !== currentUser.department_id) return false; } else if (filterDept && emp.department_id !== parseInt(filterDept)) { return false; } return true; }); return (
{canManageUsers && ( <> )}
{activeTab === "list" && (
setSearchQuery(e.target.value)} className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
setFilterRole(e.target.value)} />
Total Users: {filteredEmployees.length}
{error && (
Error: {error}
)} {loading ?
Loading...
: filteredEmployees.length > 0 ? ( ID USERNAME FULL NAME EMAIL ROLE DEPARTMENT REPORTS TO STATUS ACTIONS {filteredEmployees.map((user) => { // Find supervisor for contractors (supervisor in same department) const getSupervisorName = () => { if (user.role !== "Contractor") return null; const supervisor = employees.find( (e) => e.role === "Supervisor" && e.department_id === user.department_id, ); return supervisor?.name || null; }; // Get reports to info based on role const getReportsTo = () => { if (user.role === "Employee") { return user.contractor_name ? ( {user.contractor_name} ) : "-"; } if (user.role === "Contractor") { const supervisorName = getSupervisorName(); return supervisorName ? ( {supervisorName} ) : "-"; } return "-"; }; return ( {user.id} {user.username} {user.name} {user.email} {user.role} {user.department_name || "-"} {getReportsTo()} {user.is_active ? "Active" : "Inactive"} {canManageUsers && (
)}
); })}
) : !loading && (
No users found
)}
)} {activeTab === "add" && (
{formError && (
{formError}
)}

User Information

Role & Department

{formData.role === "Employee" && (

Bank Details

)} {/* Contractor-specific fields */} {formData.role === "Contractor" && ( <>

Contractor Details

)}
)} {activeTab === "edit" && (
{formError && (
{formError}
)} {!editingUserId ? (

Select User to Edit

({ value: String(c.id), label: c.name, })), ]} /> )}
{/* Personal & Bank Details - for Employee and Contractor */} {(formData.role === "Employee" || formData.role === "Contractor") && ( <>

Personal Details

Bank Details

)} {/* Contractor-specific fields */} {formData.role === "Contractor" && ( <>

Contractor Details

)}
)}
)} {activeTab === "delete" && canManageUsers && (

Warning: Permanent Action

Deleting a user is permanent and cannot be undone. All associated data will be removed. {isSupervisor && " As a Supervisor, you can only delete Employees and Contractors in your department."}

setSearchQuery(e.target.value)} className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-red-500 focus:border-transparent" />
{!isSupervisor && ( setFilterRole(e.target.value)} />
{(() => { // Filter users that can be deleted const deletableUsers = employees.filter((emp) => { // SuperAdmins and Supervisors cannot be deleted from this tab if (emp.role === "SuperAdmin" || emp.role === "Supervisor") { return false; } // Only Employees and Contractors can be deleted if (emp.role !== "Employee" && emp.role !== "Contractor") { return false; } // Supervisors can only delete users in their department if ( isSupervisor && emp.department_id !== currentUser?.department_id ) return false; // Apply search filter if (searchQuery) { const query = searchQuery.toLowerCase(); const matchesSearch = emp.name?.toLowerCase().includes(query) || emp.username?.toLowerCase().includes(query) || emp.email?.toLowerCase().includes(query); if (!matchesSearch) return false; } // Apply role filter if (filterRole && emp.role !== filterRole) return false; // Apply department filter (for SuperAdmin) if ( !isSupervisor && filterDept && emp.department_id !== parseInt(filterDept) ) return false; return true; }); return ( <>
Deletable Users: {deletableUsers.length}
{deletableUsers.length > 0 ? ( ID USERNAME FULL NAME EMAIL ROLE DEPARTMENT REPORTS TO STATUS ACTION {deletableUsers.map((user) => { // Find supervisor for contractors (supervisor in same department) const getSupervisorName = () => { if (user.role !== "Contractor") return null; const supervisor = employees.find( (e) => e.role === "Supervisor" && e.department_id === user.department_id, ); return supervisor?.name || null; }; // Get reports to info based on role const getReportsTo = () => { if (user.role === "Employee") { return user.contractor_name ? ( {user.contractor_name} ) : "-"; } if (user.role === "Contractor") { const supervisorName = getSupervisorName(); return supervisorName ? ( {supervisorName} ) : "-"; } return "-"; }; return ( {user.id} {user.username} {user.name} {user.email} {user.role} {user.department_name || "-"} {getReportsTo()} {user.is_active ? "Active" : "Inactive"} ); })}
) : (

No deletable users found

{isSupervisor ? "Only Employees and Contractors in your department can be deleted." : "Only Employees and Contractors can be deleted from this tab."}

)} ); })()}
)}
); };