update base url
This commit is contained in:
2
.env
Normal file
2
.env
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
REACT_APP_BASE_URL=/dashboard
|
||||||
|
REACT_APP_API_URL=https://tpay.shiblysolution.id/api/
|
||||||
112
package.json
112
package.json
@ -1,58 +1,58 @@
|
|||||||
{
|
{
|
||||||
"name": "new-tpay",
|
"name": "new-tpay",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.14.0",
|
"@emotion/react": "^11.14.0",
|
||||||
"@emotion/styled": "^11.14.0",
|
"@emotion/styled": "^11.14.0",
|
||||||
"@mui/icons-material": "^6.2.1",
|
"@mui/icons-material": "^6.2.1",
|
||||||
"@mui/material": "^6.2.1",
|
"@mui/material": "^6.2.1",
|
||||||
"@reduxjs/toolkit": "^2.5.0",
|
"@reduxjs/toolkit": "^2.5.0",
|
||||||
"@testing-library/jest-dom": "^5.17.0",
|
"@testing-library/jest-dom": "^5.17.0",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"ajv": "^8.17.1",
|
"ajv": "^8.17.1",
|
||||||
"ajv-keywords": "^5.1.0",
|
"ajv-keywords": "^5.1.0",
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
"chart.js": "^4.4.7",
|
"chart.js": "^4.4.7",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-chartjs-2": "^5.2.0",
|
"react-chartjs-2": "^5.2.0",
|
||||||
"react-circular-progressbar": "^2.1.0",
|
"react-circular-progressbar": "^2.1.0",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-redux": "^9.2.0",
|
"react-redux": "^9.2.0",
|
||||||
"react-router-dom": "^7.1.1",
|
"react-router-dom": "^7.1.1",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"redux": "^5.0.1",
|
"redux": "^5.0.1",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start eslint-disable-next-line",
|
"start": "react-scripts start eslint-disable-next-line",
|
||||||
"build": "react-scripts build",
|
"build": "react-scripts build",
|
||||||
"test": "react-scripts test",
|
"test": "react-scripts test",
|
||||||
"eject": "react-scripts eject"
|
"eject": "react-scripts eject"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": [
|
"extends": [
|
||||||
"react-app",
|
"react-app",
|
||||||
"react-app/jest"
|
"react-app/jest"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"production": [
|
"production": [
|
||||||
">0.2%",
|
">0.2%",
|
||||||
"not dead",
|
"not dead",
|
||||||
"not op_mini all"
|
"not op_mini all"
|
||||||
],
|
],
|
||||||
"development": [
|
"development": [
|
||||||
"last 1 chrome version",
|
"last 1 chrome version",
|
||||||
"last 1 firefox version",
|
"last 1 firefox version",
|
||||||
"last 1 safari version"
|
"last 1 safari version"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
||||||
"@babel/plugin-transform-private-property-in-object": "^7.25.9",
|
"@babel/plugin-transform-private-property-in-object": "^7.25.9",
|
||||||
"@testing-library/dom": "^10.4.0",
|
"@testing-library/dom": "^10.4.0",
|
||||||
"@testing-library/react": "^16.1.0"
|
"@testing-library/react": "^16.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,31 +1,32 @@
|
|||||||
import axios from 'axios';
|
import axios from "axios"
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie"
|
||||||
|
|
||||||
const token = Cookies.get(`token`) || null;
|
const token = Cookies.get(`token`) || null
|
||||||
const headers = {
|
const headers = {
|
||||||
"Access-Control-Allow-Origin": "*",
|
// "Access-Control-Allow-Origin": "*",
|
||||||
"content-type":"application/json",
|
// "content-type": "application/json",
|
||||||
};
|
}
|
||||||
if (token) headers["Authorization"] = `Bearer ${token}`;
|
if (token) headers["Authorization"] = `Bearer ${token}`
|
||||||
|
|
||||||
const instance = axios.create({
|
const instance = axios.create({
|
||||||
baseURL: `https://tpay.shiblysolution.id/dashboard/`,
|
// baseURL: `https://tpay.shiblysolution.id/dashboard/`,
|
||||||
// baseURL: 'https://api.telkomcel.tl/tpay-stg-dash-api/',
|
// baseURL: 'https://api.telkomcel.tl/tpay-stg-dash-api/',
|
||||||
headers: headers
|
baseURL: process.env.REACT_APP_API_URL,
|
||||||
|
headers: headers,
|
||||||
})
|
})
|
||||||
|
|
||||||
export async function fetchApi(path, method, data, params) {
|
export async function fetchApi(path, method, data, params) {
|
||||||
try {
|
try {
|
||||||
let query = params || {};
|
let query = params || {}
|
||||||
query.token = token
|
query.token = token
|
||||||
let response = await instance({
|
let response = await instance({
|
||||||
method: method,
|
method: method,
|
||||||
url: path,
|
url: path,
|
||||||
data: data,
|
data: data,
|
||||||
params: query
|
params: query,
|
||||||
});
|
})
|
||||||
return response
|
return response
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert(error.message)
|
alert(error.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
36
src/index.js
36
src/index.js
@ -1,24 +1,24 @@
|
|||||||
import React from "react";
|
import React from "react"
|
||||||
import ReactDOM from "react-dom/client";
|
import ReactDOM from "react-dom/client"
|
||||||
import "./index.css";
|
import "./index.css"
|
||||||
import App from "./routes/routes";
|
import App from "./routes/routes"
|
||||||
import reportWebVitals from "./reportWebVitals";
|
import reportWebVitals from "./reportWebVitals"
|
||||||
import { BrowserRouter } from "react-router-dom";
|
import { BrowserRouter } from "react-router-dom"
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from "react-redux"
|
||||||
import store from './store/store';
|
import store from "./store/store"
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(document.getElementById("root"));
|
const root = ReactDOM.createRoot(document.getElementById("root"))
|
||||||
root.render(
|
root.render(
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<BrowserRouter>
|
<BrowserRouter basename={process.env.REACT_APP_BASE_URL}>
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<App />
|
<App />
|
||||||
</React.StrictMode>
|
</React.StrictMode>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
)
|
||||||
|
|
||||||
// If you want to start measuring performance in your app, pass a function
|
// If you want to start measuring performance in your app, pass a function
|
||||||
// to log results (for example: reportWebVitals(console.log))
|
// to log results (for example: reportWebVitals(console.log))
|
||||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||||
reportWebVitals();
|
reportWebVitals()
|
||||||
|
|||||||
@ -1,135 +1,109 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react"
|
||||||
import { TextField, Button, Box, Typography, Grid, Paper, Avatar, Divider } from "@mui/material";
|
import { TextField, Button, Box, Typography, Grid, Paper, Avatar, Divider } from "@mui/material"
|
||||||
import {Link, useNavigate } from 'react-router-dom';
|
import { Link, useNavigate } from "react-router-dom"
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie"
|
||||||
import { fetchApi } from '../config/axios';
|
import { fetchApi } from "../config/axios"
|
||||||
import logo from '../logo/logo.jpeg';
|
import logo from "../logo/logo.jpeg"
|
||||||
|
|
||||||
const LoginPage = () => {
|
const LoginPage = () => {
|
||||||
// State for email and password
|
// State for email and password
|
||||||
const [username, setUsername] = useState("");
|
const [username, setUsername] = useState("")
|
||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("")
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate()
|
||||||
|
|
||||||
// Handle form submission
|
// Handle form submission
|
||||||
const handleSubmit = async (e) => {
|
const handleSubmit = async (e) => {
|
||||||
try {
|
try {
|
||||||
e.preventDefault();
|
e.preventDefault()
|
||||||
if (username && password) {
|
if (username && password) {
|
||||||
// GET CREDIENTIAL
|
// GET CREDIENTIAL
|
||||||
let user = await fetchApi('/api/login', 'POST', { username, password });
|
let user = await fetchApi("/d/login", "POST", { username, password })
|
||||||
if (user) {
|
if (user) {
|
||||||
if (user.data && user.data.data) {
|
if (user.data && user.data.data) {
|
||||||
let resUserLogin = user.data.data;
|
let resUserLogin = user.data.data
|
||||||
console.log('resUserLogin', resUserLogin);
|
console.log("resUserLogin", resUserLogin)
|
||||||
let roleList = JSON.stringify(resUserLogin.roles_list);
|
let roleList = JSON.stringify(resUserLogin.roles_list)
|
||||||
Cookies.set('token', resUserLogin.token.access_token, { expires: 1, path: '/' });
|
Cookies.set("token", resUserLogin.token.access_token, { expires: 1, path: "/" })
|
||||||
Cookies.set('role', resUserLogin.role_name, { expires: 1, path: '/' });
|
Cookies.set("role", resUserLogin.role_name, { expires: 1, path: "/" })
|
||||||
Cookies.set('userId', resUserLogin.user.id, { expires: 1, path: '/' });
|
Cookies.set("userId", resUserLogin.user.id, { expires: 1, path: "/" })
|
||||||
Cookies.set('username', resUserLogin.user.username, { expires: 1, path: '/' });
|
Cookies.set("username", resUserLogin.user.username, { expires: 1, path: "/" })
|
||||||
// Cookies.set('roles_list', roleList, { expires: 1, path: '/' });
|
// Cookies.set('roles_list', roleList, { expires: 1, path: '/' });
|
||||||
localStorage.setItem('roles_list', roleList)
|
localStorage.setItem("roles_list", roleList)
|
||||||
navigate('/');
|
navigate("/")
|
||||||
} else {
|
} else {
|
||||||
alert(user.response.data.message);
|
alert(user.response.data.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alert("Please fill in both fields.");
|
alert("Please fill in both fields.")
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.response) alert(error.response.data.message)
|
if (error.response) alert(error.response.data.message)
|
||||||
else alert(error.message)
|
else alert(error.message)
|
||||||
console.log(error);
|
console.log(error)
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid
|
<Grid container justifyContent="center" alignItems="center" style={{ minHeight: "100vh", backgroundColor: "#f4f6f8" }}>
|
||||||
container
|
<Grid item xs={12} sm={6} md={4}>
|
||||||
justifyContent="center"
|
<Paper elevation={3} sx={{ padding: 3 }}>
|
||||||
alignItems="center"
|
<Typography variant="h5" align="center" gutterBottom>
|
||||||
style={{ minHeight: "100vh", backgroundColor: "#f4f6f8" }}
|
Login
|
||||||
>
|
</Typography>
|
||||||
<Grid item xs={12} sm={6} md={4}>
|
<form onSubmit={handleSubmit}>
|
||||||
<Paper elevation={3} sx={{ padding: 3 }}>
|
<Box mb={2}>
|
||||||
<Typography variant="h5" align="center" gutterBottom>
|
<TextField label="Email" variant="outlined" fullWidth value={username} onChange={(e) => setUsername(e.target.value)} type="text" required />
|
||||||
Login
|
</Box>
|
||||||
</Typography>
|
<Box mb={2}>
|
||||||
<form onSubmit={handleSubmit}>
|
<TextField label="Password" variant="outlined" fullWidth value={password} onChange={(e) => setPassword(e.target.value)} type="password" required />
|
||||||
<Box mb={2}>
|
</Box>
|
||||||
<TextField
|
<Box mt={2} textAlign="center">
|
||||||
label="Email"
|
<Button>
|
||||||
variant="outlined"
|
<Link to="/register">Register</Link>
|
||||||
fullWidth
|
</Button>
|
||||||
value={username}
|
<Button variant="contained" color="primary" type="submit" fullWidth>
|
||||||
onChange={(e) => setUsername(e.target.value)}
|
Login
|
||||||
type="text"
|
</Button>
|
||||||
required
|
</Box>
|
||||||
/>
|
</form>
|
||||||
</Box>
|
</Paper>
|
||||||
<Box mb={2}>
|
</Grid>
|
||||||
<TextField
|
<Box
|
||||||
label="Password"
|
sx={{
|
||||||
variant="outlined"
|
width: "100%",
|
||||||
fullWidth
|
position: "fixed",
|
||||||
value={password}
|
bottom: 0,
|
||||||
onChange={(e) => setPassword(e.target.value)}
|
textAlign: "center",
|
||||||
type="password"
|
bgcolor: "#f9f9f9", // Background color
|
||||||
required
|
py: 2, // Padding
|
||||||
/>
|
}}
|
||||||
</Box>
|
>
|
||||||
<Box mt={2} textAlign="center">
|
{/* Divider (Horizontal Line) */}
|
||||||
<Button>
|
<Divider sx={{ mb: 2 }} />
|
||||||
<Link to="/register">Register</Link>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
type="submit"
|
|
||||||
fullWidth
|
|
||||||
>
|
|
||||||
Login
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
</form>
|
|
||||||
</Paper>
|
|
||||||
</Grid>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
width: "100%",
|
|
||||||
position: "fixed",
|
|
||||||
bottom: 0,
|
|
||||||
textAlign: "center",
|
|
||||||
bgcolor: "#f9f9f9", // Background color
|
|
||||||
py: 2, // Padding
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{/* Divider (Horizontal Line) */}
|
|
||||||
<Divider sx={{ mb: 2 }} />
|
|
||||||
|
|
||||||
{/* Content */}
|
|
||||||
<Box justifyItems={'center'}
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center", // Align items vertically
|
|
||||||
justifyContent: "center", // Center content horizontally
|
|
||||||
gap: 1, // Space between logo and text
|
|
||||||
mt: 2, // Optional margin-top
|
|
||||||
}}>
|
|
||||||
<Avatar
|
|
||||||
src={logo}
|
|
||||||
alt="T-PAY"
|
|
||||||
sx={{ backgroundColor: 'red', width: '50px', height: '50px' }}
|
|
||||||
/>
|
|
||||||
<Typography variant="h6" sx={{ fontWeight: "bold" }}>T-PAY</Typography>
|
|
||||||
</Box>
|
|
||||||
<Typography variant="body2" sx={{ color: "gray" }}>
|
|
||||||
© 2025 TelinDigital Solution
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</Grid>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default LoginPage;
|
{/* Content */}
|
||||||
|
<Box
|
||||||
|
justifyItems={"center"}
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center", // Align items vertically
|
||||||
|
justifyContent: "center", // Center content horizontally
|
||||||
|
gap: 1, // Space between logo and text
|
||||||
|
mt: 2, // Optional margin-top
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Avatar src={logo} alt="T-PAY" sx={{ backgroundColor: "red", width: "50px", height: "50px" }} />
|
||||||
|
<Typography variant="h6" sx={{ fontWeight: "bold" }}>
|
||||||
|
T-PAY
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Typography variant="body2" sx={{ color: "gray" }}>
|
||||||
|
© 2025 TelinDigital Solution
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Grid>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LoginPage
|
||||||
|
|||||||
@ -1,184 +1,144 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from "react"
|
||||||
import {
|
import { TextField, Button, Box, Typography, Paper, FormControl, Select, InputLabel, MenuItem, FormControlLabel, Checkbox, FormLabel } from "@mui/material"
|
||||||
TextField,
|
import { fetchApi } from "../config/axios"
|
||||||
Button,
|
import WarningDialog from "../components/WarningDialog"
|
||||||
Box,
|
import Cookies from "js-cookie"
|
||||||
Typography,
|
|
||||||
Paper,
|
|
||||||
FormControl,
|
|
||||||
Select,
|
|
||||||
InputLabel,
|
|
||||||
MenuItem,
|
|
||||||
FormControlLabel,
|
|
||||||
Checkbox,
|
|
||||||
FormLabel
|
|
||||||
} from "@mui/material";
|
|
||||||
import { fetchApi } from '../config/axios';
|
|
||||||
import WarningDialog from '../components/WarningDialog';
|
|
||||||
import Cookies from "js-cookie";
|
|
||||||
|
|
||||||
const ProfilePage = () => {
|
const ProfilePage = () => {
|
||||||
// State for form fields
|
// State for form fields
|
||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
username: '',
|
username: "",
|
||||||
name: '',
|
name: "",
|
||||||
email: '',
|
email: "",
|
||||||
status: '',
|
status: "",
|
||||||
idRole: '',
|
idRole: "",
|
||||||
password: '',
|
password: "",
|
||||||
oldPassword: '',
|
oldPassword: "",
|
||||||
confirmPassword: '',
|
confirmPassword: "",
|
||||||
newPassword: ''
|
newPassword: "",
|
||||||
// nik: '',
|
// nik: '',
|
||||||
// position: '',
|
// position: '',
|
||||||
// telp: '',
|
// telp: '',
|
||||||
// address: '',
|
// address: '',
|
||||||
// organisasi: '',
|
// organisasi: '',
|
||||||
// devisi: '',
|
// devisi: '',
|
||||||
// unit: '',
|
// unit: '',
|
||||||
});
|
})
|
||||||
const [roles, setRoles] = useState([]);
|
const [roles, setRoles] = useState([])
|
||||||
const [isModalOpen, setIsModalOpen] = useState(false); // ERROR MSG
|
const [isModalOpen, setIsModalOpen] = useState(false) // ERROR MSG
|
||||||
const [error, setError] = useState(""); // ERROR MSG
|
const [error, setError] = useState("") // ERROR MSG
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchUser()
|
fetchUser()
|
||||||
fetchUserRoles()
|
fetchUserRoles()
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
}, []);
|
}, [])
|
||||||
|
|
||||||
async function fetchUser(params) {
|
async function fetchUser(params) {
|
||||||
try {
|
try {
|
||||||
let userId = Cookies.get(`userId`);
|
let userId = Cookies.get(`userId`)
|
||||||
let token = Cookies.get(`token`);
|
let token = Cookies.get(`token`)
|
||||||
|
|
||||||
let fetchUsers = await fetchApi(`/api/user/detail/${userId}`, 'GET', null, { token: token });
|
|
||||||
// setFormData({})
|
|
||||||
console.log(fetchUsers);
|
|
||||||
setFormData(fetchUsers.data.data)
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
handleError(`${error.message}. \n ${error.response.data.error}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchUserRoles(params) {
|
let fetchUsers = await fetchApi(`d/user/detail/${userId}`, "GET", null, { token: token })
|
||||||
try {
|
// setFormData({})
|
||||||
let userRoles = await fetchApi('/api/user_role/list', 'GET', null, {
|
console.log(fetchUsers)
|
||||||
limit: 10,
|
setFormData(fetchUsers.data.data)
|
||||||
page: 1,
|
} catch (error) {
|
||||||
with_deleted: true,
|
console.log(error)
|
||||||
order_field: 'id',
|
handleError(`${error.message}. \n ${error.response.data.error}`)
|
||||||
order_direction: 'ASC'
|
}
|
||||||
});
|
}
|
||||||
console.log(userRoles);
|
|
||||||
|
|
||||||
if (userRoles.data && userRoles.data.data) setRoles(userRoles.data.data.list)
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
handleError(`${error.message}. \n ${error.response.data.error}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle form submission
|
async function fetchUserRoles(params) {
|
||||||
const handleSubmit = (e) => {
|
try {
|
||||||
e.preventDefault();
|
let userRoles = await fetchApi("d/user_role/list", "GET", null, {
|
||||||
// if (name && email) {
|
limit: 10,
|
||||||
// // Handle registration logic, like calling an API to create the user
|
page: 1,
|
||||||
// console.log("Registered with:", { name, email });
|
with_deleted: true,
|
||||||
// } else {
|
order_field: "id",
|
||||||
// alert("Please fill in all fields.");
|
order_direction: "ASC",
|
||||||
// }
|
})
|
||||||
};
|
console.log(userRoles)
|
||||||
|
|
||||||
const handleChange = (e) => {
|
if (userRoles.data && userRoles.data.data) setRoles(userRoles.data.data.list)
|
||||||
let { name, value } = e.target;
|
} catch (error) {
|
||||||
if (name === 'status' && value === "Y") value = "N"
|
console.log(error)
|
||||||
else if (name === 'status' && value === "N") value = "Y"
|
handleError(`${error.message}. \n ${error.response.data.error}`)
|
||||||
setFormData((prev) => ({ ...prev, [name]: value }));
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleError = (msg) => { // ERROR MSG
|
// Handle form submission
|
||||||
setError(msg);
|
const handleSubmit = (e) => {
|
||||||
setIsModalOpen(true);
|
e.preventDefault()
|
||||||
};
|
// if (name && email) {
|
||||||
|
// // Handle registration logic, like calling an API to create the user
|
||||||
|
// console.log("Registered with:", { name, email });
|
||||||
|
// } else {
|
||||||
|
// alert("Please fill in all fields.");
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
const closeModal = () => { // ERROR MSG
|
const handleChange = (e) => {
|
||||||
setIsModalOpen(false);
|
let { name, value } = e.target
|
||||||
setError("");
|
if (name === "status" && value === "Y") value = "N"
|
||||||
};
|
else if (name === "status" && value === "N") value = "Y"
|
||||||
|
setFormData((prev) => ({ ...prev, [name]: value }))
|
||||||
async function updatePassword() {
|
}
|
||||||
try {
|
|
||||||
let updatePassword = await fetchApi(`/api/user/update_password`, 'PUT', {
|
|
||||||
password: formData.password,
|
|
||||||
retype_password: formData.confirmPassword
|
|
||||||
});
|
|
||||||
console.log(updatePassword);
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
const handleError = (msg) => {
|
||||||
<Box sx={{ padding: 3 }}>
|
// ERROR MSG
|
||||||
<WarningDialog // ERROR MSG
|
setError(msg)
|
||||||
open={isModalOpen}
|
setIsModalOpen(true)
|
||||||
onClose={closeModal}
|
}
|
||||||
errorMessage={error}
|
|
||||||
/>
|
const closeModal = () => {
|
||||||
<Box sx={{ display: 'flex', justifyContent: 'flex-start', pr: 2, }}>
|
// ERROR MSG
|
||||||
<Typography sx={{ color: 'gray', fontSize: '30px' }}>User Profile</Typography>
|
setIsModalOpen(false)
|
||||||
</Box>
|
setError("")
|
||||||
<Box sx={{ padding: 3 }}>
|
}
|
||||||
<Box sx={{ padding: 3 }}>
|
|
||||||
<Paper sx={{ width: '100%', overflow: 'hidden' }}>
|
async function updatePassword() {
|
||||||
<form onSubmit={handleSubmit}>
|
try {
|
||||||
<Box mb={2} m={2}>
|
let updatePassword = await fetchApi(`d/user/update_password`, "PUT", {
|
||||||
<TextField
|
password: formData.password,
|
||||||
label="Username"
|
retype_password: formData.confirmPassword,
|
||||||
name="username"
|
})
|
||||||
variant="outlined"
|
console.log(updatePassword)
|
||||||
fullWidth
|
} catch (error) {
|
||||||
value={formData.username}
|
console.log(error)
|
||||||
onChange={handleChange}
|
}
|
||||||
required
|
}
|
||||||
disabled
|
|
||||||
/>
|
return (
|
||||||
</Box>
|
<Box sx={{ padding: 3 }}>
|
||||||
<Box mb={2} m={2}>
|
<WarningDialog // ERROR MSG
|
||||||
<TextField
|
open={isModalOpen}
|
||||||
label="Name"
|
onClose={closeModal}
|
||||||
name="name"
|
errorMessage={error}
|
||||||
variant="outlined"
|
/>
|
||||||
fullWidth
|
<Box sx={{ display: "flex", justifyContent: "flex-start", pr: 2 }}>
|
||||||
value={formData.name}
|
<Typography sx={{ color: "gray", fontSize: "30px" }}>User Profile</Typography>
|
||||||
onChange={handleChange}
|
</Box>
|
||||||
required
|
<Box sx={{ padding: 3 }}>
|
||||||
/>
|
<Box sx={{ padding: 3 }}>
|
||||||
</Box>
|
<Paper sx={{ width: "100%", overflow: "hidden" }}>
|
||||||
<Box mb={2} m={2}>
|
<form onSubmit={handleSubmit}>
|
||||||
<TextField
|
<Box mb={2} m={2}>
|
||||||
label="Email"
|
<TextField label="Username" name="username" variant="outlined" fullWidth value={formData.username} onChange={handleChange} required disabled />
|
||||||
name="email"
|
</Box>
|
||||||
variant="outlined"
|
<Box mb={2} m={2}>
|
||||||
fullWidth
|
<TextField label="Name" name="name" variant="outlined" fullWidth value={formData.name} onChange={handleChange} required />
|
||||||
value={formData.email}
|
</Box>
|
||||||
onChange={handleChange}
|
<Box mb={2} m={2}>
|
||||||
type="email"
|
<TextField label="Email" name="email" variant="outlined" fullWidth value={formData.email} onChange={handleChange} type="email" required />
|
||||||
required
|
</Box>
|
||||||
/>
|
<Box mb={2} m={2} sx={{ display: "flex", justifyContent: "flex-start" }}>
|
||||||
</Box>
|
<FormLabel component="legend">
|
||||||
<Box mb={2} m={2} sx={{ display: 'flex', justifyContent: 'flex-start' }}>
|
Status :
|
||||||
<FormLabel component="legend">Status :
|
<FormControlLabel required label="Aktif" control={<Checkbox value={formData.status} name="status" onClick={handleChange} checked={formData.status === "Y" ? true : false} />} />
|
||||||
<FormControlLabel required label="Aktif" control={
|
</FormLabel>
|
||||||
<Checkbox value={formData.status} name="status" onClick={handleChange}
|
</Box>
|
||||||
checked={ formData.status === "Y" ? true : false } />
|
{/* <Box mb={2} m={2}>
|
||||||
}/>
|
|
||||||
</FormLabel>
|
|
||||||
</Box>
|
|
||||||
{/* <Box mb={2} m={2}>
|
|
||||||
<TextField
|
<TextField
|
||||||
label="NIK"
|
label="NIK"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
@ -269,94 +229,62 @@ const ProfilePage = () => {
|
|||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</Box> */}
|
</Box> */}
|
||||||
<Box mb={2} m={2}>
|
<Box mb={2} m={2}>
|
||||||
<FormControl fullWidth required>
|
<FormControl fullWidth required>
|
||||||
<InputLabel id="organization-label">Role</InputLabel>
|
<InputLabel id="organization-label">Role</InputLabel>
|
||||||
<Select
|
<Select labelId="organization-label" id="organization" value={formData.idRole} label="Role" onChange={handleChange} name="idRole">
|
||||||
labelId="organization-label"
|
{roles.map((el, idx) => (
|
||||||
id="organization"
|
<MenuItem key={idx} value={el.id}>
|
||||||
value={formData.idRole}
|
{el.name}
|
||||||
label="Role"
|
</MenuItem>
|
||||||
onChange={handleChange}
|
))}
|
||||||
name='idRole'
|
</Select>
|
||||||
>
|
</FormControl>
|
||||||
{
|
</Box>
|
||||||
roles.map((el, idx) => (
|
<Box mb={2} m={2}>
|
||||||
<MenuItem key={idx} value={el.id}>{el.name}</MenuItem>
|
<TextField label="Password" name="password" value={formData.password} onChange={handleChange} fullWidth type="password" required disabled />
|
||||||
))
|
</Box>
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
</Box>
|
|
||||||
<Box mb={2} m={2}>
|
|
||||||
<TextField
|
|
||||||
label="Password"
|
|
||||||
name="password"
|
|
||||||
value={formData.password}
|
|
||||||
onChange={handleChange}
|
|
||||||
fullWidth
|
|
||||||
type="password"
|
|
||||||
required
|
|
||||||
disabled
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box mt={2} mb={2} textAlign="center">
|
<Box mt={2} mb={2} textAlign="center">
|
||||||
<Button style={{ marginRight: '5px' }} variant="contained">Cancel</Button>
|
<Button style={{ marginRight: "5px" }} variant="contained">
|
||||||
<Button variant="contained" color="success">Submit</Button>
|
Cancel
|
||||||
</Box>
|
</Button>
|
||||||
</form>
|
<Button variant="contained" color="success">
|
||||||
</Paper>
|
Submit
|
||||||
</Box>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
|
</form>
|
||||||
|
</Paper>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<Box sx={{ padding: 3 }}>
|
<Box sx={{ padding: 3 }}>
|
||||||
<Box sx={{ padding: 3 }}>
|
<Box sx={{ padding: 3 }}>
|
||||||
<Typography sx={{ color: 'gray', fontSize: '30px' }}>User Password</Typography>
|
<Typography sx={{ color: "gray", fontSize: "30px" }}>User Password</Typography>
|
||||||
<Paper sx={{ width: '100%', overflow: 'hidden' }}>
|
<Paper sx={{ width: "100%", overflow: "hidden" }}>
|
||||||
<Box mb={2} m={2}>
|
<Box mb={2} m={2}>
|
||||||
<TextField
|
<TextField label="Old Password" name="oldPassword" value={formData.oldPassword} onChange={handleChange} fullWidth type="password" required />
|
||||||
label="Old Password"
|
</Box>
|
||||||
name="oldPassword"
|
<Box mb={2} m={2}>
|
||||||
value={formData.oldPassword}
|
<TextField label="New Password" name="newPassword" value={formData.newPassword} onChange={handleChange} fullWidth type="password" required />
|
||||||
onChange={handleChange}
|
</Box>
|
||||||
fullWidth
|
<Box mb={2} m={2}>
|
||||||
type="password"
|
<TextField label="Confirm Password" name="confirmPassword" value={formData.confirmPassword} onChange={handleChange} fullWidth type="password" required />
|
||||||
required
|
</Box>
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
<Box mb={2} m={2}>
|
|
||||||
<TextField
|
|
||||||
label="New Password"
|
|
||||||
name="newPassword"
|
|
||||||
value={formData.newPassword}
|
|
||||||
onChange={handleChange}
|
|
||||||
fullWidth
|
|
||||||
type="password"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
<Box mb={2} m={2}>
|
|
||||||
<TextField
|
|
||||||
label="Confirm Password"
|
|
||||||
name="confirmPassword"
|
|
||||||
value={formData.confirmPassword}
|
|
||||||
onChange={handleChange}
|
|
||||||
fullWidth
|
|
||||||
type="password"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box mt={2} mb={2} textAlign="center">
|
|
||||||
<Button style={{ marginRight: '5px' }} variant="contained">Cancel</Button>
|
|
||||||
<Button variant="contained" onClick={() => updatePassword} color="success">Update</Button>
|
|
||||||
</Box>
|
|
||||||
</Paper>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ProfilePage;
|
<Box mt={2} mb={2} textAlign="center">
|
||||||
|
<Button style={{ marginRight: "5px" }} variant="contained">
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button variant="contained" onClick={() => updatePassword} color="success">
|
||||||
|
Update
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Paper>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProfilePage
|
||||||
|
|||||||
@ -1,26 +1,7 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from "react"
|
||||||
import {
|
import { Container, Typography, Button, Dialog, DialogTitle, DialogContent, DialogActions, TextField, IconButton, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Checkbox, Paper, Box } from "@mui/material"
|
||||||
Container,
|
import AddIcon from "@mui/icons-material/Add"
|
||||||
Typography,
|
import { fetchApi } from "../config/axios"
|
||||||
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';
|
|
||||||
import { fetchApi } from '../config/axios';
|
|
||||||
|
|
||||||
// Initial list of roles and menus
|
// Initial list of roles and menus
|
||||||
// const initialRoles = ['Admin', 'Escrow', 'Agent'];
|
// const initialRoles = ['Admin', 'Escrow', 'Agent'];
|
||||||
@ -38,203 +19,200 @@ import { fetchApi } from '../config/axios';
|
|||||||
// ];
|
// ];
|
||||||
|
|
||||||
const RoleMenuTable = () => {
|
const RoleMenuTable = () => {
|
||||||
const [roles, setRoles] = useState([]);
|
const [roles, setRoles] = useState([])
|
||||||
// const [roleMenus, setRoleMenus] = useState([]);
|
// const [roleMenus, setRoleMenus] = useState([]);
|
||||||
const [menus, setMenus] = useState([]);
|
const [menus, setMenus] = useState([])
|
||||||
const [openDialog, setOpenDialog] = useState(false);
|
const [openDialog, setOpenDialog] = useState(false)
|
||||||
const [newRole, setNewRole] = useState('');
|
const [newRole, setNewRole] = useState("")
|
||||||
const [confirmDialog, setConfirmDialog] = useState({
|
const [confirmDialog, setConfirmDialog] = useState({
|
||||||
open: false, roleName: '', menuData: [], roleId: '', menuId: '', status: null, menuName: ''
|
open: false,
|
||||||
});
|
roleName: "",
|
||||||
|
menuData: [],
|
||||||
useEffect(() => {
|
roleId: "",
|
||||||
fetchData()
|
menuId: "",
|
||||||
// eslint-disable-next-line
|
status: null,
|
||||||
}, []);
|
menuName: "",
|
||||||
|
})
|
||||||
|
|
||||||
async function fetchData(params) {
|
useEffect(() => {
|
||||||
try {
|
fetchData()
|
||||||
let userRole = await fetchApi('/api/user_role/list', 'GET', null, {
|
// eslint-disable-next-line
|
||||||
limit: 5,
|
}, [])
|
||||||
page: 1,
|
|
||||||
with_deleted: true,
|
|
||||||
order_field: 'id',
|
|
||||||
order_direction: 'ASC'
|
|
||||||
});
|
|
||||||
let userMenu = await fetchApi('/api/menus/list', 'GET', null, {
|
|
||||||
limit: 50,
|
|
||||||
page: 1,
|
|
||||||
with_deleted: true,
|
|
||||||
order_field: 'id',
|
|
||||||
order_direction: 'ASC'
|
|
||||||
});
|
|
||||||
setMenus(userMenu.data.data.list)
|
|
||||||
|
|
||||||
console.log('role',userRole);
|
|
||||||
console.log('menu',userMenu);
|
|
||||||
if (userRole.data && userRole.data.data) setRoles(userRole.data.data.list)
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleCheckboxChange = (roleName, menuData, roleId, menuId, status, menuName) => {
|
async function fetchData(params) {
|
||||||
setConfirmDialog({ open: true, roleName, menuData, roleId, menuId, status, menuName });
|
try {
|
||||||
};
|
let userRole = await fetchApi("d/user_role/list", "GET", null, {
|
||||||
|
limit: 5,
|
||||||
|
page: 1,
|
||||||
|
with_deleted: true,
|
||||||
|
order_field: "id",
|
||||||
|
order_direction: "ASC",
|
||||||
|
})
|
||||||
|
let userMenu = await fetchApi("/api/menus/list", "GET", null, {
|
||||||
|
limit: 50,
|
||||||
|
page: 1,
|
||||||
|
with_deleted: true,
|
||||||
|
order_field: "id",
|
||||||
|
order_direction: "ASC",
|
||||||
|
})
|
||||||
|
setMenus(userMenu.data.data.list)
|
||||||
|
|
||||||
const handleConfirm = async (confirm) => {
|
console.log("role", userRole)
|
||||||
const { roleName, menuData, roleId, menuId, status } = confirmDialog;
|
console.log("menu", userMenu)
|
||||||
try {
|
if (userRole.data && userRole.data.data) setRoles(userRole.data.data.list)
|
||||||
if (confirm) {
|
} catch (error) {
|
||||||
console.log(confirm,confirmDialog);
|
console.log(error)
|
||||||
if (status) {
|
}
|
||||||
let generateRoles = menuData.filter(el => +el !== +menuId);
|
}
|
||||||
console.log(generateRoles);
|
|
||||||
let userMenu = await fetchApi(`/api/user_role/update/${roleId}`, 'PUT', {
|
|
||||||
name: roleName,
|
|
||||||
roles: generateRoles,
|
|
||||||
status: "Y"
|
|
||||||
})
|
|
||||||
console.log(userMenu);
|
|
||||||
await fetchData()
|
|
||||||
} else {
|
|
||||||
let generateRoles = menuData.filter(el => +el !== +menuId);
|
|
||||||
generateRoles.push(`${menuId}`)
|
|
||||||
console.log(generateRoles);
|
|
||||||
let userMenu = await fetchApi(`/api/user_role/update/${roleId}`, 'PUT', {
|
|
||||||
name: roleName,
|
|
||||||
roles: generateRoles,
|
|
||||||
status: "Y"
|
|
||||||
})
|
|
||||||
console.log(userMenu);
|
|
||||||
await fetchData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setConfirmDialog({ open: false, role: '', menu: '' });
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleAddRole = async () => {
|
const handleCheckboxChange = (roleName, menuData, roleId, menuId, status, menuName) => {
|
||||||
try {
|
setConfirmDialog({ open: true, roleName, menuData, roleId, menuId, status, menuName })
|
||||||
await fetchApi('/api/user_role/create', 'POST', {
|
}
|
||||||
"name": newRole,
|
|
||||||
"roles": [],
|
|
||||||
"status": "Y"
|
|
||||||
});
|
|
||||||
await fetchData();
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
setNewRole('');
|
|
||||||
setOpenDialog(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const deleteRole = async (role) => {
|
const handleConfirm = async (confirm) => {
|
||||||
try {
|
const { roleName, menuData, roleId, menuId, status } = confirmDialog
|
||||||
let resDeleteRole = await fetchApi(`/api/user_role/delete/${role.id}/true`, 'DELETE');
|
try {
|
||||||
console.log(resDeleteRole);
|
if (confirm) {
|
||||||
await fetchData();
|
console.log(confirm, confirmDialog)
|
||||||
} catch (error) {
|
if (status) {
|
||||||
console.log(error);
|
let generateRoles = menuData.filter((el) => +el !== +menuId)
|
||||||
}
|
console.log(generateRoles)
|
||||||
}
|
let userMenu = await fetchApi(`d/user_role/update/${roleId}`, "PUT", {
|
||||||
|
name: roleName,
|
||||||
|
roles: generateRoles,
|
||||||
|
status: "Y",
|
||||||
|
})
|
||||||
|
console.log(userMenu)
|
||||||
|
await fetchData()
|
||||||
|
} else {
|
||||||
|
let generateRoles = menuData.filter((el) => +el !== +menuId)
|
||||||
|
generateRoles.push(`${menuId}`)
|
||||||
|
console.log(generateRoles)
|
||||||
|
let userMenu = await fetchApi(`d/user_role/update/${roleId}`, "PUT", {
|
||||||
|
name: roleName,
|
||||||
|
roles: generateRoles,
|
||||||
|
status: "Y",
|
||||||
|
})
|
||||||
|
console.log(userMenu)
|
||||||
|
await fetchData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setConfirmDialog({ open: false, role: "", menu: "" })
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
const handleAddRole = async () => {
|
||||||
<Container>
|
try {
|
||||||
<Typography variant="h4" align="center" gutterBottom marginTop={5}>
|
await fetchApi("d/user_role/create", "POST", {
|
||||||
Role Menu Management
|
name: newRole,
|
||||||
</Typography>
|
roles: [],
|
||||||
<IconButton
|
status: "Y",
|
||||||
style={{ position: 'absolute', top: 16, right: 16 }}
|
})
|
||||||
color="primary"
|
await fetchData()
|
||||||
onClick={() => setOpenDialog(true)}
|
} catch (error) {
|
||||||
>
|
console.log(error)
|
||||||
<AddIcon />
|
}
|
||||||
</IconButton>
|
setNewRole("")
|
||||||
|
setOpenDialog(false)
|
||||||
|
}
|
||||||
|
|
||||||
<Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', pr: 2, }}>
|
const deleteRole = async (role) => {
|
||||||
<Button variant="contained" color="primary" onClick={() => setOpenDialog(true)}>Create Role</Button>
|
try {
|
||||||
</Box>
|
let resDeleteRole = await fetchApi(`d/user_role/delete/${role.id}/true`, "DELETE")
|
||||||
|
console.log(resDeleteRole)
|
||||||
|
await fetchData()
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{/* Table for roles and menus */}
|
return (
|
||||||
<TableContainer component={Paper} style={{ marginTop: '20px' }}>
|
<Container>
|
||||||
<Table>
|
<Typography variant="h4" align="center" gutterBottom marginTop={5}>
|
||||||
<TableHead>
|
Role Menu Management
|
||||||
<TableRow>
|
</Typography>
|
||||||
<TableCell><strong>Role</strong></TableCell>
|
<IconButton style={{ position: "absolute", top: 16, right: 16 }} color="primary" onClick={() => setOpenDialog(true)}>
|
||||||
{menus.map((menu, idx) => (
|
<AddIcon />
|
||||||
<TableCell key={idx} align="center"><strong>{menu.name}</strong></TableCell>
|
</IconButton>
|
||||||
))}
|
|
||||||
<TableCell><strong>Action</strong></TableCell>
|
|
||||||
</TableRow>
|
|
||||||
</TableHead>
|
|
||||||
<TableBody>
|
|
||||||
{roles.map((role) => (
|
|
||||||
<TableRow key={role.id}>
|
|
||||||
<TableCell>{role.name}</TableCell>
|
|
||||||
{menus.map((menu, idx) => (
|
|
||||||
<TableCell key={idx} align="center">
|
|
||||||
<Checkbox
|
|
||||||
checked={(role.roles.find(el => +el === menu.id)) ? true : false}
|
|
||||||
onChange={() => handleCheckboxChange(
|
|
||||||
role.name, role.roles, role.id, menu.id, (role.roles.find(el => +el === menu.id)) ? true : false, menu.name
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
))}
|
|
||||||
<TableCell align="center">
|
|
||||||
<Button onClick={() => deleteRole(role)}>Delete</Button>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</TableContainer>
|
|
||||||
|
|
||||||
{/* Dialog for adding new role */}
|
<Box sx={{ display: "flex", justifyContent: "flex-end", alignItems: "center", pr: 2 }}>
|
||||||
<Dialog open={openDialog} onClose={() => setOpenDialog(false)}>
|
<Button variant="contained" color="primary" onClick={() => setOpenDialog(true)}>
|
||||||
<DialogTitle>Add New Role</DialogTitle>
|
Create Role
|
||||||
<DialogContent>
|
</Button>
|
||||||
<TextField
|
</Box>
|
||||||
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 */}
|
{/* Table for roles and menus */}
|
||||||
<Dialog open={confirmDialog.open} onClose={() => handleConfirm(false)}>
|
<TableContainer component={Paper} style={{ marginTop: "20px" }}>
|
||||||
<DialogTitle>Confirm Menu Selection</DialogTitle>
|
<Table>
|
||||||
<DialogContent>
|
<TableHead>
|
||||||
Are you sure you want to <strong>{confirmDialog.status ? 'remove ' : 'add '}</strong>
|
<TableRow>
|
||||||
the menu <strong>{confirmDialog.menuName}</strong> for role <strong>{confirmDialog.roleName}</strong>?
|
<TableCell>
|
||||||
</DialogContent>
|
<strong>Role</strong>
|
||||||
<DialogActions>
|
</TableCell>
|
||||||
<Button onClick={() => handleConfirm(false)} color="secondary">
|
{menus.map((menu, idx) => (
|
||||||
Cancel
|
<TableCell key={idx} align="center">
|
||||||
</Button>
|
<strong>{menu.name}</strong>
|
||||||
<Button onClick={() => handleConfirm(true)} color="primary">
|
</TableCell>
|
||||||
Confirm
|
))}
|
||||||
</Button>
|
<TableCell>
|
||||||
</DialogActions>
|
<strong>Action</strong>
|
||||||
</Dialog>
|
</TableCell>
|
||||||
</Container>
|
</TableRow>
|
||||||
);
|
</TableHead>
|
||||||
};
|
<TableBody>
|
||||||
|
{roles.map((role) => (
|
||||||
|
<TableRow key={role.id}>
|
||||||
|
<TableCell>{role.name}</TableCell>
|
||||||
|
{menus.map((menu, idx) => (
|
||||||
|
<TableCell key={idx} align="center">
|
||||||
|
<Checkbox checked={role.roles.find((el) => +el === menu.id) ? true : false} onChange={() => handleCheckboxChange(role.name, role.roles, role.id, menu.id, role.roles.find((el) => +el === menu.id) ? true : false, menu.name)} />
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
<TableCell align="center">
|
||||||
|
<Button onClick={() => deleteRole(role)}>Delete</Button>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
|
||||||
export default RoleMenuTable;
|
{/* 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 <strong>{confirmDialog.status ? "remove " : "add "}</strong>
|
||||||
|
the menu <strong>{confirmDialog.menuName}</strong> for role <strong>{confirmDialog.roleName}</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
|
||||||
|
|||||||
@ -1,287 +1,247 @@
|
|||||||
// Import React and Material-UI components
|
// Import React and Material-UI components
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from "react"
|
||||||
import {
|
import { Paper, Button, Dialog, DialogActions, DialogContent, DialogTitle, TableContainer, FormLabel, Checkbox, FormControlLabel, Box, Typography, TextField, Grid, MenuItem, InputLabel, Select, FormControl } from "@mui/material"
|
||||||
Paper, Button, Dialog, DialogActions, DialogContent, DialogTitle, TableContainer, FormLabel,
|
import ReusableTable from "../components/Table"
|
||||||
Checkbox, FormControlLabel, Box, Typography, TextField, Grid, MenuItem, InputLabel, Select, FormControl
|
import { fetchApi } from "../config/axios"
|
||||||
} from '@mui/material';
|
import WarningDialog from "../components/WarningDialog" // ERROR MSG
|
||||||
import ReusableTable from '../components/Table';
|
|
||||||
import { fetchApi } from '../config/axios';
|
|
||||||
import WarningDialog from '../components/WarningDialog'; // ERROR MSG
|
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{ id: 'username', label: 'Username' },
|
{ id: "username", label: "Username" },
|
||||||
{ id: 'name', label: 'Name' },
|
{ id: "name", label: "Name" },
|
||||||
{ id: 'email', label: 'Email' },
|
{ id: "email", label: "Email" },
|
||||||
{ id: 'role_name', label: 'Roles' },
|
{ id: "role_name", label: "Roles" },
|
||||||
{ id: 'status', label: 'Status' },
|
{ id: "status", label: "Status" },
|
||||||
{ id: 'created_at', label: 'Created' },
|
{ id: "created_at", label: "Created" },
|
||||||
{ id: 'actions', label: 'Actions' },
|
{ id: "actions", label: "Actions" },
|
||||||
];
|
]
|
||||||
|
|
||||||
const initiateForm = {
|
const initiateForm = {
|
||||||
username: '',
|
username: "",
|
||||||
name: '',
|
name: "",
|
||||||
email: '',
|
email: "",
|
||||||
status: '',
|
status: "",
|
||||||
id_role: '',
|
id_role: "",
|
||||||
password: '',
|
password: "",
|
||||||
confirmPassword: '',
|
confirmPassword: "",
|
||||||
// nik: '',
|
// nik: '',
|
||||||
// position: '',
|
// position: '',
|
||||||
// telp: '',
|
// telp: '',
|
||||||
// address: '',
|
// address: '',
|
||||||
// organisasi: '',
|
// organisasi: '',
|
||||||
// devisi: '',
|
// devisi: '',
|
||||||
// unit: '',
|
// unit: '',
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function UserManagement() {
|
export default function UserManagement() {
|
||||||
const [users, setUsers] = useState([]);
|
const [users, setUsers] = useState([])
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false)
|
||||||
const [selectedUser, setSelectedUser] = useState(null);
|
const [selectedUser, setSelectedUser] = useState(null)
|
||||||
const [selectedRoles, setSelectedRoles] = useState([]);
|
const [selectedRoles, setSelectedRoles] = useState([])
|
||||||
const [roles, setRoles] = useState([]);
|
const [roles, setRoles] = useState([])
|
||||||
const [openDialog, setOpenDialog] = useState(false);
|
const [openDialog, setOpenDialog] = useState(false)
|
||||||
const [labelDialog, setLabelDialog] = useState('');
|
const [labelDialog, setLabelDialog] = useState("")
|
||||||
const [formData, setFormData] = useState(initiateForm);
|
const [formData, setFormData] = useState(initiateForm)
|
||||||
const [errors, setErrors] = useState({ passwordMatch: false, });
|
const [errors, setErrors] = useState({ passwordMatch: false })
|
||||||
const [isModalOpen, setIsModalOpen] = useState(false); // ERROR MSG
|
const [isModalOpen, setIsModalOpen] = useState(false) // ERROR MSG
|
||||||
const [error, setError] = useState(""); // ERROR MSG
|
const [error, setError] = useState("") // ERROR MSG
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchUserRoles()
|
fetchUserRoles()
|
||||||
fetchUser()
|
fetchUser()
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
}, []);
|
}, [])
|
||||||
|
|
||||||
async function fetchUser(params) {
|
async function fetchUser(params) {
|
||||||
try {
|
try {
|
||||||
let fetchUsers = await fetchApi('/api/user/list', 'GET', null, {
|
let fetchUsers = await fetchApi("d/user/list", "GET", null, {
|
||||||
limit: 5,
|
limit: 5,
|
||||||
page: 1,
|
page: 1,
|
||||||
with_deleted: true,
|
with_deleted: true,
|
||||||
order_field: 'id',
|
order_field: "id",
|
||||||
order_direction: 'ASC'
|
order_direction: "ASC",
|
||||||
});
|
})
|
||||||
console.log(fetchUsers);
|
console.log(fetchUsers)
|
||||||
if (fetchUsers.data && fetchUsers.data.data) {
|
if (fetchUsers.data && fetchUsers.data.data) {
|
||||||
let resFetchUsers = fetchUsers.data.data.list
|
let resFetchUsers = fetchUsers.data.data.list
|
||||||
let temp = resFetchUsers.map(el => {
|
let temp = resFetchUsers.map((el) => {
|
||||||
if (el.status === 'Y') el.status = 'Aktif'
|
if (el.status === "Y") el.status = "Aktif"
|
||||||
else el.status ='Tidak Aktif'
|
else el.status = "Tidak Aktif"
|
||||||
el.actions = [
|
el.actions = [
|
||||||
{ label: 'Edit', color: 'info', onClick: (row) => handleOpen(row) },
|
{ label: "Edit", color: "info", onClick: (row) => handleOpen(row) },
|
||||||
{ label: 'Delete', color: 'secondary', onClick: (row) => handleDelete(row) },
|
{ label: "Delete", color: "secondary", onClick: (row) => handleDelete(row) },
|
||||||
]
|
]
|
||||||
return el
|
return el
|
||||||
})
|
})
|
||||||
setUsers(temp)
|
setUsers(temp)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
handleError(`${error.message}. \n ${error.response.data.error}`)
|
handleError(`${error.message}. \n ${error.response.data.error}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchUserRoles(params) {
|
async function fetchUserRoles(params) {
|
||||||
try {
|
try {
|
||||||
let userRoles = await fetchApi('/api/user_role/list', 'GET', null, {
|
let userRoles = await fetchApi("d/user_role/list", "GET", null, {
|
||||||
limit: 5,
|
limit: 5,
|
||||||
page: 1,
|
page: 1,
|
||||||
with_deleted: true,
|
with_deleted: true,
|
||||||
order_field: 'id',
|
order_field: "id",
|
||||||
order_direction: 'ASC'
|
order_direction: "ASC",
|
||||||
});
|
})
|
||||||
if (userRoles.data && userRoles.data.data) setRoles(userRoles.data.data.list)
|
if (userRoles.data && userRoles.data.data) setRoles(userRoles.data.data.list)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
handleError(`${error.message}. \n ${error.response.data.error}`)
|
handleError(`${error.message}. \n ${error.response.data.error}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleOpen = (user) => {
|
const handleOpen = (user) => {
|
||||||
setLabelDialog(`Edit User`)
|
setLabelDialog(`Edit User`)
|
||||||
setFormData(user)
|
setFormData(user)
|
||||||
setOpenDialog(true)
|
setOpenDialog(true)
|
||||||
// setSelectedUser(user);
|
// setSelectedUser(user);
|
||||||
// setSelectedRoles(user.role_name);
|
// setSelectedRoles(user.role_name);
|
||||||
// setOpen(true);
|
// setOpen(true);
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setOpen(false);
|
setOpen(false)
|
||||||
setSelectedUser(null);
|
setSelectedUser(null)
|
||||||
setSelectedRoles([]);
|
setSelectedRoles([])
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleRoleChange = (role) => {
|
const handleRoleChange = (role) => {
|
||||||
setSelectedRoles((prevRoles) =>
|
setSelectedRoles((prevRoles) => (prevRoles.includes(role) ? prevRoles.filter((r) => r !== role) : [...prevRoles, role]))
|
||||||
prevRoles.includes(role)
|
}
|
||||||
? prevRoles.filter((r) => r !== role)
|
|
||||||
: [...prevRoles, role]
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDelete = (row) => {
|
const handleDelete = (row) => {
|
||||||
const newData = users.filter((item) => item.id !== row.id);
|
const newData = users.filter((item) => item.id !== row.id)
|
||||||
setUsers(newData);
|
setUsers(newData)
|
||||||
alert(`Deleted ${row.name}`);
|
alert(`Deleted ${row.name}`)
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
setUsers((prevUsers) =>
|
setUsers((prevUsers) => prevUsers.map((user) => (user.id === selectedUser.id ? { ...user, roles: selectedRoles } : user)))
|
||||||
prevUsers.map((user) =>
|
handleClose()
|
||||||
user.id === selectedUser.id ? { ...user, roles: selectedRoles } : user
|
}
|
||||||
)
|
|
||||||
);
|
|
||||||
handleClose();
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChange = (e) => {
|
const handleChange = (e) => {
|
||||||
const { name, value } = e.target;
|
const { name, value } = e.target
|
||||||
setFormData((prev) => ({ ...prev, [name]: value }));
|
setFormData((prev) => ({ ...prev, [name]: value }))
|
||||||
|
|
||||||
if (name === 'confirmPassword' || name === 'password') {
|
if (name === "confirmPassword" || name === "password") {
|
||||||
setErrors((prev) => ({
|
setErrors((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
passwordMatch: name === 'confirmPassword' ? value !== formData.password : formData.confirmPassword !== value,
|
passwordMatch: name === "confirmPassword" ? value !== formData.password : formData.confirmPassword !== value,
|
||||||
}));
|
}))
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
try {
|
try {
|
||||||
if (!errors.passwordMatch) {
|
if (!errors.passwordMatch) {
|
||||||
console.log('Form Data:', formData);
|
console.log("Form Data:", formData)
|
||||||
// setOpen(false);
|
// setOpen(false);
|
||||||
// setFormData(initiateForm);
|
// setFormData(initiateForm);
|
||||||
}
|
}
|
||||||
console.log(formData);
|
console.log(formData)
|
||||||
formData.status = "Y";
|
formData.status = "Y"
|
||||||
if (labelDialog === `Create User`) {
|
if (labelDialog === `Create User`) {
|
||||||
delete formData.confirmPassword
|
delete formData.confirmPassword
|
||||||
let createUser = await fetchApi('/api/user/create', 'POST', formData);
|
let createUser = await fetchApi("d/user/create", "POST", formData)
|
||||||
console.log(createUser);
|
console.log(createUser)
|
||||||
} else if (labelDialog === `Edit User`) {
|
} else if (labelDialog === `Edit User`) {
|
||||||
delete formData.created_at
|
delete formData.created_at
|
||||||
delete formData.updated_at
|
delete formData.updated_at
|
||||||
delete formData.role_name
|
delete formData.role_name
|
||||||
delete formData.actions
|
delete formData.actions
|
||||||
delete formData.confirmPassword
|
delete formData.confirmPassword
|
||||||
console.log(formData);
|
console.log(formData)
|
||||||
let editUser = await fetchApi(`/api/user/update/${formData.id}`, 'PUT', formData);
|
let editUser = await fetchApi(`d/user/update/${formData.id}`, "PUT", formData)
|
||||||
console.log('editUser', editUser);
|
console.log("editUser", editUser)
|
||||||
}
|
}
|
||||||
await fetchUser()
|
await fetchUser()
|
||||||
setOpenDialog(false)
|
setOpenDialog(false)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
handleError(`${error.message}. \n ${error.response.data.error}`)
|
handleError(`${error.message}. \n ${error.response.data.error}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const createNewUserBtn = () => {
|
const createNewUserBtn = () => {
|
||||||
setLabelDialog(`Create User`);
|
setLabelDialog(`Create User`)
|
||||||
setFormData(initiateForm);
|
setFormData(initiateForm)
|
||||||
setOpenDialog(true);
|
setOpenDialog(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleError = (msg) => { // ERROR MSG
|
const handleError = (msg) => {
|
||||||
setError(msg);
|
// ERROR MSG
|
||||||
setIsModalOpen(true);
|
setError(msg)
|
||||||
};
|
setIsModalOpen(true)
|
||||||
|
}
|
||||||
const closeModal = () => { // ERROR MSG
|
|
||||||
setIsModalOpen(false);
|
|
||||||
setError("");
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
const closeModal = () => {
|
||||||
<Box sx={{ padding: 3 }}>
|
// ERROR MSG
|
||||||
<WarningDialog // ERROR MSG
|
setIsModalOpen(false)
|
||||||
open={isModalOpen}
|
setError("")
|
||||||
onClose={closeModal}
|
}
|
||||||
errorMessage={error}
|
|
||||||
/>
|
|
||||||
<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={() => createNewUserBtn()}>Create New User</Button>
|
|
||||||
</Box>
|
|
||||||
<TableContainer component={Paper} sx={{ marginTop: 3 }}>
|
|
||||||
<ReusableTable columns={columns} data={users} />
|
|
||||||
|
|
||||||
<Dialog open={open} onClose={handleClose}>
|
return (
|
||||||
<DialogTitle>Add Roles to {selectedUser?.name}</DialogTitle>
|
<Box sx={{ padding: 3 }}>
|
||||||
<DialogContent>
|
<WarningDialog // ERROR MSG
|
||||||
{roles.map((role) => (
|
open={isModalOpen}
|
||||||
<FormControlLabel
|
onClose={closeModal}
|
||||||
key={role.id}
|
errorMessage={error}
|
||||||
control={
|
/>
|
||||||
<Checkbox
|
<Box sx={{ display: "flex", justifyContent: "flex-start", pr: 2 }}>
|
||||||
checked={selectedRoles.includes(role.name)}
|
<Typography sx={{ color: "gray", fontSize: "30px" }}>User Management</Typography>
|
||||||
onChange={() => handleRoleChange(role.name)}
|
</Box>
|
||||||
/>
|
<Box p={3}>
|
||||||
}
|
<Box sx={{ display: "flex", justifyContent: "flex-end", alignItems: "center", pr: 2 }}>
|
||||||
label={role.name}
|
<Button variant="contained" color="primary" onClick={() => createNewUserBtn()}>
|
||||||
/>
|
Create New User
|
||||||
))}
|
</Button>
|
||||||
</DialogContent>
|
</Box>
|
||||||
<DialogActions>
|
<TableContainer component={Paper} sx={{ marginTop: 3 }}>
|
||||||
<Button onClick={handleClose} color="secondary">
|
<ReusableTable columns={columns} data={users} />
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
<Button onClick={handleSave} color="primary" variant="contained">
|
|
||||||
Save
|
|
||||||
</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
</TableContainer>
|
|
||||||
|
|
||||||
<Dialog open={openDialog} onClose={() => setOpenDialog(false)} maxWidth="sm" fullWidth>
|
<Dialog open={open} onClose={handleClose}>
|
||||||
<DialogTitle>{labelDialog}</DialogTitle>
|
<DialogTitle>Add Roles to {selectedUser?.name}</DialogTitle>
|
||||||
<DialogContent sx={{ marginTop: 2 }}>
|
<DialogContent>
|
||||||
<Grid container spacing={2}>
|
{roles.map((role) => (
|
||||||
<Grid item xs={12}>
|
<FormControlLabel key={role.id} control={<Checkbox checked={selectedRoles.includes(role.name)} onChange={() => handleRoleChange(role.name)} />} label={role.name} />
|
||||||
<TextField
|
))}
|
||||||
sx={{ marginTop: 2 }}
|
</DialogContent>
|
||||||
label="Username"
|
<DialogActions>
|
||||||
name="username"
|
<Button onClick={handleClose} color="secondary">
|
||||||
value={formData.username}
|
Cancel
|
||||||
onChange={handleChange}
|
</Button>
|
||||||
fullWidth
|
<Button onClick={handleSave} color="primary" variant="contained">
|
||||||
required
|
Save
|
||||||
/>
|
</Button>
|
||||||
</Grid>
|
</DialogActions>
|
||||||
<Grid item xs={12}>
|
</Dialog>
|
||||||
<TextField
|
</TableContainer>
|
||||||
sx={{ marginTop: 2 }}
|
|
||||||
label="Name"
|
<Dialog open={openDialog} onClose={() => setOpenDialog(false)} maxWidth="sm" fullWidth>
|
||||||
name="name"
|
<DialogTitle>{labelDialog}</DialogTitle>
|
||||||
value={formData.name}
|
<DialogContent sx={{ marginTop: 2 }}>
|
||||||
onChange={handleChange}
|
<Grid container spacing={2}>
|
||||||
fullWidth
|
<Grid item xs={12}>
|
||||||
required
|
<TextField sx={{ marginTop: 2 }} label="Username" name="username" value={formData.username} onChange={handleChange} fullWidth required />
|
||||||
/>
|
</Grid>
|
||||||
</Grid>
|
<Grid item xs={12}>
|
||||||
<Grid item xs={12}>
|
<TextField sx={{ marginTop: 2 }} label="Name" name="name" value={formData.name} onChange={handleChange} fullWidth required />
|
||||||
<TextField
|
</Grid>
|
||||||
label="Email"
|
<Grid item xs={12}>
|
||||||
name="email"
|
<TextField label="Email" name="email" value={formData.email} onChange={handleChange} fullWidth type="email" required />
|
||||||
value={formData.email}
|
</Grid>
|
||||||
onChange={handleChange}
|
<Grid item xs={12}>
|
||||||
fullWidth
|
<FormLabel component="legend">Status</FormLabel>
|
||||||
type="email"
|
<FormControlLabel control={<Checkbox name="status" defaultChecked onChange={handleChange} value={formData.status === "Y" ? true : false} />} label="Aktif" />
|
||||||
required
|
</Grid>
|
||||||
/>
|
{/* <Grid item xs={12}>
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<FormLabel component="legend">Status</FormLabel>
|
|
||||||
<FormControlLabel control={<Checkbox name='status' defaultChecked onChange={handleChange} value={formData.status === 'Y' ? true : false}/>} label="Aktif" />
|
|
||||||
</Grid>
|
|
||||||
{/* <Grid item xs={12}>
|
|
||||||
<TextField
|
<TextField
|
||||||
sx={{ marginTop: 2 }}
|
sx={{ marginTop: 2 }}
|
||||||
label="Nik"
|
label="Nik"
|
||||||
@ -377,68 +337,36 @@ export default function UserManagement() {
|
|||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</Grid> */}
|
</Grid> */}
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<FormControl fullWidth required>
|
<FormControl fullWidth required>
|
||||||
<InputLabel id="organization-label">Role</InputLabel>
|
<InputLabel id="organization-label">Role</InputLabel>
|
||||||
<Select
|
<Select labelId="organization-label" id="organization" value={formData.id_role} label="Role" onChange={handleChange} name="id_role">
|
||||||
labelId="organization-label"
|
{roles.map((el, idx) => (
|
||||||
id="organization"
|
<MenuItem key={idx} value={el.id}>
|
||||||
value={formData.id_role}
|
{el.name}
|
||||||
label="Role"
|
</MenuItem>
|
||||||
onChange={handleChange}
|
))}
|
||||||
name='id_role'
|
</Select>
|
||||||
>
|
</FormControl>
|
||||||
{
|
</Grid>
|
||||||
roles.map((el, idx) => (
|
<Grid item xs={12}>
|
||||||
<MenuItem key={idx} value={el.id}>{el.name}</MenuItem>
|
<TextField label="Password" name="password" value={formData.password} onChange={handleChange} fullWidth type="password" required />
|
||||||
))
|
</Grid>
|
||||||
}
|
<Grid item xs={12}>
|
||||||
</Select>
|
<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 />
|
||||||
</FormControl>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
</DialogContent>
|
||||||
<TextField
|
<DialogActions>
|
||||||
label="Password"
|
<Button onClick={() => setOpenDialog(false)} color="secondary">
|
||||||
name="password"
|
Cancel
|
||||||
value={formData.password}
|
</Button>
|
||||||
onChange={handleChange}
|
<Button onClick={handleSubmit} color="primary" disabled={!formData.name || !formData.email || !formData.password || errors.passwordMatch || !formData.id_role || !formData.status || !formData.username}>
|
||||||
fullWidth
|
Submit
|
||||||
type="password"
|
</Button>
|
||||||
required
|
</DialogActions>
|
||||||
/>
|
</Dialog>
|
||||||
</Grid>
|
</Box>
|
||||||
<Grid item xs={12}>
|
</Box>
|
||||||
<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.password || errors.passwordMatch || !formData.id_role
|
|
||||||
|| !formData.status || !formData.username
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Submit
|
|
||||||
</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,134 +1,384 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from "react"
|
||||||
import { Routes, Route, useLocation, Navigate } from 'react-router-dom';
|
import { Routes, Route, useLocation, Navigate } from "react-router-dom"
|
||||||
import "../pages/Dashboard.css";
|
import "../pages/Dashboard.css"
|
||||||
import Sidebar from "../components/SideBar";
|
import Sidebar from "../components/SideBar"
|
||||||
import Header from "../components/Header";
|
import Header from "../components/Header"
|
||||||
import { Box, Toolbar } from "@mui/material";
|
import { Box, Toolbar } from "@mui/material"
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie"
|
||||||
// GENERAL
|
// GENERAL
|
||||||
import Dasboard from '../pages/Dashboard';
|
import Dasboard from "../pages/Dashboard"
|
||||||
import LoginPage from '../pages/Login';
|
import LoginPage from "../pages/Login"
|
||||||
import RegisterPage from '../pages/Register';
|
import RegisterPage from "../pages/Register"
|
||||||
import ProfilePage from '../pages/Profile';
|
import ProfilePage from "../pages/Profile"
|
||||||
// ADMIN
|
// ADMIN
|
||||||
import ManageTransfers from '../pages/ManageTransfers';
|
import ManageTransfers from "../pages/ManageTransfers"
|
||||||
import ManageNotifications from '../pages/ManageNotifications';
|
import ManageNotifications from "../pages/ManageNotifications"
|
||||||
import ManageAccess from '../pages/ManageAccess';
|
import ManageAccess from "../pages/ManageAccess"
|
||||||
import ManageAccounts from '../pages/ManageAccount';
|
import ManageAccounts from "../pages/ManageAccount"
|
||||||
import ManageGroups from '../pages/ManageGroups';
|
import ManageGroups from "../pages/ManageGroups"
|
||||||
import ManageMembers from '../pages/ManageMembers';
|
import ManageMembers from "../pages/ManageMembers"
|
||||||
import ManageMenus from '../pages/ManageMenu';
|
import ManageMenus from "../pages/ManageMenu"
|
||||||
import MemberKyc from '../pages/MemberKYC';
|
import MemberKyc from "../pages/MemberKYC"
|
||||||
import ManageCredential from '../pages/ManageCredential';
|
import ManageCredential from "../pages/ManageCredential"
|
||||||
import ManageCurrency from '../pages/ManageCurrency';
|
import ManageCurrency from "../pages/ManageCurrency"
|
||||||
import ManageWebservice from '../pages/ManageWebservice';
|
import ManageWebservice from "../pages/ManageWebservice"
|
||||||
import SettingPage from '../pages/Setting';
|
import SettingPage from "../pages/Setting"
|
||||||
import UserManagement from '../pages/UserManagement';
|
import UserManagement from "../pages/UserManagement"
|
||||||
import RoleMenus from '../pages/RoleManagement';
|
import RoleMenus from "../pages/RoleManagement"
|
||||||
import MasterDataPage from '../pages/MasterData';
|
import MasterDataPage from "../pages/MasterData"
|
||||||
// ESCROW
|
// ESCROW
|
||||||
import TransactionHistory from '../escrowPages/TransactionHistory';
|
import TransactionHistory from "../escrowPages/TransactionHistory"
|
||||||
import TransferPage from '../escrowPages/Transfer';
|
import TransferPage from "../escrowPages/Transfer"
|
||||||
import TicketConfirmationPage from '../escrowPages/TicketConfirmation';
|
import TicketConfirmationPage from "../escrowPages/TicketConfirmation"
|
||||||
// TDS
|
// TDS
|
||||||
import AgentBalance from '../tdsPages/AgentBalance';
|
import AgentBalance from "../tdsPages/AgentBalance"
|
||||||
import DepositReport from '../tdsPages/DepostiReport';
|
import DepositReport from "../tdsPages/DepostiReport"
|
||||||
import TopUp from '../tdsPages/TopUp';
|
import TopUp from "../tdsPages/TopUp"
|
||||||
import TopUpApproval from '../tdsPages/TopUpApproval';
|
import TopUpApproval from "../tdsPages/TopUpApproval"
|
||||||
import TopUpRequest from '../tdsPages/TopUpRequest';
|
import TopUpRequest from "../tdsPages/TopUpRequest"
|
||||||
import OperationTransfer from '../tdsPages/Transfer';
|
import OperationTransfer from "../tdsPages/Transfer"
|
||||||
import RegisteredAgent from '../tdsPages/RegisteredAgent';
|
import RegisteredAgent from "../tdsPages/RegisteredAgent"
|
||||||
import RegisteredSupervisor from '../tdsPages/RegisteredSupervisor';
|
import RegisteredSupervisor from "../tdsPages/RegisteredSupervisor"
|
||||||
|
|
||||||
// Mock Authentication Function
|
// Mock Authentication Function
|
||||||
const isAuthenticated = () => {
|
const isAuthenticated = () => {
|
||||||
let token = Cookies.get(`token`);
|
let token = Cookies.get(`token`)
|
||||||
let role = Cookies.get(`role`);
|
let role = Cookies.get(`role`)
|
||||||
if (token && role) return true
|
if (token && role) return true
|
||||||
return false
|
return false
|
||||||
};
|
}
|
||||||
|
|
||||||
// Middleware Component for Protected Routes
|
// Middleware Component for Protected Routes
|
||||||
const ProtectedRoute = ({ children }) => {
|
const ProtectedRoute = ({ children }) => {
|
||||||
if (!isAuthenticated()) {
|
if (!isAuthenticated()) {
|
||||||
return <Navigate to="/login" replace />;
|
return <Navigate to="/login" replace />
|
||||||
}
|
}
|
||||||
return children;
|
return children
|
||||||
};
|
|
||||||
|
|
||||||
const Layout = ({ children }) => {
|
|
||||||
const location = useLocation();
|
|
||||||
// Define routes where the Navbar should not appear
|
|
||||||
const hideNavbarRoutes = ['/login', "/register"];
|
|
||||||
const shouldShowLayout = !hideNavbarRoutes.includes(location.pathname);
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{shouldShowLayout &&
|
|
||||||
(
|
|
||||||
<div className="App">
|
|
||||||
<Box sx={{ display: "flex", backgroundColor: "#f5f5f5", color: "#333" }}>
|
|
||||||
<Sidebar />
|
|
||||||
<Box sx={{ flexGrow: 1 }}>
|
|
||||||
<Header />
|
|
||||||
<Toolbar />
|
|
||||||
<main>{children}</main>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
function App() {
|
|
||||||
let roles_list = JSON.parse(localStorage.getItem('roles_list'));
|
|
||||||
const location = useLocation();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
console.log(roles_list, location);
|
|
||||||
|
|
||||||
}, [roles_list, location]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Routes>
|
|
||||||
{/* GENERAL */}
|
|
||||||
<Route path="/login" element={<LoginPage />} />
|
|
||||||
<Route path="/register" element={<RegisterPage />} />
|
|
||||||
<Route exact path="/" element={<ProtectedRoute><Layout><Dasboard /></Layout></ProtectedRoute>} />
|
|
||||||
{/* GENERAL AFTER LOGIN */}
|
|
||||||
<Route path="/profile" element={<ProtectedRoute><Layout><ProfilePage /></Layout></ProtectedRoute>} />
|
|
||||||
{/* ADMIN */}
|
|
||||||
<Route path="/manage-groups" element={<ProtectedRoute><Layout><ManageGroups /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/manage-members" element={<ProtectedRoute><Layout><ManageMembers /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/manage-member-credential" element={<ProtectedRoute><Layout><ManageCredential /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/manage-access" element={<ProtectedRoute><Layout><ManageAccess /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/manage-accounts" element={<ProtectedRoute><Layout><ManageAccounts /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/manage-currency" element={<ProtectedRoute><Layout><ManageCurrency /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/manage-transfers" element={<ProtectedRoute><Layout><ManageTransfers /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/manage-notifications" element={<ProtectedRoute><Layout><ManageNotifications /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/manage-menu" element={<ProtectedRoute><Layout><ManageMenus /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/manage-webservice" element={<ProtectedRoute><Layout><ManageWebservice /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/manage-member-kyc" element={<ProtectedRoute><Layout><MemberKyc /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/setting" element={<ProtectedRoute><Layout><SettingPage /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/user-management" element={<ProtectedRoute><Layout><UserManagement /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/role-management" element={<ProtectedRoute><Layout><RoleMenus /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/master-data" element={<ProtectedRoute><Layout><MasterDataPage /></Layout></ProtectedRoute>} />
|
|
||||||
{/* ESCROW */}
|
|
||||||
<Route path="/transaction-history" element={<ProtectedRoute><Layout><TransactionHistory /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/transfer" element={<ProtectedRoute><Layout><TransferPage /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/ticket-confirmation" element={<ProtectedRoute><Layout><TicketConfirmationPage /></Layout></ProtectedRoute>} />
|
|
||||||
{/* TDS */}
|
|
||||||
<Route path="/agent-balance" element={<ProtectedRoute><Layout><AgentBalance /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/deposit-report" element={<ProtectedRoute><Layout><DepositReport /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/topup" element={<ProtectedRoute><Layout><TopUp /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/topup-approval" element={<ProtectedRoute><Layout><TopUpApproval /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/topup-request" element={<ProtectedRoute><Layout><TopUpRequest /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/operation-transfer" element={<ProtectedRoute><Layout><OperationTransfer /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/registered-agent" element={<ProtectedRoute><Layout><RegisteredAgent /></Layout></ProtectedRoute>} />
|
|
||||||
<Route path="/registered-supervisor" element={<ProtectedRoute><Layout><RegisteredSupervisor /></Layout></ProtectedRoute>} />
|
|
||||||
</Routes>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App;
|
const Layout = ({ children }) => {
|
||||||
|
const location = useLocation()
|
||||||
|
// Define routes where the Navbar should not appear
|
||||||
|
const hideNavbarRoutes = ["/login", "/register"]
|
||||||
|
const shouldShowLayout = !hideNavbarRoutes.includes(location.pathname)
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{shouldShowLayout && (
|
||||||
|
<div className="App">
|
||||||
|
<Box sx={{ display: "flex", backgroundColor: "#f5f5f5", color: "#333" }}>
|
||||||
|
<Sidebar />
|
||||||
|
<Box sx={{ flexGrow: 1 }}>
|
||||||
|
<Header />
|
||||||
|
<Toolbar />
|
||||||
|
<main>{children}</main>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
let roles_list = JSON.parse(localStorage.getItem("roles_list"))
|
||||||
|
const location = useLocation()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log(roles_list, location)
|
||||||
|
}, [roles_list, location])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Routes>
|
||||||
|
{/* GENERAL */}
|
||||||
|
<Route path="/login" element={<LoginPage />} />
|
||||||
|
<Route path="/register" element={<RegisterPage />} />
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path="/"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<Dasboard />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{/* GENERAL AFTER LOGIN */}
|
||||||
|
<Route
|
||||||
|
path="/profile"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<ProfilePage />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{/* ADMIN */}
|
||||||
|
<Route
|
||||||
|
path="/manage-groups"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<ManageGroups />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/manage-members"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<ManageMembers />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/manage-member-credential"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<ManageCredential />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/manage-access"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<ManageAccess />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/manage-accounts"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<ManageAccounts />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/manage-currency"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<ManageCurrency />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/manage-transfers"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<ManageTransfers />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/manage-notifications"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<ManageNotifications />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/manage-menu"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<ManageMenus />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/manage-webservice"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<ManageWebservice />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/manage-member-kyc"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<MemberKyc />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/setting"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<SettingPage />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/user-management"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<UserManagement />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/role-management"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<RoleMenus />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/master-data"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<MasterDataPage />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{/* ESCROW */}
|
||||||
|
<Route
|
||||||
|
path="/transaction-history"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<TransactionHistory />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/transfer"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<TransferPage />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/ticket-confirmation"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<TicketConfirmationPage />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{/* TDS */}
|
||||||
|
<Route
|
||||||
|
path="/agent-balance"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<AgentBalance />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/deposit-report"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<DepositReport />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/topup"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<TopUp />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/topup-approval"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<TopUpApproval />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/topup-request"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<TopUpRequest />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/operation-transfer"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<OperationTransfer />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/registered-agent"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<RegisteredAgent />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/registered-supervisor"
|
||||||
|
element={
|
||||||
|
<ProtectedRoute>
|
||||||
|
<Layout>
|
||||||
|
<RegisteredSupervisor />
|
||||||
|
</Layout>
|
||||||
|
</ProtectedRoute>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Routes>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App
|
||||||
|
|||||||
Reference in New Issue
Block a user