login, usermanagement, role
This commit is contained in:
9
package-lock.json
generated
9
package-lock.json
generated
@ -18,6 +18,7 @@
|
|||||||
"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",
|
||||||
"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",
|
||||||
@ -10813,6 +10814,14 @@
|
|||||||
"jiti": "bin/jiti.js"
|
"jiti": "bin/jiti.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/js-cookie": {
|
||||||
|
"version": "3.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
|
||||||
|
"integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/js-tokens": {
|
"node_modules/js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
"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",
|
||||||
"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",
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import {
|
import {
|
||||||
AppBar,
|
AppBar,
|
||||||
Toolbar,
|
Toolbar,
|
||||||
@ -6,16 +6,23 @@ import {
|
|||||||
IconButton,
|
IconButton,
|
||||||
Menu,
|
Menu,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
Avatar,
|
Avatar,Button
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { Mail, AccountCircle } from "@mui/icons-material";
|
import { Mail, AccountCircle } from "@mui/icons-material";
|
||||||
import "../style/Header.css";
|
import "../style/Header.css";
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import Cookies from "js-cookie";
|
||||||
|
|
||||||
const Header = () => {
|
const Header = () => {
|
||||||
|
const [userData, setUserData] = useState('');
|
||||||
const [anchorEl, setAnchorEl] = useState(null);
|
const [anchorEl, setAnchorEl] = useState(null);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let username = Cookies.get('username');
|
||||||
|
setUserData(username)
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handleClick = (event) => {
|
const handleClick = (event) => {
|
||||||
setAnchorEl(event.currentTarget);
|
setAnchorEl(event.currentTarget);
|
||||||
};
|
};
|
||||||
@ -25,7 +32,9 @@ const Header = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function logoutBtn() {
|
function logoutBtn() {
|
||||||
localStorage.removeItem("authToken");
|
Cookies.remove('token');
|
||||||
|
Cookies.remove('role');
|
||||||
|
Cookies.remove('username');
|
||||||
navigate('/login')
|
navigate('/login')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,9 +43,7 @@ const Header = () => {
|
|||||||
return (
|
return (
|
||||||
<AppBar position="fixed" sx={{ backgroundColor: "#f5f5f5", color: "#333" }}>
|
<AppBar position="fixed" sx={{ backgroundColor: "#f5f5f5", color: "#333" }}>
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
<Typography variant="h6" noWrap sx={{ flexGrow: 1 }}>
|
<Typography variant="h6" noWrap sx={{ flexGrow: 1 }}></Typography>
|
||||||
|
|
||||||
</Typography>
|
|
||||||
<IconButton>
|
<IconButton>
|
||||||
<Mail />
|
<Mail />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
@ -51,6 +58,12 @@ const Header = () => {
|
|||||||
>
|
>
|
||||||
<AccountCircle />
|
<AccountCircle />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
<Button onClick={handleClick}
|
||||||
|
id="basic-button"
|
||||||
|
aria-controls={open ? 'account-menu' : undefined}
|
||||||
|
aria-haspopup="true"
|
||||||
|
aria-expanded={open ? 'true' : undefined}>{userData}
|
||||||
|
</Button>
|
||||||
<Menu
|
<Menu
|
||||||
id="account-menu"
|
id="account-menu"
|
||||||
anchorEl={anchorEl}
|
anchorEl={anchorEl}
|
||||||
@ -59,6 +72,10 @@ const Header = () => {
|
|||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
transformOrigin={{ horizontal: "right", vertical: "top" }}
|
transformOrigin={{ horizontal: "right", vertical: "top" }}
|
||||||
anchorOrigin={{ horizontal: "right", vertical: "bottom" }}
|
anchorOrigin={{ horizontal: "right", vertical: "bottom" }}
|
||||||
|
title="User Profile"
|
||||||
|
MenuListProps={{
|
||||||
|
'aria-labelledby': 'basic-button',
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<MenuItem>
|
<MenuItem>
|
||||||
<Avatar sx={{ marginRight: 1 }} /> Profile
|
<Avatar sx={{ marginRight: 1 }} /> Profile
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import {
|
import {
|
||||||
Drawer,
|
Drawer,
|
||||||
List,
|
List,
|
||||||
@ -12,7 +12,8 @@ import {
|
|||||||
// Divider,
|
// Divider,
|
||||||
Box,
|
Box,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Avatar
|
Avatar,
|
||||||
|
Link
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
|
|
||||||
import SettingsIcon from "@mui/icons-material/Settings";
|
import SettingsIcon from "@mui/icons-material/Settings";
|
||||||
@ -22,6 +23,8 @@ import InfoIcon from "@mui/icons-material/Info";
|
|||||||
import Logout from "@mui/icons-material/Logout";
|
import Logout from "@mui/icons-material/Logout";
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import logo from '../logo/logo.jpeg';
|
import logo from '../logo/logo.jpeg';
|
||||||
|
import Cookies from "js-cookie";
|
||||||
|
import { Link as ReactRouterLink } from 'react-router-dom';
|
||||||
|
|
||||||
const Sidebar = () => {
|
const Sidebar = () => {
|
||||||
const [userRole, setUserRole] = useState('');
|
const [userRole, setUserRole] = useState('');
|
||||||
@ -131,6 +134,14 @@ const Sidebar = () => {
|
|||||||
{
|
{
|
||||||
title: 'Setting',
|
title: 'Setting',
|
||||||
path: '/setting'
|
path: '/setting'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'User Management',
|
||||||
|
path: '/user-management'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Role Management',
|
||||||
|
path: '/role-management'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -229,7 +240,7 @@ const Sidebar = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Transfer',
|
title: 'Transfer',
|
||||||
path: '/transfer'
|
path: '/operation-transfer'
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -238,26 +249,33 @@ const Sidebar = () => {
|
|||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
title: 'Agent Registered',
|
title: 'Agent Registered',
|
||||||
path: '/agent'
|
path: '/registered-agent'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Supervisor Registered',
|
title: 'Supervisor Registered',
|
||||||
path: '/supervisor'
|
path: '/registered-supervisor'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let token = Cookies.get(`token`);
|
||||||
|
let role = Cookies.get(`role`);
|
||||||
|
if (token && role) setUserRole(role);
|
||||||
|
}, []);
|
||||||
|
|
||||||
function roleMenu() {
|
function roleMenu() {
|
||||||
setUserRole('escrow')
|
if (userRole === 'Super Admin') return adminMenu
|
||||||
if (userRole === 'admin') return adminMenu
|
|
||||||
if (userRole === 'escrow') return esCrowMenu
|
if (userRole === 'escrow') return esCrowMenu
|
||||||
if (userRole === 'tds') return tdsMenu
|
if (userRole === 'tds') return tdsMenu
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
function logoutBtn() {
|
function logoutBtn() {
|
||||||
localStorage.removeItem("authToken");
|
Cookies.remove('token');
|
||||||
|
Cookies.remove('role');
|
||||||
|
Cookies.remove('username');
|
||||||
navigate('/login');
|
navigate('/login');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,9 +374,11 @@ function ListOfMenus({roleMenu, navigate, label}) {
|
|||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
{menuItem.options && menuItem.options.map((option, subIndex) => (
|
{menuItem.options && menuItem.options.map((option, subIndex) => (
|
||||||
<ListItem button key={subIndex} sx={{ pl: 2 }}>
|
<ListItem key={subIndex} sx={{ pl: 2 }}>
|
||||||
<ListItemText>
|
<ListItemText>
|
||||||
<Typography onClick={() => navigate(option.path)} color='wheat' style={{ textAlign: 'left' }}>{option.title}</Typography>
|
<Link to={option.path} component={ReactRouterLink} underline="none">
|
||||||
|
<Typography color='wheat' style={{ textAlign: 'left' }}>{option.title}</Typography>
|
||||||
|
</Link>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
))}
|
))}
|
||||||
|
|||||||
90
src/components/Table.js
Normal file
90
src/components/Table.js
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { tableCellClasses } from '@mui/material/TableCell';
|
||||||
|
import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, Button, styled, TablePagination } from '@mui/material';
|
||||||
|
|
||||||
|
const StyledTableCell = styled(TableCell)(({ theme }) => ({
|
||||||
|
[`&.${tableCellClasses.head}`]: {
|
||||||
|
backgroundColor: `grey`,
|
||||||
|
color: theme.palette.common.white,
|
||||||
|
},
|
||||||
|
[`&.${tableCellClasses.body}`]: {
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledTableRow = styled(TableRow)(({ theme }) => ({
|
||||||
|
'&:nth-of-type(odd)': {
|
||||||
|
backgroundColor: theme.palette.action.hover,
|
||||||
|
},
|
||||||
|
// hide last border
|
||||||
|
'&:last-child td, &:last-child th': {
|
||||||
|
border: 0,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
function ReusableTable({ columns, data }) {
|
||||||
|
const [page, setPage] = React.useState(0);
|
||||||
|
const [rowsPerPage, setRowsPerPage] = React.useState(10);
|
||||||
|
|
||||||
|
const handleChangePage = (event, newPage) => {
|
||||||
|
setPage(newPage);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChangeRowsPerPage = (event) => {
|
||||||
|
setRowsPerPage(+event.target.value);
|
||||||
|
setPage(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<TableContainer component={Paper}>
|
||||||
|
<Table>
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
{columns.map((column, index) => (
|
||||||
|
<StyledTableCell align={index === columns.length - 1 ? "right" : "left"} key={column.id}>{column.label}</StyledTableCell>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{data.map((row, index) => (
|
||||||
|
<StyledTableRow key={row.id || index}>
|
||||||
|
{columns.map((column, index) => (
|
||||||
|
<StyledTableCell align={index === columns.length - 1 ? "right" : "left"} key={column.id}>
|
||||||
|
{column.id === 'actions' && row.actions ? (
|
||||||
|
row.actions.map((action, actionIndex) => (
|
||||||
|
<Button
|
||||||
|
key={actionIndex}
|
||||||
|
variant="contained"
|
||||||
|
color={action.color || 'primary'}
|
||||||
|
onClick={() => action.onClick(row)}
|
||||||
|
style={{ marginRight: '5px' }}
|
||||||
|
size='small'
|
||||||
|
>
|
||||||
|
{action.label}
|
||||||
|
</Button>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
row[column.id]
|
||||||
|
)}
|
||||||
|
</StyledTableCell>
|
||||||
|
))}
|
||||||
|
</StyledTableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
<TablePagination
|
||||||
|
rowsPerPageOptions={[10, 25, 100]}
|
||||||
|
component="div"
|
||||||
|
count={data.length}
|
||||||
|
rowsPerPage={rowsPerPage}
|
||||||
|
page={page}
|
||||||
|
onPageChange={handleChangePage}
|
||||||
|
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ReusableTable;
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
const instance = axios.create({
|
const instance = axios.create({
|
||||||
baseURL: 'https://api.telkomcel.tl/stag-tpay-dash-api/',
|
baseURL: 'https://api.telkomcel.tl/tpay-stg-dash-api/',
|
||||||
headers: {
|
headers: {
|
||||||
"Access-Control-Allow-Origin": "*",
|
"Access-Control-Allow-Origin": "*",
|
||||||
"content-type":"application/json",
|
"content-type":"application/json",
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { TextField, Button, Box, Typography, Grid, Paper } from "@mui/material";
|
import { TextField, Button, Box, Typography, Grid, Paper } from "@mui/material";
|
||||||
import {Link, useNavigate } from 'react-router-dom';
|
import {Link, useNavigate } from 'react-router-dom';
|
||||||
// import { fetchApi } from '../config/axios';
|
import Cookies from "js-cookie";
|
||||||
|
import { fetchApi } from '../config/axios';
|
||||||
|
|
||||||
const LoginPage = () => {
|
const LoginPage = () => {
|
||||||
// State for email and password
|
// State for email and password
|
||||||
@ -15,14 +16,14 @@ const LoginPage = () => {
|
|||||||
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('/api/login', 'POST', { username, password });
|
||||||
// console.log(user);
|
if (user.data && user.data.data) {
|
||||||
// if (user.data && user.data.data) {
|
let userLogin = 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);
|
||||||
// document.cookie = `role=${role}`
|
// localStorage.setItem('token', userLogin.token.access_token)
|
||||||
localStorage.setItem('authToken', username)
|
}
|
||||||
navigate('/');
|
navigate('/');
|
||||||
} else {
|
} else {
|
||||||
alert("Please fill in both fields.");
|
alert("Please fill in both fields.");
|
||||||
|
|||||||
@ -244,7 +244,7 @@ export default function ManageGroups() {
|
|||||||
<TablePagination
|
<TablePagination
|
||||||
rowsPerPageOptions={[10, 25, 100]}
|
rowsPerPageOptions={[10, 25, 100]}
|
||||||
component="div"
|
component="div"
|
||||||
count={rows.length}
|
count={rows.data.length}
|
||||||
rowsPerPage={rowsPerPage}
|
rowsPerPage={rowsPerPage}
|
||||||
page={page}
|
page={page}
|
||||||
onPageChange={handleChangePage}
|
onPageChange={handleChangePage}
|
||||||
|
|||||||
169
src/pages/RoleManagement.js
Normal file
169
src/pages/RoleManagement.js
Normal 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
252
src/pages/UserManagement.js
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -21,14 +21,29 @@ 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 RoleMenus from '../pages/RoleManagement';
|
||||||
// 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
|
||||||
|
import AgentBalance from '../tdsPages/AgentBalance';
|
||||||
|
import DepositReport from '../tdsPages/DepostiReport';
|
||||||
|
import TopUp from '../tdsPages/TopUp';
|
||||||
|
import TopUpApproval from '../tdsPages/TopUpApproval';
|
||||||
|
import TopUpRequest from '../tdsPages/TopUpRequest';
|
||||||
|
import OperationTransfer from '../tdsPages/Transfer';
|
||||||
|
import RegisteredAgent from '../tdsPages/RegisteredAgent';
|
||||||
|
import RegisteredSupervisor from '../tdsPages/RegisteredSupervisor';
|
||||||
|
import Cookies from "js-cookie";
|
||||||
|
|
||||||
// Mock Authentication Function
|
// Mock Authentication Function
|
||||||
const isAuthenticated = () => {
|
const isAuthenticated = () => {
|
||||||
return localStorage.getItem("authToken") !== null;
|
let token = Cookies.get(`token`);
|
||||||
|
let role = Cookies.get(`role`);
|
||||||
|
if (token && role) return true
|
||||||
|
return false
|
||||||
};
|
};
|
||||||
|
|
||||||
// Middleware Component for Protected Routes
|
// Middleware Component for Protected Routes
|
||||||
@ -84,10 +99,21 @@ function App() {
|
|||||||
<Route path="/manage-webservice" element={<ProtectedRoute><Layout><ManageWebservice /></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="/manage-member-kyc" element={<ProtectedRoute><Layout><MemberKyc /></Layout></ProtectedRoute>} />
|
||||||
<Route path="/setting" element={<ProtectedRoute><Layout><SettingPage /></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>} />
|
||||||
{/* ESCROW */}
|
{/* ESCROW */}
|
||||||
<Route path="/transaction-history" element={<ProtectedRoute><Layout><TransactionHistory /></Layout></ProtectedRoute>} />
|
<Route path="/transaction-history" element={<ProtectedRoute><Layout><TransactionHistory /></Layout></ProtectedRoute>} />
|
||||||
<Route path="/transfer" element={<ProtectedRoute><Layout><TransferPage /></Layout></ProtectedRoute>} />
|
<Route path="/transfer" element={<ProtectedRoute><Layout><TransferPage /></Layout></ProtectedRoute>} />
|
||||||
<Route path="/ticket-confirmation" element={<ProtectedRoute><Layout><TicketConfirmationPage /></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>
|
</Routes>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
149
src/tdsPages/AgentBalance.js
Normal file
149
src/tdsPages/AgentBalance.js
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import Paper from '@mui/material/Paper';
|
||||||
|
import Table from '@mui/material/Table';
|
||||||
|
import TableBody from '@mui/material/TableBody';
|
||||||
|
import TableCell from '@mui/material/TableCell';
|
||||||
|
import TableContainer from '@mui/material/TableContainer';
|
||||||
|
import TableHead from '@mui/material/TableHead';
|
||||||
|
import TablePagination from '@mui/material/TablePagination';
|
||||||
|
import TableRow from '@mui/material/TableRow';
|
||||||
|
import { Box, Typography, Button, TextField } from '@mui/material';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import SearchIcon from '@mui/icons-material/Search';
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ id: 'id', label: 'ID Agen', minWidth: 50 },
|
||||||
|
{
|
||||||
|
id: 'name',
|
||||||
|
label: 'Nama Agen',
|
||||||
|
minWidth: 100,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toLocaleString('en-US'),
|
||||||
|
},
|
||||||
|
{ id: 'id', label: 'ID Supervisor', minWidth: 50 },
|
||||||
|
{
|
||||||
|
id: 'name',
|
||||||
|
label: 'Nama Supervisor',
|
||||||
|
minWidth: 100,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toLocaleString('en-US'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'description',
|
||||||
|
label: 'Agent Balance',
|
||||||
|
minWidth: 170,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toLocaleString('en-US'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'description',
|
||||||
|
label: 'Merchant Balance',
|
||||||
|
minWidth: 170,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toLocaleString('en-US'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function createData(id, name, description, population, size) {
|
||||||
|
const today = new Date();
|
||||||
|
return { id, name, description, population, size, createdDate: today.toString()};
|
||||||
|
}
|
||||||
|
|
||||||
|
const rows = [
|
||||||
|
createData(1,'India', 'IN', 1324171354, 3287263),
|
||||||
|
createData(2,'China', 'CN', 1403500365, 9596961),
|
||||||
|
createData(3,'Italy', 'IT', 60483973, 301340),
|
||||||
|
createData(4,'United States', 'US', 327167434, 9833520),
|
||||||
|
createData(5,'Canada', 'CA', 37602103, 9984670),
|
||||||
|
createData(6,'Australia', 'AU', 25475400, 7692024),
|
||||||
|
createData(7,'Germany', 'DE', 83019200, 357578),
|
||||||
|
createData(8,'Ireland', 'IE', 4857000, 70273),
|
||||||
|
createData(9,'Mexico', 'MX', 126577691, 1972550),
|
||||||
|
createData(10,'Japan', 'JP', 126317000, 377973),
|
||||||
|
createData(11,'France', 'FR', 67022000, 640679),
|
||||||
|
createData(12,'United Kingdom', 'GB', 67545757, 242495),
|
||||||
|
createData(13,'Russia', 'RU', 146793744, 17098246),
|
||||||
|
createData(14,'Nigeria', 'NG', 200962417, 923768),
|
||||||
|
createData(15,'Brazil', 'BR', 210147125, 8515767),
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function AgentBalance() {
|
||||||
|
const [page, setPage] = React.useState(0);
|
||||||
|
const [rowsPerPage, setRowsPerPage] = React.useState(10);
|
||||||
|
|
||||||
|
const handleChangePage = (event, newPage) => {
|
||||||
|
setPage(newPage);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChangeRowsPerPage = (event) => {
|
||||||
|
setRowsPerPage(+event.target.value);
|
||||||
|
setPage(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ padding: 3 }}>
|
||||||
|
<Typography sx={{ color: 'gray', size: 'xl' }}>Manage Group</Typography>
|
||||||
|
<Box sx={{ padding: 3 }}>
|
||||||
|
<Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', pr: 2, }}>
|
||||||
|
<Button variant="contained" color="primary">Create New Group</Button>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ display: 'flex', justifyContent: 'flex-start', alignItems: 'center', pr: 2, }}>
|
||||||
|
<TextField id="standard-basic" label="Search" variant="standard" />
|
||||||
|
<IconButton type="button" sx={{ p: '10px' }} aria-label="search">
|
||||||
|
<SearchIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
<Paper sx={{ width: '100%', overflow: 'hidden' }}>
|
||||||
|
<TableContainer sx={{ maxHeight: 440 }}>
|
||||||
|
<Table stickyHeader aria-label="sticky table">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
{columns.map((column) => (
|
||||||
|
<TableCell
|
||||||
|
key={column.id}
|
||||||
|
align={column.align}
|
||||||
|
style={{ minWidth: column.minWidth }}
|
||||||
|
>
|
||||||
|
{column.label}
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{rows
|
||||||
|
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
|
||||||
|
.map((row) => {
|
||||||
|
return (
|
||||||
|
<TableRow hover role="checkbox" tabIndex={-1} key={row.id}>
|
||||||
|
{columns.map((column) => {
|
||||||
|
const value = row[column.id];
|
||||||
|
return (
|
||||||
|
<TableCell key={column.id} align={column.align}>
|
||||||
|
{
|
||||||
|
column.id === 'action' ? (
|
||||||
|
<Button>Details</Button>
|
||||||
|
) : value
|
||||||
|
}
|
||||||
|
</TableCell>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
<TablePagination
|
||||||
|
rowsPerPageOptions={[10, 25, 100]}
|
||||||
|
component="div"
|
||||||
|
count={rows.length}
|
||||||
|
rowsPerPage={rowsPerPage}
|
||||||
|
page={page}
|
||||||
|
onPageChange={handleChangePage}
|
||||||
|
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||||
|
/>
|
||||||
|
</Paper>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
149
src/tdsPages/DepostiReport.js
Normal file
149
src/tdsPages/DepostiReport.js
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import Paper from '@mui/material/Paper';
|
||||||
|
import Table from '@mui/material/Table';
|
||||||
|
import TableBody from '@mui/material/TableBody';
|
||||||
|
import TableCell from '@mui/material/TableCell';
|
||||||
|
import TableContainer from '@mui/material/TableContainer';
|
||||||
|
import TableHead from '@mui/material/TableHead';
|
||||||
|
import TablePagination from '@mui/material/TablePagination';
|
||||||
|
import TableRow from '@mui/material/TableRow';
|
||||||
|
import { Box, Typography, Button, TextField } from '@mui/material';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import SearchIcon from '@mui/icons-material/Search';
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ id: 'createdDate', label: 'Tanggal Transaksi', minWidth: 100 },
|
||||||
|
{ id: 'id', label: 'Transaksi', minWidth: 50 },
|
||||||
|
{
|
||||||
|
id: 'name',
|
||||||
|
label: 'Debit',
|
||||||
|
minWidth: 100,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toLocaleString('en-US'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'description',
|
||||||
|
label: 'Kredit',
|
||||||
|
minWidth: 170,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toLocaleString('en-US'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'description',
|
||||||
|
label: 'Balance',
|
||||||
|
minWidth: 170,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toLocaleString('en-US'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'action',
|
||||||
|
label: 'Keterangan',
|
||||||
|
minWidth: 170,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toFixed(2),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function createData(id, name, description, population, size) {
|
||||||
|
const today = new Date();
|
||||||
|
return { id, name, description, population, size, createdDate: today.toString()};
|
||||||
|
}
|
||||||
|
|
||||||
|
const rows = [
|
||||||
|
createData(1,'India', 'IN', 1324171354, 3287263),
|
||||||
|
createData(2,'China', 'CN', 1403500365, 9596961),
|
||||||
|
createData(3,'Italy', 'IT', 60483973, 301340),
|
||||||
|
createData(4,'United States', 'US', 327167434, 9833520),
|
||||||
|
createData(5,'Canada', 'CA', 37602103, 9984670),
|
||||||
|
createData(6,'Australia', 'AU', 25475400, 7692024),
|
||||||
|
createData(7,'Germany', 'DE', 83019200, 357578),
|
||||||
|
createData(8,'Ireland', 'IE', 4857000, 70273),
|
||||||
|
createData(9,'Mexico', 'MX', 126577691, 1972550),
|
||||||
|
createData(10,'Japan', 'JP', 126317000, 377973),
|
||||||
|
createData(11,'France', 'FR', 67022000, 640679),
|
||||||
|
createData(12,'United Kingdom', 'GB', 67545757, 242495),
|
||||||
|
createData(13,'Russia', 'RU', 146793744, 17098246),
|
||||||
|
createData(14,'Nigeria', 'NG', 200962417, 923768),
|
||||||
|
createData(15,'Brazil', 'BR', 210147125, 8515767),
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function DepositReport() {
|
||||||
|
const [page, setPage] = React.useState(0);
|
||||||
|
const [rowsPerPage, setRowsPerPage] = React.useState(10);
|
||||||
|
|
||||||
|
const handleChangePage = (event, newPage) => {
|
||||||
|
setPage(newPage);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChangeRowsPerPage = (event) => {
|
||||||
|
setRowsPerPage(+event.target.value);
|
||||||
|
setPage(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ padding: 3 }}>
|
||||||
|
<Typography sx={{ color: 'gray', size: 'xl' }}>Manage Group</Typography>
|
||||||
|
<Box sx={{ padding: 3 }}>
|
||||||
|
<Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', pr: 2, }}>
|
||||||
|
<Button variant="contained" color="primary">Create New Group</Button>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ display: 'flex', justifyContent: 'flex-start', alignItems: 'center', pr: 2, }}>
|
||||||
|
<TextField id="standard-basic" label="Search" variant="standard" />
|
||||||
|
<IconButton type="button" sx={{ p: '10px' }} aria-label="search">
|
||||||
|
<SearchIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
<Paper sx={{ width: '100%', overflow: 'hidden' }}>
|
||||||
|
<TableContainer sx={{ maxHeight: 440 }}>
|
||||||
|
<Table stickyHeader aria-label="sticky table">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
{columns.map((column) => (
|
||||||
|
<TableCell
|
||||||
|
key={column.id}
|
||||||
|
align={column.align}
|
||||||
|
style={{ minWidth: column.minWidth }}
|
||||||
|
>
|
||||||
|
{column.label}
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{rows
|
||||||
|
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
|
||||||
|
.map((row) => {
|
||||||
|
return (
|
||||||
|
<TableRow hover role="checkbox" tabIndex={-1} key={row.id}>
|
||||||
|
{columns.map((column) => {
|
||||||
|
const value = row[column.id];
|
||||||
|
return (
|
||||||
|
<TableCell key={column.id} align={column.align}>
|
||||||
|
{
|
||||||
|
column.id === 'action' ? (
|
||||||
|
<Button>Details</Button>
|
||||||
|
) : value
|
||||||
|
}
|
||||||
|
</TableCell>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
<TablePagination
|
||||||
|
rowsPerPageOptions={[10, 25, 100]}
|
||||||
|
component="div"
|
||||||
|
count={rows.length}
|
||||||
|
rowsPerPage={rowsPerPage}
|
||||||
|
page={page}
|
||||||
|
onPageChange={handleChangePage}
|
||||||
|
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||||
|
/>
|
||||||
|
</Paper>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
142
src/tdsPages/RegisteredAgent.js
Normal file
142
src/tdsPages/RegisteredAgent.js
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import Paper from '@mui/material/Paper';
|
||||||
|
import Table from '@mui/material/Table';
|
||||||
|
import TableBody from '@mui/material/TableBody';
|
||||||
|
import TableCell from '@mui/material/TableCell';
|
||||||
|
import TableContainer from '@mui/material/TableContainer';
|
||||||
|
import TableHead from '@mui/material/TableHead';
|
||||||
|
import TablePagination from '@mui/material/TablePagination';
|
||||||
|
import TableRow from '@mui/material/TableRow';
|
||||||
|
import { Box, Typography, Button, TextField } from '@mui/material';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import SearchIcon from '@mui/icons-material/Search';
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ id: 'id', label: 'ID', minWidth: 50 },
|
||||||
|
{ id: 'createdDate', label: 'Created Date', minWidth: 100 },
|
||||||
|
{
|
||||||
|
id: 'name',
|
||||||
|
label: 'Name',
|
||||||
|
minWidth: 100,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toLocaleString('en-US'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'description',
|
||||||
|
label: 'Description',
|
||||||
|
minWidth: 170,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toLocaleString('en-US'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'action',
|
||||||
|
label: 'Action',
|
||||||
|
minWidth: 170,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toFixed(2),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function createData(id, name, description, population, size) {
|
||||||
|
const today = new Date();
|
||||||
|
return { id, name, description, population, size, createdDate: today.toString()};
|
||||||
|
}
|
||||||
|
|
||||||
|
const rows = [
|
||||||
|
createData(1,'India', 'IN', 1324171354, 3287263),
|
||||||
|
createData(2,'China', 'CN', 1403500365, 9596961),
|
||||||
|
createData(3,'Italy', 'IT', 60483973, 301340),
|
||||||
|
createData(4,'United States', 'US', 327167434, 9833520),
|
||||||
|
createData(5,'Canada', 'CA', 37602103, 9984670),
|
||||||
|
createData(6,'Australia', 'AU', 25475400, 7692024),
|
||||||
|
createData(7,'Germany', 'DE', 83019200, 357578),
|
||||||
|
createData(8,'Ireland', 'IE', 4857000, 70273),
|
||||||
|
createData(9,'Mexico', 'MX', 126577691, 1972550),
|
||||||
|
createData(10,'Japan', 'JP', 126317000, 377973),
|
||||||
|
createData(11,'France', 'FR', 67022000, 640679),
|
||||||
|
createData(12,'United Kingdom', 'GB', 67545757, 242495),
|
||||||
|
createData(13,'Russia', 'RU', 146793744, 17098246),
|
||||||
|
createData(14,'Nigeria', 'NG', 200962417, 923768),
|
||||||
|
createData(15,'Brazil', 'BR', 210147125, 8515767),
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function RegisteredAgent() {
|
||||||
|
const [page, setPage] = React.useState(0);
|
||||||
|
const [rowsPerPage, setRowsPerPage] = React.useState(10);
|
||||||
|
|
||||||
|
const handleChangePage = (event, newPage) => {
|
||||||
|
setPage(newPage);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChangeRowsPerPage = (event) => {
|
||||||
|
setRowsPerPage(+event.target.value);
|
||||||
|
setPage(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ padding: 3 }}>
|
||||||
|
<Typography sx={{ color: 'gray', size: 'xl' }}>Manage Group</Typography>
|
||||||
|
<Box sx={{ padding: 3 }}>
|
||||||
|
<Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', pr: 2, }}>
|
||||||
|
<Button variant="contained" color="primary">Create New Group</Button>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ display: 'flex', justifyContent: 'flex-start', alignItems: 'center', pr: 2, }}>
|
||||||
|
<TextField id="standard-basic" label="Search" variant="standard" />
|
||||||
|
<IconButton type="button" sx={{ p: '10px' }} aria-label="search">
|
||||||
|
<SearchIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
<Paper sx={{ width: '100%', overflow: 'hidden' }}>
|
||||||
|
<TableContainer sx={{ maxHeight: 440 }}>
|
||||||
|
<Table stickyHeader aria-label="sticky table">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
{columns.map((column) => (
|
||||||
|
<TableCell
|
||||||
|
key={column.id}
|
||||||
|
align={column.align}
|
||||||
|
style={{ minWidth: column.minWidth }}
|
||||||
|
>
|
||||||
|
{column.label}
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{rows
|
||||||
|
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
|
||||||
|
.map((row) => {
|
||||||
|
return (
|
||||||
|
<TableRow hover role="checkbox" tabIndex={-1} key={row.id}>
|
||||||
|
{columns.map((column) => {
|
||||||
|
const value = row[column.id];
|
||||||
|
return (
|
||||||
|
<TableCell key={column.id} align={column.align}>
|
||||||
|
{
|
||||||
|
column.id === 'action' ? (
|
||||||
|
<Button>Details</Button>
|
||||||
|
) : value
|
||||||
|
}
|
||||||
|
</TableCell>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
<TablePagination
|
||||||
|
rowsPerPageOptions={[10, 25, 100]}
|
||||||
|
component="div"
|
||||||
|
count={rows.length}
|
||||||
|
rowsPerPage={rowsPerPage}
|
||||||
|
page={page}
|
||||||
|
onPageChange={handleChangePage}
|
||||||
|
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||||
|
/>
|
||||||
|
</Paper>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
142
src/tdsPages/RegisteredSupervisor.js
Normal file
142
src/tdsPages/RegisteredSupervisor.js
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import Paper from '@mui/material/Paper';
|
||||||
|
import Table from '@mui/material/Table';
|
||||||
|
import TableBody from '@mui/material/TableBody';
|
||||||
|
import TableCell from '@mui/material/TableCell';
|
||||||
|
import TableContainer from '@mui/material/TableContainer';
|
||||||
|
import TableHead from '@mui/material/TableHead';
|
||||||
|
import TablePagination from '@mui/material/TablePagination';
|
||||||
|
import TableRow from '@mui/material/TableRow';
|
||||||
|
import { Box, Typography, Button, TextField } from '@mui/material';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import SearchIcon from '@mui/icons-material/Search';
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ id: 'id', label: 'ID', minWidth: 50 },
|
||||||
|
{ id: 'createdDate', label: 'Created Date', minWidth: 100 },
|
||||||
|
{
|
||||||
|
id: 'name',
|
||||||
|
label: 'Name',
|
||||||
|
minWidth: 100,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toLocaleString('en-US'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'description',
|
||||||
|
label: 'Description',
|
||||||
|
minWidth: 170,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toLocaleString('en-US'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'action',
|
||||||
|
label: 'Action',
|
||||||
|
minWidth: 170,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toFixed(2),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function createData(id, name, description, population, size) {
|
||||||
|
const today = new Date();
|
||||||
|
return { id, name, description, population, size, createdDate: today.toString()};
|
||||||
|
}
|
||||||
|
|
||||||
|
const rows = [
|
||||||
|
createData(1,'India', 'IN', 1324171354, 3287263),
|
||||||
|
createData(2,'China', 'CN', 1403500365, 9596961),
|
||||||
|
createData(3,'Italy', 'IT', 60483973, 301340),
|
||||||
|
createData(4,'United States', 'US', 327167434, 9833520),
|
||||||
|
createData(5,'Canada', 'CA', 37602103, 9984670),
|
||||||
|
createData(6,'Australia', 'AU', 25475400, 7692024),
|
||||||
|
createData(7,'Germany', 'DE', 83019200, 357578),
|
||||||
|
createData(8,'Ireland', 'IE', 4857000, 70273),
|
||||||
|
createData(9,'Mexico', 'MX', 126577691, 1972550),
|
||||||
|
createData(10,'Japan', 'JP', 126317000, 377973),
|
||||||
|
createData(11,'France', 'FR', 67022000, 640679),
|
||||||
|
createData(12,'United Kingdom', 'GB', 67545757, 242495),
|
||||||
|
createData(13,'Russia', 'RU', 146793744, 17098246),
|
||||||
|
createData(14,'Nigeria', 'NG', 200962417, 923768),
|
||||||
|
createData(15,'Brazil', 'BR', 210147125, 8515767),
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function RegisteredSupervisor() {
|
||||||
|
const [page, setPage] = React.useState(0);
|
||||||
|
const [rowsPerPage, setRowsPerPage] = React.useState(10);
|
||||||
|
|
||||||
|
const handleChangePage = (event, newPage) => {
|
||||||
|
setPage(newPage);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChangeRowsPerPage = (event) => {
|
||||||
|
setRowsPerPage(+event.target.value);
|
||||||
|
setPage(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ padding: 3 }}>
|
||||||
|
<Typography sx={{ color: 'gray', size: 'xl' }}>Manage Group</Typography>
|
||||||
|
<Box sx={{ padding: 3 }}>
|
||||||
|
<Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', pr: 2, }}>
|
||||||
|
<Button variant="contained" color="primary">Create New Group</Button>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ display: 'flex', justifyContent: 'flex-start', alignItems: 'center', pr: 2, }}>
|
||||||
|
<TextField id="standard-basic" label="Search" variant="standard" />
|
||||||
|
<IconButton type="button" sx={{ p: '10px' }} aria-label="search">
|
||||||
|
<SearchIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
<Paper sx={{ width: '100%', overflow: 'hidden' }}>
|
||||||
|
<TableContainer sx={{ maxHeight: 440 }}>
|
||||||
|
<Table stickyHeader aria-label="sticky table">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
{columns.map((column) => (
|
||||||
|
<TableCell
|
||||||
|
key={column.id}
|
||||||
|
align={column.align}
|
||||||
|
style={{ minWidth: column.minWidth }}
|
||||||
|
>
|
||||||
|
{column.label}
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{rows
|
||||||
|
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
|
||||||
|
.map((row) => {
|
||||||
|
return (
|
||||||
|
<TableRow hover role="checkbox" tabIndex={-1} key={row.id}>
|
||||||
|
{columns.map((column) => {
|
||||||
|
const value = row[column.id];
|
||||||
|
return (
|
||||||
|
<TableCell key={column.id} align={column.align}>
|
||||||
|
{
|
||||||
|
column.id === 'action' ? (
|
||||||
|
<Button>Details</Button>
|
||||||
|
) : value
|
||||||
|
}
|
||||||
|
</TableCell>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
<TablePagination
|
||||||
|
rowsPerPageOptions={[10, 25, 100]}
|
||||||
|
component="div"
|
||||||
|
count={rows.length}
|
||||||
|
rowsPerPage={rowsPerPage}
|
||||||
|
page={page}
|
||||||
|
onPageChange={handleChangePage}
|
||||||
|
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||||
|
/>
|
||||||
|
</Paper>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
142
src/tdsPages/TopUp.js
Normal file
142
src/tdsPages/TopUp.js
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import Paper from '@mui/material/Paper';
|
||||||
|
import Table from '@mui/material/Table';
|
||||||
|
import TableBody from '@mui/material/TableBody';
|
||||||
|
import TableCell from '@mui/material/TableCell';
|
||||||
|
import TableContainer from '@mui/material/TableContainer';
|
||||||
|
import TableHead from '@mui/material/TableHead';
|
||||||
|
import TablePagination from '@mui/material/TablePagination';
|
||||||
|
import TableRow from '@mui/material/TableRow';
|
||||||
|
import { Box, Typography, Button, TextField } from '@mui/material';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import SearchIcon from '@mui/icons-material/Search';
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ id: 'createdDate', label: 'Tanggal', minWidth: 100 },
|
||||||
|
{ id: 'id', label: 'ID', minWidth: 50 },
|
||||||
|
{
|
||||||
|
id: 'name',
|
||||||
|
label: 'Name',
|
||||||
|
minWidth: 100,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toLocaleString('en-US'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'description',
|
||||||
|
label: 'Description',
|
||||||
|
minWidth: 170,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toLocaleString('en-US'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'action',
|
||||||
|
label: 'Action',
|
||||||
|
minWidth: 170,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toFixed(2),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function createData(id, name, description, population, size) {
|
||||||
|
const today = new Date();
|
||||||
|
return { id, name, description, population, size, createdDate: today.toString()};
|
||||||
|
}
|
||||||
|
|
||||||
|
const rows = [
|
||||||
|
createData(1,'India', 'IN', 1324171354, 3287263),
|
||||||
|
createData(2,'China', 'CN', 1403500365, 9596961),
|
||||||
|
createData(3,'Italy', 'IT', 60483973, 301340),
|
||||||
|
createData(4,'United States', 'US', 327167434, 9833520),
|
||||||
|
createData(5,'Canada', 'CA', 37602103, 9984670),
|
||||||
|
createData(6,'Australia', 'AU', 25475400, 7692024),
|
||||||
|
createData(7,'Germany', 'DE', 83019200, 357578),
|
||||||
|
createData(8,'Ireland', 'IE', 4857000, 70273),
|
||||||
|
createData(9,'Mexico', 'MX', 126577691, 1972550),
|
||||||
|
createData(10,'Japan', 'JP', 126317000, 377973),
|
||||||
|
createData(11,'France', 'FR', 67022000, 640679),
|
||||||
|
createData(12,'United Kingdom', 'GB', 67545757, 242495),
|
||||||
|
createData(13,'Russia', 'RU', 146793744, 17098246),
|
||||||
|
createData(14,'Nigeria', 'NG', 200962417, 923768),
|
||||||
|
createData(15,'Brazil', 'BR', 210147125, 8515767),
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function TopUp() {
|
||||||
|
const [page, setPage] = React.useState(0);
|
||||||
|
const [rowsPerPage, setRowsPerPage] = React.useState(10);
|
||||||
|
|
||||||
|
const handleChangePage = (event, newPage) => {
|
||||||
|
setPage(newPage);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChangeRowsPerPage = (event) => {
|
||||||
|
setRowsPerPage(+event.target.value);
|
||||||
|
setPage(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ padding: 3 }}>
|
||||||
|
<Typography sx={{ color: 'gray', size: 'xl' }}>Manage Group</Typography>
|
||||||
|
<Box sx={{ padding: 3 }}>
|
||||||
|
<Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', pr: 2, }}>
|
||||||
|
<Button variant="contained" color="primary">Create New Group</Button>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ display: 'flex', justifyContent: 'flex-start', alignItems: 'center', pr: 2, }}>
|
||||||
|
<TextField id="standard-basic" label="Search" variant="standard" />
|
||||||
|
<IconButton type="button" sx={{ p: '10px' }} aria-label="search">
|
||||||
|
<SearchIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
<Paper sx={{ width: '100%', overflow: 'hidden' }}>
|
||||||
|
<TableContainer sx={{ maxHeight: 440 }}>
|
||||||
|
<Table stickyHeader aria-label="sticky table">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
{columns.map((column) => (
|
||||||
|
<TableCell
|
||||||
|
key={column.id}
|
||||||
|
align={column.align}
|
||||||
|
style={{ minWidth: column.minWidth }}
|
||||||
|
>
|
||||||
|
{column.label}
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{rows
|
||||||
|
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
|
||||||
|
.map((row) => {
|
||||||
|
return (
|
||||||
|
<TableRow hover role="checkbox" tabIndex={-1} key={row.id}>
|
||||||
|
{columns.map((column) => {
|
||||||
|
const value = row[column.id];
|
||||||
|
return (
|
||||||
|
<TableCell key={column.id} align={column.align}>
|
||||||
|
{
|
||||||
|
column.id === 'action' ? (
|
||||||
|
<Button>Details</Button>
|
||||||
|
) : value
|
||||||
|
}
|
||||||
|
</TableCell>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
<TablePagination
|
||||||
|
rowsPerPageOptions={[10, 25, 100]}
|
||||||
|
component="div"
|
||||||
|
count={rows.length}
|
||||||
|
rowsPerPage={rowsPerPage}
|
||||||
|
page={page}
|
||||||
|
onPageChange={handleChangePage}
|
||||||
|
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||||
|
/>
|
||||||
|
</Paper>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
142
src/tdsPages/TopUpApproval.js
Normal file
142
src/tdsPages/TopUpApproval.js
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import Paper from '@mui/material/Paper';
|
||||||
|
import Table from '@mui/material/Table';
|
||||||
|
import TableBody from '@mui/material/TableBody';
|
||||||
|
import TableCell from '@mui/material/TableCell';
|
||||||
|
import TableContainer from '@mui/material/TableContainer';
|
||||||
|
import TableHead from '@mui/material/TableHead';
|
||||||
|
import TablePagination from '@mui/material/TablePagination';
|
||||||
|
import TableRow from '@mui/material/TableRow';
|
||||||
|
import { Box, Typography, Button, TextField } from '@mui/material';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import SearchIcon from '@mui/icons-material/Search';
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ id: 'id', label: 'ID', minWidth: 50 },
|
||||||
|
{ id: 'createdDate', label: 'Created Date', minWidth: 100 },
|
||||||
|
{
|
||||||
|
id: 'name',
|
||||||
|
label: 'Name',
|
||||||
|
minWidth: 100,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toLocaleString('en-US'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'description',
|
||||||
|
label: 'Description',
|
||||||
|
minWidth: 170,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toLocaleString('en-US'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'action',
|
||||||
|
label: 'Action',
|
||||||
|
minWidth: 170,
|
||||||
|
align: 'right',
|
||||||
|
format: (value) => value.toFixed(2),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function createData(id, name, description, population, size) {
|
||||||
|
const today = new Date();
|
||||||
|
return { id, name, description, population, size, createdDate: today.toString()};
|
||||||
|
}
|
||||||
|
|
||||||
|
const rows = [
|
||||||
|
createData(1,'India', 'IN', 1324171354, 3287263),
|
||||||
|
createData(2,'China', 'CN', 1403500365, 9596961),
|
||||||
|
createData(3,'Italy', 'IT', 60483973, 301340),
|
||||||
|
createData(4,'United States', 'US', 327167434, 9833520),
|
||||||
|
createData(5,'Canada', 'CA', 37602103, 9984670),
|
||||||
|
createData(6,'Australia', 'AU', 25475400, 7692024),
|
||||||
|
createData(7,'Germany', 'DE', 83019200, 357578),
|
||||||
|
createData(8,'Ireland', 'IE', 4857000, 70273),
|
||||||
|
createData(9,'Mexico', 'MX', 126577691, 1972550),
|
||||||
|
createData(10,'Japan', 'JP', 126317000, 377973),
|
||||||
|
createData(11,'France', 'FR', 67022000, 640679),
|
||||||
|
createData(12,'United Kingdom', 'GB', 67545757, 242495),
|
||||||
|
createData(13,'Russia', 'RU', 146793744, 17098246),
|
||||||
|
createData(14,'Nigeria', 'NG', 200962417, 923768),
|
||||||
|
createData(15,'Brazil', 'BR', 210147125, 8515767),
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function TopUpApproval() {
|
||||||
|
const [page, setPage] = React.useState(0);
|
||||||
|
const [rowsPerPage, setRowsPerPage] = React.useState(10);
|
||||||
|
|
||||||
|
const handleChangePage = (event, newPage) => {
|
||||||
|
setPage(newPage);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChangeRowsPerPage = (event) => {
|
||||||
|
setRowsPerPage(+event.target.value);
|
||||||
|
setPage(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ padding: 3 }}>
|
||||||
|
<Typography sx={{ color: 'gray', size: 'xl' }}>Manage Group</Typography>
|
||||||
|
<Box sx={{ padding: 3 }}>
|
||||||
|
<Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', pr: 2, }}>
|
||||||
|
<Button variant="contained" color="primary">Create New Group</Button>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ display: 'flex', justifyContent: 'flex-start', alignItems: 'center', pr: 2, }}>
|
||||||
|
<TextField id="standard-basic" label="Search" variant="standard" />
|
||||||
|
<IconButton type="button" sx={{ p: '10px' }} aria-label="search">
|
||||||
|
<SearchIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
<Paper sx={{ width: '100%', overflow: 'hidden' }}>
|
||||||
|
<TableContainer sx={{ maxHeight: 440 }}>
|
||||||
|
<Table stickyHeader aria-label="sticky table">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
{columns.map((column) => (
|
||||||
|
<TableCell
|
||||||
|
key={column.id}
|
||||||
|
align={column.align}
|
||||||
|
style={{ minWidth: column.minWidth }}
|
||||||
|
>
|
||||||
|
{column.label}
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{rows
|
||||||
|
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
|
||||||
|
.map((row) => {
|
||||||
|
return (
|
||||||
|
<TableRow hover role="checkbox" tabIndex={-1} key={row.id}>
|
||||||
|
{columns.map((column) => {
|
||||||
|
const value = row[column.id];
|
||||||
|
return (
|
||||||
|
<TableCell key={column.id} align={column.align}>
|
||||||
|
{
|
||||||
|
column.id === 'action' ? (
|
||||||
|
<Button>Details</Button>
|
||||||
|
) : value
|
||||||
|
}
|
||||||
|
</TableCell>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
<TablePagination
|
||||||
|
rowsPerPageOptions={[10, 25, 100]}
|
||||||
|
component="div"
|
||||||
|
count={rows.length}
|
||||||
|
rowsPerPage={rowsPerPage}
|
||||||
|
page={page}
|
||||||
|
onPageChange={handleChangePage}
|
||||||
|
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||||
|
/>
|
||||||
|
</Paper>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
77
src/tdsPages/TopUpRequest.js
Normal file
77
src/tdsPages/TopUpRequest.js
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
TextField,
|
||||||
|
Button,
|
||||||
|
Box,
|
||||||
|
Typography,
|
||||||
|
Paper,
|
||||||
|
} from "@mui/material";
|
||||||
|
|
||||||
|
const TopUpRequest = () => {
|
||||||
|
// State for form fields
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
|
||||||
|
// Handle form submission
|
||||||
|
const handleSubmit = (e) => {
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ padding: 3 }}>
|
||||||
|
<Typography sx={{ color: 'gray', size: 'xl' }}>Manage Webservice</Typography>
|
||||||
|
<Box sx={{ padding: 3 }}>
|
||||||
|
<Box sx={{ padding: 3 }}>
|
||||||
|
<Paper sx={{ width: '100%', overflow: 'hidden' }}>
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<Box mb={2} m={2}>
|
||||||
|
<TextField
|
||||||
|
label="Username"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
value={name}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box mb={2} m={2}>
|
||||||
|
<TextField
|
||||||
|
label="Name"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
value={name}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box mb={2} m={2}>
|
||||||
|
<TextField
|
||||||
|
label="Email"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
value={email}
|
||||||
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
|
type="email"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box mt={2} mb={2} textAlign="center">
|
||||||
|
<Button style={{ marginRight: '5px'}} variant="contained">Edit</Button>
|
||||||
|
<Button variant="contained" color="success">Submit</Button>
|
||||||
|
</Box>
|
||||||
|
</form>
|
||||||
|
</Paper>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TopUpRequest;
|
||||||
77
src/tdsPages/Transfer.js
Normal file
77
src/tdsPages/Transfer.js
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
TextField,
|
||||||
|
Button,
|
||||||
|
Box,
|
||||||
|
Typography,
|
||||||
|
Paper,
|
||||||
|
} from "@mui/material";
|
||||||
|
|
||||||
|
const OperationTransfer = () => {
|
||||||
|
// State for form fields
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
|
||||||
|
// Handle form submission
|
||||||
|
const handleSubmit = (e) => {
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ padding: 3 }}>
|
||||||
|
<Typography sx={{ color: 'gray', size: 'xl' }}>Manage Webservice</Typography>
|
||||||
|
<Box sx={{ padding: 3 }}>
|
||||||
|
<Box sx={{ padding: 3 }}>
|
||||||
|
<Paper sx={{ width: '100%', overflow: 'hidden' }}>
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<Box mb={2} m={2}>
|
||||||
|
<TextField
|
||||||
|
label="Username"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
value={name}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box mb={2} m={2}>
|
||||||
|
<TextField
|
||||||
|
label="Name"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
value={name}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box mb={2} m={2}>
|
||||||
|
<TextField
|
||||||
|
label="Email"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
value={email}
|
||||||
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
|
type="email"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box mt={2} mb={2} textAlign="center">
|
||||||
|
<Button style={{ marginRight: '5px'}} variant="contained">Edit</Button>
|
||||||
|
<Button variant="contained" color="success">Submit</Button>
|
||||||
|
</Box>
|
||||||
|
</form>
|
||||||
|
</Paper>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default OperationTransfer;
|
||||||
Reference in New Issue
Block a user