import { useState, useEffect } from "react"; import type { ReactElement } from "react"; import { Layout } from "@/components/layout/Layout"; import { PrimaryButton, StatusBadge, ActionDropdown, NewUserModal, ViewUserModal, EditUserModal, // DeleteConfirmationModal, DataTable, Pagination, FilterDropdown, type Column, } from "@/components/shared"; import { Plus, Download, ArrowUpDown } from "lucide-react"; import { userService } from "@/services/user-service"; import type { User } from "@/types/user"; import { showToast } from "@/utils/toast"; import { usePermissions } from "@/hooks/usePermissions"; // Helper function to get user initials const getUserInitials = (firstName: string, lastName: string): string => { return `${firstName[0]}${lastName[0]}`.toUpperCase(); }; // Helper function to format date const formatDate = (dateString: string): string => { const date = new Date(dateString); return date.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric", }); }; // Helper function to get status badge variant const getStatusVariant = ( status: string, ): "success" | "failure" | "process" => { switch (status.toLowerCase()) { case "active": return "success"; case "pending_verification": return "process"; case "inactive": return "failure"; case "deleted": return "failure"; case "suspended": return "process"; default: return "success"; } }; const Users = (): ReactElement => { const { canCreate, canUpdate // , canDelete } = usePermissions(); const [users, setUsers] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); const [isCreating, setIsCreating] = useState(false); // Pagination state const [currentPage, setCurrentPage] = useState(1); const [limit, setLimit] = useState(5); const [pagination, setPagination] = useState<{ page: number; limit: number; total: number; totalPages: number; hasMore: boolean; }>({ page: 1, limit: 5, total: 0, totalPages: 1, hasMore: false, }); // Filter state const [statusFilter, setStatusFilter] = useState(null); const [orderBy, setOrderBy] = useState(null); // View, Edit, Delete modals const [viewModalOpen, setViewModalOpen] = useState(false); const [editModalOpen, setEditModalOpen] = useState(false); // const [deleteModalOpen, setDeleteModalOpen] = useState(false); const [selectedUserId, setSelectedUserId] = useState(null); // const [selectedUserName, setSelectedUserName] = useState(""); const [isUpdating, setIsUpdating] = useState(false); // const [isDeleting, setIsDeleting] = useState(false); const fetchUsers = async ( page: number, itemsPerPage: number, status: string | null = null, sortBy: string[] | null = null, ): Promise => { try { setIsLoading(true); setError(null); const response = await userService.getAll( page, itemsPerPage, status, sortBy, ); if (response.success) { setUsers(response.data); setPagination(response.pagination); } else { setError("Failed to load users"); } } catch (err: any) { setError(err?.response?.data?.error?.message || "Failed to load users"); } finally { setIsLoading(false); } }; useEffect(() => { fetchUsers(currentPage, limit, statusFilter, orderBy); }, [currentPage, limit, statusFilter, orderBy]); const handleCreateUser = async (data: { email: string; password: string; first_name: string; last_name: string; status: "active" | "suspended" | "deleted"; auth_provider: "local"; role_module_combinations: { role_id: string; module_id?: string | null }[]; department_id?: string; designation_id?: string; }): Promise => { try { setIsCreating(true); const response = await userService.create(data); const message = response.message || `User created successfully`; const description = response.message ? undefined : `${data.first_name} ${data.last_name} has been added`; showToast.success(message, description); setIsModalOpen(false); await fetchUsers(currentPage, limit, statusFilter, orderBy); } catch (err: any) { throw err; } finally { setIsCreating(false); } }; // View user handler const handleViewUser = (userId: string): void => { setSelectedUserId(userId); setViewModalOpen(true); }; // Edit user handler const handleEditUser = (userId: string // , userName: string ): void => { setSelectedUserId(userId); // setSelectedUserName(userName); setEditModalOpen(true); }; // Update user handler const handleUpdateUser = async ( id: string, data: { email: string; first_name: string; last_name: string; status: "active" | "suspended" | "deleted"; tenant_id: string; role_module_combinations: { role_id: string; module_id?: string | null }[]; department_id?: string; designation_id?: string; }, ): Promise => { try { setIsUpdating(true); const response = await userService.update(id, data); const message = response.message || `User updated successfully`; const description = response.message ? undefined : `${data.first_name} ${data.last_name} has been updated`; showToast.success(message, description); setEditModalOpen(false); setSelectedUserId(null); await fetchUsers(currentPage, limit, statusFilter, orderBy); } catch (err: any) { throw err; } finally { setIsUpdating(false); } }; // Delete user handler // const handleDeleteUser = (userId: string, userName: string): void => { // setSelectedUserId(userId); // setSelectedUserName(userName); // setDeleteModalOpen(true); // }; // Confirm delete handler // const handleConfirmDelete = async (): Promise => { // if (!selectedUserId) return; // try { // setIsDeleting(true); // await userService.delete(selectedUserId); // setDeleteModalOpen(false); // setSelectedUserId(null); // setSelectedUserName(""); // await fetchUsers(currentPage, limit, statusFilter, orderBy); // } catch (err: any) { // throw err; // } finally { // setIsDeleting(false); // } // }; // Load user for view/edit const loadUser = async (id: string): Promise => { const response = await userService.getById(id); return response.data; }; // Define table columns const columns: Column[] = [ { key: "name", label: "User Name", render: (user) => (
{getUserInitials(user.first_name, user.last_name)}
{user.first_name} {user.last_name}
), mobileLabel: "Name", }, { key: "email", label: "Email", render: (user) => ( {user.email} ), }, { key: "role", label: "Role", render: (user) => (
{user.role_module_combinations && user.role_module_combinations.length > 0 ? ( user.role_module_combinations.map((combo, idx) => ( {combo.role_name} {combo.module_name && `(${combo.module_name})`} )) ) : user.roles && user.roles.length > 0 ? ( user.roles.map((role) => ( {role.name} )) ) : ( {user.role?.name || "-"} )}
), }, { key: "status", label: "Status", render: (user) => ( {user.status} ), }, { key: "auth_provider", label: "Auth Provider", render: (user) => ( {user.auth_provider} ), }, { key: "created_at", label: "Joined Date", render: (user) => ( {formatDate(user.created_at)} ), mobileLabel: "Joined", }, { key: "actions", label: "Actions", align: "right", render: (user) => (
handleViewUser(user.id)} onEdit={ canUpdate("users") ? () => handleEditUser( user.id, // `${user.first_name} ${user.last_name}`, ) : undefined } // onDelete={ // canDelete("users") // ? () => // handleDeleteUser( // user.id, // `${user.first_name} ${user.last_name}`, // ) // : undefined // } />
), }, ]; // Mobile card renderer const mobileCardRenderer = (user: User) => (
{getUserInitials(user.first_name, user.last_name)}

{user.first_name} {user.last_name}

{user.email}

handleViewUser(user.id)} onEdit={ canUpdate("users") ? () => handleEditUser( user.id, // `${user.first_name} ${user.last_name}`, ) : undefined } // onDelete={ // canDelete("users") // ? () => // handleDeleteUser( // user.id, // `${user.first_name} ${user.last_name}`, // ) // : undefined // } />
Status:
{user.status}
Auth Provider:

{user.auth_provider}

Joined:

{formatDate(user.created_at)}

); return ( {/* Table Container */}
{/* Table Header with Filters */}
{/* Filters */}
{/* Status Filter */} { setStatusFilter(value as string | null); setCurrentPage(1); // Reset to first page when filter changes }} placeholder="All" /> {/* Sort Filter */} { setOrderBy(value as string[] | null); setCurrentPage(1); // Reset to first page when sort changes }} placeholder="Default" showIcon icon={} />
{/* Actions */}
{/* Export Button */} {/* New User Button */} {canCreate("users") && ( setIsModalOpen(true)} > New User )}
{/* Data Table */} user.id} mobileCardRenderer={mobileCardRenderer} emptyMessage="No users found" isLoading={isLoading} error={error} /> {/* Table Footer with Pagination */} {pagination.total > 0 && ( { setCurrentPage(page); }} onLimitChange={(newLimit: number) => { setLimit(newLimit); setCurrentPage(1); // Reset to first page when limit changes }} /> )}
{/* New User Modal */} setIsModalOpen(false)} onSubmit={handleCreateUser} isLoading={isCreating} /> {/* View User Modal */} { setViewModalOpen(false); setSelectedUserId(null); }} userId={selectedUserId} onLoadUser={loadUser} /> {/* Edit User Modal */} { setEditModalOpen(false); setSelectedUserId(null); // setSelectedUserName(""); }} userId={selectedUserId} onLoadUser={loadUser} onSubmit={handleUpdateUser} isLoading={isUpdating} /> {/* Delete Confirmation Modal */} {/* { setDeleteModalOpen(false); setSelectedUserId(null); setSelectedUserName(""); }} onConfirm={handleConfirmDelete} title="Delete User" message="Are you sure you want to delete this user" itemName={selectedUserName} isLoading={isDeleting} /> */}
); }; export default Users;