Files
road-monitoring-ui/src/app/(modules)/users/page.tsx

158 lines
4.0 KiB
TypeScript

'use client';
import { useCallback, useMemo, useState } from 'react';
import { Plus, Users } from 'lucide-react';
import { PageHeader } from '@/components/page-header';
import { Button } from '@/components/ui/button';
import { PERMISSIONS } from '@/constants/permissions';
import { PermissionGuard } from '@/guards';
import type { AdministrationUser } from '@/types';
import { useUserColumns } from './components/UserColumns';
import { UserFilters } from './components/UserFilters';
import { UserSheet } from './components/UserSheet';
import { UserStats } from './components/UserStats';
import { UserTable } from './components/UserTable';
import { useUserFilters } from './hooks/useUserFilters';
import { useUserForm } from './hooks/useUserForm';
import { useUserStatusMutation } from './hooks/useUserMutations';
import { useUsersQuery } from './hooks/useUserQueries';
export default function UsersPage() {
const [isSheetOpen, setIsSheetOpen] = useState(false);
const {
skip,
setSkip,
limit,
setLimit,
sorting,
setSorting,
searchTerm,
debouncedSearchTerm,
setSearchTerm,
statusFilter,
setStatusFilter,
} = useUserFilters();
const usersQuery = useUsersQuery({
skip,
limit,
searchTerm: debouncedSearchTerm,
statusFilter,
sorting,
});
const userForm = useUserForm({
onSaved: () => setIsSheetOpen(false),
});
const {
openCreate: prepareCreateUser,
openEdit: prepareEditUser,
register,
handleSubmit,
userId,
roleId,
setRoleId,
errors,
isSubmitted,
canSubmit,
isSaving,
} = userForm;
const statusMutation = useUserStatusMutation();
const { mutate: updateUserStatus, pendingUserId } = statusMutation;
const openCreate = useCallback(() => {
prepareCreateUser();
setIsSheetOpen(true);
}, [prepareCreateUser]);
const openEdit = useCallback(
(user: AdministrationUser) => {
prepareEditUser(user);
setIsSheetOpen(true);
},
[prepareEditUser],
);
const toggleStatus = useCallback(
(user: AdministrationUser) => {
updateUserStatus(user);
},
[updateUserStatus],
);
const columns = useUserColumns();
const total = usersQuery.data?.total ?? 0;
const users = usersQuery.data?.items ?? [];
const toolbar = useMemo(
() => (
<UserFilters
searchTerm={searchTerm}
statusFilter={statusFilter}
onSearchChange={setSearchTerm}
onStatusChange={setStatusFilter}
/>
),
[searchTerm, setSearchTerm, setStatusFilter, statusFilter],
);
return (
<>
<main className="relative z-10 space-y-5">
<PageHeader
title="User Management"
description="Manage users and role assignment"
icon={Users}
actions={
<PermissionGuard permissions={PERMISSIONS.USER.CREATE}>
<Button onClick={openCreate} size="sm">
<Plus />
Add User
</Button>
</PermissionGuard>
}
/>
<UserStats
total={total}
activeCount={usersQuery.data?.active_count ?? 0}
inactiveCount={usersQuery.data?.inactive_count ?? 0}
pendingCount={usersQuery.data?.pending_count ?? 0}
/>
<UserTable
columns={columns}
users={users}
isLoading={usersQuery.isLoading}
toolbar={toolbar}
skip={skip}
limit={limit}
total={total}
sorting={sorting}
onPageChange={setSkip}
onLimitChange={setLimit}
onSortingChange={setSorting}
onEdit={openEdit}
onToggleStatus={toggleStatus}
pendingUserId={pendingUserId}
/>
</main>
<UserSheet
open={isSheetOpen}
onOpenChange={setIsSheetOpen}
userId={userId}
register={register}
errors={errors}
isSubmitted={isSubmitted}
onSubmit={handleSubmit}
roleId={roleId}
onRoleChange={setRoleId}
canSubmit={canSubmit}
isSaving={isSaving}
/>
</>
);
}