import { createFileRoute, useNavigate } from "@tanstack/react-router"; import { useGetPermissionList, useCreateRole } from "@/hooks/queries"; import { useState, useMemo } from "react"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Checkbox } from "@/components/ui/checkbox"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Shield, ArrowLeft, Save } from "lucide-react"; import { toast } from "sonner"; import type { Permission } from "@/types/permission"; export const Route = createFileRoute("/_auth/role/create/")({ component: CreateRoleComponent, loader: async ({ context }) => { context.breadcrumbs = [ { title: "Quản lý role", path: "/role" }, { title: "Tạo role mới", path: "/role/create" }, ]; }, }); function CreateRoleComponent() { const navigate = useNavigate(); const { data: permissions = [], isLoading: permissionsLoading } = useGetPermissionList(); const createMutation = useCreateRole(); const [roleName, setRoleName] = useState(""); const [priority, setPriority] = useState(0); const [selectedPermissions, setSelectedPermissions] = useState([]); // Helper to get unique identifier for permission const getPermValue = (perm: Permission) => perm.value ?? perm.id ?? 0; // Group permissions by parent (category) const groupedPermissions = useMemo(() => { const groups: Record = {}; const permissionList = Array.isArray(permissions) ? permissions : []; // First pass: identify all parent categories const parentPermissions: Permission[] = []; const childPermissions: Permission[] = []; permissionList.forEach((perm: Permission) => { const permValue = perm.value ?? perm.enum ?? 0; const isParent = permValue % 10 === 0; if (isParent) { parentPermissions.push(perm); groups[perm.name] = []; } else { childPermissions.push(perm); } }); // Second pass: assign children to parent categories childPermissions.forEach((perm: Permission) => { const permValue = perm.value ?? perm.enum ?? 0; const parentEnum = Math.floor(permValue / 10) * 10; const parent = parentPermissions.find((p: Permission) => (p.value ?? p.enum) === parentEnum); const parentName = parent?.name || "Khác"; if (!groups[parentName]) { groups[parentName] = []; } groups[parentName].push(perm); }); // Third pass: add parent permissions that have no children as selectable items // (like ALLOW_ALL which is value 0 with no children) parentPermissions.forEach((parent) => { const parentValue = parent.value ?? parent.enum ?? 0; // Check if this parent has any children const hasChildren = childPermissions.some((child) => { const childValue = child.value ?? child.enum ?? 0; return Math.floor(childValue / 10) * 10 === parentValue; }); // If no children, add the parent itself as a selectable item if (!hasChildren) { groups[parent.name].push(parent); } }); // Remove empty groups Object.keys(groups).forEach((key) => { if (groups[key].length === 0) { delete groups[key]; } }); return groups; }, [permissions]); const handleTogglePermission = (permissionValue: number) => { setSelectedPermissions((prev) => prev.includes(permissionValue) ? prev.filter((v) => v !== permissionValue) : [...prev, permissionValue] ); }; const handleSelectAll = (categoryPermissions: Permission[]) => { const allValues = categoryPermissions.map((p) => getPermValue(p)); const allSelected = allValues.every((v) => selectedPermissions.includes(v)); if (allSelected) { setSelectedPermissions((prev) => prev.filter((v) => !allValues.includes(v)) ); } else { setSelectedPermissions((prev) => [...new Set([...prev, ...allValues])]); } }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!roleName.trim()) { toast.error("Vui lòng nhập tên role!"); return; } try { await createMutation.mutateAsync({ RoleName: roleName, Priority: priority, PermissionIds: selectedPermissions, }); toast.success("Tạo role thành công!"); navigate({ to: "/role" }); } catch (error) { toast.error("Tạo role thất bại!"); } }; return (
{/* Header */}

Tạo Role mới

Tạo vai trò mới và gán quyền hạn

{/* Role Info */} Thông tin Role Nhập thông tin cơ bản của role
setRoleName(e.target.value)} placeholder="Nhập tên role..." required />
setPriority(Number(e.target.value))} placeholder="0" />
{/* Permissions Selection */} Chọn quyền hạn Chọn các quyền mà role này được phép thực hiện ({selectedPermissions.length} đã chọn) {permissionsLoading ? (
Đang tải danh sách quyền...
) : (
{Object.entries(groupedPermissions).map(([category, perms]) => (

{category}

{perms.map((perm) => { const permValue = getPermValue(perm); return (
handleTogglePermission(permValue)} />
); })}
))}
)}
{/* Submit */}
); }