inspiren-sem-tool/resources/js/forms/management/RoleForm.tsx

115 lines
4.1 KiB
TypeScript

import { Role, FormStatus, PermissionList } from "@/types";
import { useForm } from "@inertiajs/react";
import { Button, Checkbox, SimpleGrid, Stack, Text, TextInput } from "@mantine/core";
import { IconDeviceFloppy } from "@tabler/icons-react";
import React from "react";
interface Props {
role?: Role;
status: FormStatus;
permissions: PermissionList;
}
export default function UserForm({ role, status, permissions }: Props) {
// 1. Initialize form with the permissions passed from PHP
const { data, setData, post, put, processing, errors } = useForm({
name: role?.name || '',
permissions: permissions,
});
// Handle individual permission toggle
const handlePermissionChange = (group: string, index: number, checked: boolean) => {
const updatedPermissions = { ...data.permissions };
if (updatedPermissions[group] && updatedPermissions[group][index]) {
// Create a new object for the specific permission to trigger state update
updatedPermissions[group][index] = {
...updatedPermissions[group][index],
checked
};
setData('permissions', updatedPermissions);
}
};
// Handle "Check All" for a specific group
const handleGroupCheckboxChange = (group: string, checked: boolean) => {
const updatedPermissions = { ...data.permissions };
if (updatedPermissions[group]) {
updatedPermissions[group] = updatedPermissions[group].map(p => ({
...p,
checked
}));
setData('permissions', updatedPermissions);
}
};
function submit(event: React.FormEvent) {
event.preventDefault();
if (status === 'create') {
post(route('management.roles.store'));
} else {
// Use put() for updates if your route is Route::put
post(route('management.roles.update', { id: role?.id }));
}
}
// IMPORTANT: Map over data.permissions (state), not permissions (prop)
const permissionCheckboxes = Object.entries(data.permissions).map(([group, list]) => {
const allChecked = list.every(p => p.checked);
const someChecked = list.some(p => p.checked);
return (
<Stack key={group} spacing="xs">
<Checkbox
label={<Text fw={600}>{group}</Text>}
checked={allChecked}
indeterminate={someChecked && !allChecked}
onChange={(e) => handleGroupCheckboxChange(group, e.target.checked)}
/>
<SimpleGrid cols={1}>
{list.map((permission, index) => (
<Checkbox
key={permission.id}
ml={20}
label={<Text size="sm">{permission.description}</Text>}
checked={permission.checked}
onChange={(e) => handlePermissionChange(group, index, e.target.checked)}
/>
))}
</SimpleGrid>
</Stack>
);
});
return (
<form onSubmit={submit}>
<Stack spacing="xl">
<TextInput
label="Role Name"
value={data.name}
onChange={(e) => setData('name', e.target.value)}
error={errors.name}
required
/>
<Stack spacing={5}>
<Text fw={500}>Permissions</Text>
<SimpleGrid cols={4} spacing="lg" verticalSpacing="xl">
{permissionCheckboxes}
</SimpleGrid>
</Stack>
<Button
type="submit"
loading={processing}
leftIcon={<IconDeviceFloppy size={18} />}
style={{ width: 'fit-content' }}
>
Save Role
</Button>
</Stack>
</form>
);
}