login, usermanagement, role

This commit is contained in:
unknown
2025-01-14 20:31:57 +07:00
parent 2781e9181d
commit 7772062831
19 changed files with 1633 additions and 28 deletions

View File

@ -1,7 +1,8 @@
import React, { useState } from "react";
import { TextField, Button, Box, Typography, Grid, Paper } from "@mui/material";
import {Link, useNavigate } from 'react-router-dom';
// import { fetchApi } from '../config/axios';
import Cookies from "js-cookie";
import { fetchApi } from '../config/axios';
const LoginPage = () => {
// State for email and password
@ -15,14 +16,14 @@ const LoginPage = () => {
e.preventDefault();
if (username && password) {
// GET CREDIENTIAL
// let user = await fetchApi('/api/login', 'POST', { username, password });
// console.log(user);
// if (user.data && user.data.data) {
// let userLogin = user.data.data;
// }
// document.cookie = `role=${role}`
localStorage.setItem('authToken', username)
let user = await fetchApi('/api/login', 'POST', { username, password });
if (user.data && user.data.data) {
let userLogin = user.data.data;
Cookies.set('token', userLogin.token.access_token, { expires: 7, path: '/' });
Cookies.set('role', userLogin.role_name);
Cookies.set('username', userLogin.user.username);
// localStorage.setItem('token', userLogin.token.access_token)
}
navigate('/');
} else {
alert("Please fill in both fields.");

View File

@ -244,7 +244,7 @@ export default function ManageGroups() {
<TablePagination
rowsPerPageOptions={[10, 25, 100]}
component="div"
count={rows.length}
count={rows.data.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}

169
src/pages/RoleManagement.js Normal file
View File

@ -0,0 +1,169 @@
import React, { useState } from 'react';
import {
Container,
Typography,
Button,
Dialog,
DialogTitle,
DialogContent,
DialogActions,
TextField,
IconButton,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Checkbox,
Paper,
Box
} from '@mui/material';
import AddIcon from '@mui/icons-material/Add';
// Initial list of roles and menus
const initialRoles = ['Admin', 'Escrow', 'Agent'];
const menus = [
'Dashboard',
'Users',
'Reports',
'Settings',
'Notifications',
'Profile',
'Help',
'Logs',
'Analytics',
'Billing',
];
const RoleMenuTable = () => {
const [roles, setRoles] = useState(initialRoles);
const [roleMenus, setRoleMenus] = useState(
initialRoles.reduce((acc, role) => ({ ...acc, [role]: [] }), {})
);
const [openDialog, setOpenDialog] = useState(false);
const [newRole, setNewRole] = useState('');
const [confirmDialog, setConfirmDialog] = useState({ open: false, role: '', menu: '' });
const handleCheckboxChange = (role, menu) => {
setConfirmDialog({ open: true, role, menu });
};
const handleConfirm = (confirm) => {
const { role, menu } = confirmDialog;
if (confirm) {
setRoleMenus((prev) => {
const isChecked = prev[role].includes(menu);
const updatedMenus = isChecked
? prev[role].filter((m) => m !== menu)
: [...prev[role], menu];
return { ...prev, [role]: updatedMenus };
});
}
setConfirmDialog({ open: false, role: '', menu: '' });
};
const handleAddRole = () => {
if (newRole.trim() && !roles.includes(newRole)) {
setRoles((prevRoles) => [...prevRoles, newRole]);
setRoleMenus((prevMenus) => ({ ...prevMenus, [newRole]: [] }));
}
setNewRole('');
setOpenDialog(false);
};
return (
<Container>
<Typography variant="h4" align="center" gutterBottom marginTop={5}>
Role Menu Management
</Typography>
<IconButton
style={{ position: 'absolute', top: 16, right: 16 }}
color="primary"
onClick={() => setOpenDialog(true)}
>
<AddIcon />
</IconButton>
<Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', pr: 2, }}>
<Button variant="contained" color="primary" onClick={() => setOpenDialog(true)}>Create Role</Button>
</Box>
{/* Table for roles and menus */}
<TableContainer component={Paper} style={{ marginTop: '20px' }}>
<Table>
<TableHead>
<TableRow>
<TableCell><strong>Role</strong></TableCell>
{menus.map((menu) => (
<TableCell key={menu} align="center"><strong>{menu}</strong></TableCell>
))}
<TableCell><strong>Action</strong></TableCell>
</TableRow>
</TableHead>
<TableBody>
{roles.map((role) => (
<TableRow key={role}>
<TableCell>{role}</TableCell>
{menus.map((menu) => (
<TableCell key={menu} align="center">
<Checkbox
checked={roleMenus[role].includes(menu)}
onChange={() => handleCheckboxChange(role, menu)}
/>
</TableCell>
))}
<TableCell align="center">
<Button>Delete</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
{/* Dialog for adding new role */}
<Dialog open={openDialog} onClose={() => setOpenDialog(false)}>
<DialogTitle>Add New Role</DialogTitle>
<DialogContent>
<TextField
autoFocus
margin="dense"
label="Role Name"
type="text"
fullWidth
value={newRole}
onChange={(e) => setNewRole(e.target.value)}
/>
</DialogContent>
<DialogActions>
<Button onClick={() => setOpenDialog(false)} color="secondary">
Cancel
</Button>
<Button onClick={handleAddRole} color="primary">
Add
</Button>
</DialogActions>
</Dialog>
{/* Confirmation Dialog for checkbox */}
<Dialog open={confirmDialog.open} onClose={() => handleConfirm(false)}>
<DialogTitle>Confirm Menu Selection</DialogTitle>
<DialogContent>
Are you sure you want to {roleMenus[confirmDialog.role]?.includes(confirmDialog.menu) ? 'remove' : 'add'}
the menu <strong>{confirmDialog.menu}</strong> for role <strong>{confirmDialog.role}</strong>?
</DialogContent>
<DialogActions>
<Button onClick={() => handleConfirm(false)} color="secondary">
Cancel
</Button>
<Button onClick={() => handleConfirm(true)} color="primary">
Confirm
</Button>
</DialogActions>
</Dialog>
</Container>
);
};
export default RoleMenuTable;

252
src/pages/UserManagement.js Normal file
View File

@ -0,0 +1,252 @@
// Import React and Material-UI components
import React, { useState, useEffect } from 'react';
import {
Paper, Button, Dialog, DialogActions, DialogContent, DialogTitle, TableContainer,
Checkbox, FormControlLabel, Box, Typography, TextField, Grid
} from '@mui/material';
import ReusableTable from '../components/Table';
const columns = [
{ id: 'name', label: 'Name' },
{ id: 'email', label: 'Email' },
{ id: 'roles', label: 'Roles' },
{ id: 'actions', label: 'Actions' },
];
const initialUsers = [
{ id: 1, name: 'John Doe', email: 'john@example.com', roles: ['User'] },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', roles: ['Admin'] },
{ id: 3, name: 'Alice Johnson', email: 'alice@example.com', roles: [] }
];
const availableRoles = ['User', 'Admin', 'Editor'];
export default function UserManagement() {
const [users, setUsers] = useState(initialUsers);
const [open, setOpen] = useState(false);
const [selectedUser, setSelectedUser] = useState(null);
const [selectedRoles, setSelectedRoles] = useState([]);
const [openDialog, setOpenDialog] = useState(false);
const [formData, setFormData] = useState({
name: '',
email: '',
telp: '',
address: '',
password: '',
confirmPassword: '',
});
const [errors, setErrors] = useState({
passwordMatch: false,
});
useEffect(() => {
fetchUser()
// eslint-disable-next-line
}, []);
async function fetchUser(params) {
let temp = users.map(el => {
el.actions = [
{ label: 'Edit Role', color: 'primary', onClick: (row) => handleOpen(row) },
{ label: 'Delete', color: 'secondary', onClick: (row) => handleDelete(row) },
{ label: 'View', color: 'info', onClick: (row) => alert(`Viewing ${row.name}`) },
]
return el
})
setUsers(temp)
}
const handleOpen = (user) => {
setSelectedUser(user);
setSelectedRoles(user.roles);
setOpen(true);
};
const handleClose = () => {
setOpen(false);
setSelectedUser(null);
setSelectedRoles([]);
};
const handleRoleChange = (role) => {
setSelectedRoles((prevRoles) =>
prevRoles.includes(role)
? prevRoles.filter((r) => r !== role)
: [...prevRoles, role]
);
};
const handleDelete = (row) => {
const newData = users.filter((item) => item.id !== row.id);
setUsers(newData);
alert(`Deleted ${row.name}`);
};
const handleSave = () => {
setUsers((prevUsers) =>
prevUsers.map((user) =>
user.id === selectedUser.id ? { ...user, roles: selectedRoles } : user
)
);
handleClose();
};
const handleChange = (e) => {
const { name, value } = e.target;
setFormData((prev) => ({ ...prev, [name]: value }));
if (name === 'confirmPassword' || name === 'password') {
setErrors((prev) => ({
...prev,
passwordMatch: name === 'confirmPassword' ? value !== formData.password : formData.confirmPassword !== value,
}));
}
};
const handleSubmit = () => {
if (!errors.passwordMatch) {
console.log('Form Data:', formData);
setOpen(false);
setFormData({
name: '',
email: '',
telp: '',
address: '',
password: '',
confirmPassword: '',
});
}
}
return (
<Box sx={{ padding: 3 }}>
<Box sx={{ display: 'flex', justifyContent: 'flex-start', pr: 2, }}>
<Typography sx={{ color: 'gray', fontSize: '30px' }}>User Management</Typography>
</Box>
<Box p={3}>
<Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', pr: 2, }}>
<Button variant="contained" color="primary" onClick={() => setOpenDialog(true)}>Create New User</Button>
</Box>
<TableContainer component={Paper} sx={{ marginTop: 3 }}>
<ReusableTable columns={columns} data={users} />
<Dialog open={open} onClose={handleClose}>
<DialogTitle>Add Roles to {selectedUser?.name}</DialogTitle>
<DialogContent>
{availableRoles.map((role) => (
<FormControlLabel
key={role}
control={
<Checkbox
checked={selectedRoles.includes(role)}
onChange={() => handleRoleChange(role)}
/>
}
label={role}
/>
))}
</DialogContent>
<DialogActions>
<Button onClick={handleClose} color="secondary">
Cancel
</Button>
<Button onClick={handleSave} color="primary" variant="contained">
Save
</Button>
</DialogActions>
</Dialog>
</TableContainer>
<Dialog open={openDialog} onClose={() => setOpenDialog(false)} maxWidth="sm" fullWidth>
<DialogTitle>Create User</DialogTitle>
<DialogContent sx={{ marginTop: 2 }}>
<Grid container spacing={2}>
<Grid item xs={12}>
<TextField
sx={{ marginTop: 2 }}
label="Name"
name="name"
value={formData.name}
onChange={handleChange}
fullWidth
required
/>
</Grid>
<Grid item xs={12}>
<TextField
label="Email"
name="email"
value={formData.email}
onChange={handleChange}
fullWidth
type="email"
required
/>
</Grid>
<Grid item xs={12}>
<TextField
label="Telephone"
name="telp"
value={formData.telp}
onChange={handleChange}
fullWidth
type="tel"
required
/>
</Grid>
<Grid item xs={12}>
<TextField
label="Address"
name="address"
value={formData.address}
onChange={handleChange}
fullWidth
multiline
rows={3}
required
/>
</Grid>
<Grid item xs={12}>
<TextField
label="Password"
name="password"
value={formData.password}
onChange={handleChange}
fullWidth
type="password"
required
/>
</Grid>
<Grid item xs={12}>
<TextField
label="Confirm Password"
name="confirmPassword"
value={formData.confirmPassword}
onChange={handleChange}
fullWidth
type="password"
error={errors.passwordMatch}
helperText={errors.passwordMatch ? "Passwords do not match" : ""}
required
/>
</Grid>
</Grid>
</DialogContent>
<DialogActions>
<Button onClick={() => setOpenDialog(false)} color="secondary">
Cancel
</Button>
<Button
onClick={handleSubmit}
color="primary"
disabled={!formData.name || !formData.email || !formData.telp || !formData.address || !formData.password || errors.passwordMatch}
>
Submit
</Button>
</DialogActions>
</Dialog>
</Box>
</Box>
);
}