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

158 lines
4.0 KiB
TypeScript

'use client';
import { useCallback, useState } from 'react';
import { Plus, ShieldCheck } 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 { useAppStore } from '@/store/app.store';
import type { Role } from '@/types';
import { useRoleColumns } from './components/RoleColumns';
import { RoleFilters } from './components/RoleFilters';
import { RoleSheet } from './components/RoleSheet';
import { RoleTable } from './components/RoleTable';
import { useRoleFilters } from './hooks/useRoleFilters';
import { useRoleForm } from './hooks/useRoleForm';
import {
usePermissionsTreeQuery,
useRolesQuery,
useRoleStatusMutation,
} from './hooks/useRoleQueries';
export default function RolesPage() {
const organizationId = useAppStore((state) => state.user?.organization_id ?? null);
const [isSheetOpen, setIsSheetOpen] = useState(false);
const {
skip,
setSkip,
limit,
setLimit,
sorting,
setSorting,
searchTerm,
debouncedSearchTerm,
setSearchTerm,
statusFilter,
setStatusFilter,
} = useRoleFilters();
const rolesQuery = useRolesQuery({
skip,
limit,
searchTerm: debouncedSearchTerm,
statusFilter,
sorting,
});
const permissionsQuery = usePermissionsTreeQuery(isSheetOpen);
const roleForm = useRoleForm({
organizationId,
permissionTree: permissionsQuery.permissionTree,
onSaved: () => setIsSheetOpen(false),
});
const {
openCreate: prepareCreateRole,
openEdit: prepareEditRole,
register,
onSubmit,
roleId,
permissionIds,
setPermissionIds,
errors,
touchedFields,
canSubmit,
isSaving,
} = roleForm;
const statusMutation = useRoleStatusMutation();
const { mutate: updateRoleStatus, isPending: isStatusPending } = statusMutation;
const openCreate = useCallback(() => {
prepareCreateRole();
setIsSheetOpen(true);
}, [prepareCreateRole]);
const openEdit = useCallback(
(role: Role) => {
prepareEditRole(role);
setIsSheetOpen(true);
},
[prepareEditRole],
);
const toggleStatus = useCallback(
(role: Role) => {
updateRoleStatus(role);
},
[updateRoleStatus],
);
const columns = useRoleColumns({
onEdit: openEdit,
onToggleStatus: toggleStatus,
isStatusPending,
});
const total = rolesQuery.data?.total ?? 0;
const roles = rolesQuery.data?.items ?? [];
const toolbar = (
<RoleFilters
searchTerm={searchTerm}
statusFilter={statusFilter}
onSearchChange={setSearchTerm}
onStatusChange={setStatusFilter}
/>
);
return (
<>
<main className="relative z-10 space-y-5">
<PageHeader
title="Role Management"
description="Manage roles and permission access"
icon={ShieldCheck}
actions={
<PermissionGuard permissions={PERMISSIONS.ROLE.CREATE}>
<Button onClick={openCreate} size="sm">
<Plus />
Add Role
</Button>
</PermissionGuard>
}
/>
<RoleTable
columns={columns}
roles={roles}
isLoading={rolesQuery.isLoading}
toolbar={toolbar}
skip={skip}
limit={limit}
total={total}
sorting={sorting}
onPageChange={setSkip}
onLimitChange={setLimit}
onSortingChange={setSorting}
/>
</main>
<RoleSheet
open={isSheetOpen}
onOpenChange={setIsSheetOpen}
roleId={roleId}
register={register}
errors={errors}
touchedFields={touchedFields}
onSubmit={onSubmit}
permissionTree={permissionsQuery.permissionTree}
permissionIds={permissionIds}
onPermissionIdsChange={setPermissionIds}
isPermissionsLoading={permissionsQuery.isLoading}
canSubmit={canSubmit}
isSaving={isSaving}
/>
</>
);
}