287 lines
6.5 KiB
TypeScript
287 lines
6.5 KiB
TypeScript
import React, { useState } from "react";
|
|
import {
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableContainer,
|
|
TableHead,
|
|
TableRow,
|
|
Paper,
|
|
Checkbox,
|
|
Typography,
|
|
Box,
|
|
Grid,
|
|
Button,
|
|
FormControlLabel,
|
|
Snackbar,
|
|
} from "@mui/material";
|
|
import { useNavigate } from "react-router-dom"; // Import useNavigate
|
|
import { useDispatch, useSelector } from "react-redux";
|
|
import { createRole } from "../../redux/slices/roleSlice"; // Import the createRole action
|
|
import { AppDispatch, RootState } from "../../redux/store/store"; // Assuming this is the path to your store file
|
|
import { toast } from "sonner";
|
|
import {
|
|
CustomTextField,
|
|
} from "../../components/AddUserModel/styled.css.tsx";
|
|
// Define the data structure for permission
|
|
interface Permission {
|
|
module: string;
|
|
list: boolean;
|
|
add: boolean;
|
|
edit: boolean;
|
|
view: boolean;
|
|
delete: boolean;
|
|
}
|
|
|
|
// Initial sample data
|
|
const initialPermissions: Permission[] = [
|
|
{
|
|
module: "User Management",
|
|
list: false,
|
|
add: false,
|
|
edit: false,
|
|
view: false,
|
|
delete: false,
|
|
},
|
|
{
|
|
module: "Role Management",
|
|
list: false,
|
|
add: false,
|
|
edit: false,
|
|
view: false,
|
|
delete: false,
|
|
},
|
|
// Add other modules as needed
|
|
];
|
|
|
|
// Table component
|
|
const AddEditRolePage: React.FC = () => {
|
|
const [permissions, setPermissions] =
|
|
useState<Permission[]>(initialPermissions);
|
|
const [roleName, setRoleName] = useState<string>("");
|
|
const [openSnackbar, setOpenSnackbar] = useState(false); // For snackbar (success message)
|
|
const navigate = useNavigate(); // Initialize useNavigate
|
|
const dispatch = useDispatch<AppDispatch>(); // Type the dispatch function with AppDispatch
|
|
|
|
const { loading } = useSelector(
|
|
(state: RootState) => state.roleReducer.roles
|
|
);
|
|
|
|
// Handle checkbox change
|
|
const handleCheckboxChange = (module: string, action: keyof Permission) => {
|
|
setPermissions((prevPermissions) =>
|
|
prevPermissions.map((perm) =>
|
|
perm.module === module
|
|
? { ...perm, [action]: !perm[action] }
|
|
: perm
|
|
)
|
|
);
|
|
};
|
|
|
|
// Handle role name input change
|
|
const handleRoleNameChange = (
|
|
event: React.ChangeEvent<HTMLInputElement>
|
|
) => {
|
|
setRoleName(event.target.value);
|
|
};
|
|
|
|
// Handle Back Navigation
|
|
const handleBack = () => {
|
|
navigate("/panel/role-list"); // Navigate back to Role List
|
|
};
|
|
|
|
// Handle form submission (adding role)
|
|
const handleSubmit = async () => {
|
|
if (!roleName.trim()) {
|
|
alert("Role name is required");
|
|
return;
|
|
}
|
|
|
|
const newRole = {
|
|
name: roleName,
|
|
resource: permissions.map((perm) => ({
|
|
moduleName: perm.module,
|
|
permissions: [
|
|
perm.list ? "list" : "",
|
|
perm.add ? "add" : "",
|
|
perm.edit ? "edit" : "",
|
|
perm.view ? "view" : "",
|
|
perm.delete ? "delete" : "",
|
|
].filter(Boolean),
|
|
moduleId: perm.module, // Assuming the module name can serve as the moduleId or use a unique id
|
|
})),
|
|
};
|
|
|
|
try {
|
|
// Dispatch the createRole action to create the new role
|
|
await dispatch(createRole(newRole));
|
|
|
|
// Show success message
|
|
toast.success("Role created successfully!");
|
|
setOpenSnackbar(true);
|
|
|
|
// Reset the form
|
|
setRoleName("");
|
|
setPermissions(initialPermissions);
|
|
navigate("/panel/role-list");
|
|
} catch (error) {
|
|
console.error("Error creating role:", error);
|
|
toast.error("Error creating role. Please try again.");
|
|
}
|
|
};
|
|
return (
|
|
<Box
|
|
sx={{ width: "100%", maxWidth: 1200, margin: "auto", mt: 4, px: 2 }}
|
|
>
|
|
{/* Title & Back Button Section */}
|
|
<Box
|
|
sx={{
|
|
display: "flex",
|
|
justifyContent: "space-between",
|
|
alignItems: "center",
|
|
backgroundColor: "#52ACDF",
|
|
color: "#fffff",
|
|
p: 2,
|
|
borderRadius: "8px",
|
|
mb: 2,
|
|
}}
|
|
>
|
|
<Typography variant="h6" fontWeight={600}>
|
|
Role Permissions
|
|
</Typography>
|
|
<Button variant="contained" onClick={handleBack}>
|
|
Back
|
|
</Button>
|
|
</Box>
|
|
|
|
{/* Role Name Input */}
|
|
<Box sx={{ mb: 2 }}>
|
|
<label>Role Name</label>
|
|
<CustomTextField
|
|
placeholder="Enter role name"
|
|
value={roleName}
|
|
onChange={handleRoleNameChange}
|
|
fullWidth
|
|
required
|
|
variant="outlined"
|
|
sx={{ mb: 2, mt: 2 }}
|
|
/>
|
|
</Box>
|
|
|
|
{/* Table Container */}
|
|
<TableContainer
|
|
component={Paper}
|
|
sx={{
|
|
borderRadius: "8px",
|
|
overflow: "hidden",
|
|
}}
|
|
>
|
|
<Table>
|
|
{/* Table Head */}
|
|
<TableHead>
|
|
<TableRow sx={{ backgroundColor: "#1C1C1C" }}>
|
|
<TableCell
|
|
sx={{ fontWeight: "bold", width: "30%" }}
|
|
>
|
|
Module Name
|
|
</TableCell>
|
|
<TableCell
|
|
sx={{ fontWeight: "bold", width: "70%" }}
|
|
>
|
|
<Typography>Actions</Typography>
|
|
</TableCell>
|
|
</TableRow>
|
|
</TableHead>
|
|
|
|
{/* Table Body */}
|
|
<TableBody>
|
|
{permissions.map((row, index) => (
|
|
<TableRow
|
|
key={index}
|
|
sx={{
|
|
"&:nth-of-type(odd)": {
|
|
backgroundColor: "#1C1C1C",
|
|
},
|
|
}}
|
|
>
|
|
<TableCell sx={{ fontWeight: 500 }}>
|
|
{row.module}
|
|
</TableCell>
|
|
<TableCell>
|
|
<Grid
|
|
container
|
|
spacing={1}
|
|
justifyContent="space-between"
|
|
>
|
|
{[
|
|
"list",
|
|
"add",
|
|
"edit",
|
|
"view",
|
|
"delete",
|
|
].map((action) => (
|
|
<Grid item key={action}>
|
|
<FormControlLabel
|
|
control={
|
|
<Checkbox
|
|
checked={
|
|
row[action]
|
|
}
|
|
onChange={() =>
|
|
handleCheckboxChange(
|
|
row.module,
|
|
action as keyof Permission
|
|
)
|
|
}
|
|
sx={{
|
|
color: "#1976D2",
|
|
}}
|
|
/>
|
|
}
|
|
label={
|
|
action
|
|
.charAt(0)
|
|
.toUpperCase() +
|
|
action.slice(1)
|
|
}
|
|
/>
|
|
</Grid>
|
|
))}
|
|
</Grid>
|
|
</TableCell>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
</TableContainer>
|
|
|
|
{/* Submit Button */}
|
|
<Box sx={{ mt: 2, display: "flex", justifyContent: "flex-end" }}>
|
|
<Button
|
|
onClick={handleSubmit}
|
|
disabled={loading}
|
|
sx={{
|
|
backgroundColor: "#52ACDF",
|
|
color: "white",
|
|
borderRadius: "8px",
|
|
width: "117px",
|
|
"&:hover": { backgroundColor: "#439BC1" },
|
|
}}
|
|
>
|
|
{loading ? "Saving..." : "Save Role"}
|
|
</Button>
|
|
</Box>
|
|
|
|
{/* Snackbar for success message */}
|
|
<Snackbar
|
|
open={openSnackbar}
|
|
autoHideDuration={3000}
|
|
onClose={() => setOpenSnackbar(false)}
|
|
message="Role added successfully!"
|
|
/>
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
export default AddEditRolePage;
|