udpate
This commit is contained in:
2
.env
2
.env
@ -1,2 +0,0 @@
|
||||
REACT_APP_BASE_URL=/dashboard
|
||||
REACT_APP_API_URL=https://tpay.shiblysolution.id/api/
|
||||
28
.gitignore
vendored
28
.gitignore
vendored
@ -1,28 +0,0 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
.vercel
|
||||
|
||||
/package-lock.json
|
||||
package-lock.json
|
||||
70
README.md
70
README.md
@ -1,70 +0,0 @@
|
||||
# Getting Started with Create React App
|
||||
|
||||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
||||
|
||||
## Available Scripts
|
||||
|
||||
In the project directory, you can run:
|
||||
|
||||
### `npm start`
|
||||
|
||||
Runs the app in the development mode.\
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
|
||||
|
||||
The page will reload when you make changes.\
|
||||
You may also see any lint errors in the console.
|
||||
|
||||
### `npm test`
|
||||
|
||||
Launches the test runner in the interactive watch mode.\
|
||||
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
||||
|
||||
### `npm run build`
|
||||
|
||||
Builds the app for production to the `build` folder.\
|
||||
It correctly bundles React in production mode and optimizes the build for the best performance.
|
||||
|
||||
The build is minified and the filenames include the hashes.\
|
||||
Your app is ready to be deployed!
|
||||
|
||||
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
||||
|
||||
### `npm run eject`
|
||||
|
||||
**Note: this is a one-way operation. Once you `eject`, you can't go back!**
|
||||
|
||||
If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
|
||||
|
||||
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
|
||||
|
||||
You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
|
||||
|
||||
## Learn More
|
||||
|
||||
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
|
||||
|
||||
To learn React, check out the [React documentation](https://reactjs.org/).
|
||||
|
||||
### Code Splitting
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
|
||||
|
||||
### Analyzing the Bundle Size
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
|
||||
|
||||
### Making a Progressive Web App
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
|
||||
|
||||
### Deployment
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
|
||||
|
||||
### `npm run build` fails to minify
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
|
||||
17132
package-lock.json
generated
17132
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
61
package.json
61
package.json
@ -1,61 +0,0 @@
|
||||
{
|
||||
"name": "new-tpay",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@emotion/styled": "^11.14.0",
|
||||
"@mui/icons-material": "^6.2.1",
|
||||
"@mui/material": "^6.2.1",
|
||||
"@reduxjs/toolkit": "^2.5.0",
|
||||
"@testing-library/jest-dom": "^5.17.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"ajv": "^8.17.1",
|
||||
"ajv-keywords": "^5.1.0",
|
||||
"axios": "^1.7.9",
|
||||
"chart.js": "^4.4.7",
|
||||
"dotenv": "^16.4.7",
|
||||
"js-cookie": "^3.0.5",
|
||||
"react": "^18.3.1",
|
||||
"react-chartjs-2": "^5.2.0",
|
||||
"react-circular-progressbar": "^2.1.0",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-redux": "^9.2.0",
|
||||
"react-router-dom": "^7.1.1",
|
||||
"react-scripts": "5.0.1",
|
||||
"redux": "^5.0.1",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
"prebuild": "node set-homepage.js",
|
||||
"start": "react-scripts start eslint-disable-next-line",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
||||
"@babel/plugin-transform-private-property-in-object": "^7.25.9",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/react": "^16.1.0"
|
||||
},
|
||||
"homepage": "/dashboard"
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.8 KiB |
@ -1,43 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/logo.jpeg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo.jpeg" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>T-Pay| Dashboard</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
BIN
public/logo.jpeg
BIN
public/logo.jpeg
Binary file not shown.
|
Before Width: | Height: | Size: 19 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9.4 KiB |
@ -1,25 +0,0 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
||||
@ -1,21 +0,0 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const dotenv = require('dotenv');
|
||||
|
||||
// Load environment variables from .env
|
||||
dotenv.config();
|
||||
|
||||
// Get the REACT_APP_BASE_URL from .env
|
||||
const baseUrl = process.env.REACT_APP_BASE_URL || '/';
|
||||
|
||||
// Read the package.json file
|
||||
const packageJsonPath = path.join(__dirname, 'package.json');
|
||||
const packageJson = require(packageJsonPath);
|
||||
|
||||
// Update the homepage field in package.json
|
||||
packageJson.homepage = baseUrl;
|
||||
|
||||
// Write the updated package.json back to the file
|
||||
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
||||
|
||||
console.log(`Updated homepage to ${baseUrl} in package.json`);
|
||||
@ -1,8 +0,0 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import App from './App';
|
||||
|
||||
test('renders learn react link', () => {
|
||||
render(<App />);
|
||||
const linkElement = screen.getByText(/learn react/i);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
});
|
||||
39
src/components/Chart.js
vendored
39
src/components/Chart.js
vendored
@ -1,39 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Line } from 'react-chartjs-2';
|
||||
import { Box, Typography } from '@mui/material';
|
||||
import '../style/Chart.css';
|
||||
|
||||
const ChartBox = () => {
|
||||
const data = {
|
||||
labels: ['Jan 01', 'Jan 02', 'Jan 03', 'Jan 04', 'Jan 05', 'Jan 06'],
|
||||
datasets: [
|
||||
{
|
||||
label: 'Cash In',
|
||||
data: [50, 75, 200, 125, 150, 175],
|
||||
backgroundColor: 'rgba(75,192,192,0.4)',
|
||||
borderColor: 'rgba(75,192,192,1)',
|
||||
fill: true, // No fill under the line
|
||||
tension: 0.5, // Line curve
|
||||
},
|
||||
{
|
||||
label: 'Cash Out',
|
||||
data: [100, 90, 80, 70, 60, 50],
|
||||
backgroundColor: 'rgba(255,99,132,0.4)',
|
||||
borderColor: 'rgba(255,99,132,1)',
|
||||
fill: true, // No fill under the line
|
||||
tension: 0.5, // Line curve
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return (
|
||||
<Box sx={{ padding: 2, backgroundColor: '#fff', borderRadius: 2, boxShadow: 1 }}>
|
||||
<Typography variant="h6" sx={{ marginBottom: 2 }}>
|
||||
Account Activities
|
||||
</Typography>
|
||||
<Line data={data} />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default ChartBox;
|
||||
@ -1,95 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import {
|
||||
AppBar,
|
||||
Toolbar,
|
||||
Typography,
|
||||
IconButton,
|
||||
Menu,
|
||||
MenuItem,
|
||||
Avatar,Button
|
||||
} from "@mui/material";
|
||||
import { Mail, AccountCircle } from "@mui/icons-material";
|
||||
import "../style/Header.css";
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
const Header = () => {
|
||||
const [userData, setUserData] = useState('');
|
||||
const [anchorEl, setAnchorEl] = useState(null);
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
let username = Cookies.get('username');
|
||||
setUserData(username)
|
||||
}, []);
|
||||
|
||||
const handleClick = (event) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
function logoutBtn() {
|
||||
Cookies.remove('token');
|
||||
Cookies.remove('role');
|
||||
Cookies.remove('userId');
|
||||
Cookies.remove('username');
|
||||
localStorage.removeItem('roles_list');
|
||||
navigate('/login')
|
||||
}
|
||||
|
||||
const open = Boolean(anchorEl);
|
||||
|
||||
return (
|
||||
<AppBar position="fixed" sx={{ backgroundColor: "#f5f5f5", color: "#333" }}>
|
||||
<Toolbar>
|
||||
<Typography variant="h6" noWrap sx={{ flexGrow: 1 }}></Typography>
|
||||
<IconButton>
|
||||
<Mail />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
size="large"
|
||||
edge="end"
|
||||
aria-label="account"
|
||||
aria-controls="account-menu"
|
||||
aria-haspopup="true"
|
||||
onClick={handleClick}
|
||||
color="inherit"
|
||||
>
|
||||
<AccountCircle />
|
||||
</IconButton>
|
||||
<Button onClick={handleClick}
|
||||
id="basic-button"
|
||||
aria-controls={open ? 'account-menu' : undefined}
|
||||
aria-haspopup="true"
|
||||
aria-expanded={open ? 'true' : undefined}>{userData}
|
||||
</Button>
|
||||
<Menu
|
||||
id="account-menu"
|
||||
anchorEl={anchorEl}
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
onClick={handleClose}
|
||||
transformOrigin={{ horizontal: "right", vertical: "top" }}
|
||||
anchorOrigin={{ horizontal: "right", vertical: "bottom" }}
|
||||
title="User Profile"
|
||||
MenuListProps={{
|
||||
'aria-labelledby': 'basic-button',
|
||||
}}
|
||||
>
|
||||
<MenuItem onClick={() => navigate('/profile')}>
|
||||
<Avatar sx={{ marginRight: 1 }} /> Profile
|
||||
</MenuItem>
|
||||
<MenuItem>
|
||||
<Avatar sx={{ marginRight: 1 }} /> My Account
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => logoutBtn()}>Logout</MenuItem>
|
||||
</Menu>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
@ -1,163 +0,0 @@
|
||||
// src/MyCharts.js
|
||||
import React from 'react';
|
||||
import { Line } from 'react-chartjs-2';
|
||||
import { Doughnut } from 'react-chartjs-2';
|
||||
import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend, ArcElement } from 'chart.js';
|
||||
import '../style/MemberActivity.css';
|
||||
import {
|
||||
Box,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemText,
|
||||
Typography,
|
||||
Divider,
|
||||
} from "@mui/material";
|
||||
import { CircularProgressbar, buildStyles } from "react-circular-progressbar";
|
||||
import "react-circular-progressbar/dist/styles.css";
|
||||
|
||||
// Register Chart.js components
|
||||
ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend, ArcElement);
|
||||
|
||||
const MyCharts = () => {
|
||||
const percentage = 45;
|
||||
// Level Chart (Line Chart) Data
|
||||
const levelData = {
|
||||
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
|
||||
datasets: [
|
||||
{
|
||||
label: 'Level Progress',
|
||||
data: [20, 40, 60, 80, 100, 90, 70],
|
||||
fill: false,
|
||||
borderColor: 'rgb(75, 192, 192)',
|
||||
tension: 0.1,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// Circle Chart (Doughnut Chart) Data
|
||||
const circleData = {
|
||||
labels: ['Completed', 'Remaining'],
|
||||
datasets: [
|
||||
{
|
||||
label: 'Completion',
|
||||
data: [75, 25],
|
||||
backgroundColor: ['rgb(75, 192, 192)', 'rgb(192, 75, 75)'],
|
||||
borderColor: 'rgb(255, 255, 255)',
|
||||
borderWidth: 1,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// Performance Chart (Bar Chart) Data
|
||||
// const performanceData = {
|
||||
// labels: ['Q1', 'Q2', 'Q3', 'Q4'],
|
||||
// datasets: [
|
||||
// {
|
||||
// label: 'Performance',
|
||||
// data: [50, 70, 90, 60],
|
||||
// backgroundColor: 'rgb(75, 192, 192)',
|
||||
// borderColor: 'rgb(0, 123, 255)',
|
||||
// borderWidth: 1,
|
||||
// },
|
||||
// ],
|
||||
// };
|
||||
|
||||
// Chart Options
|
||||
const options = {
|
||||
responsive: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'top',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="charts-container">
|
||||
<div className="chart-item">
|
||||
<Box boxShadow="0px 2px 5px rgba(0, 0, 0, 0.1)">
|
||||
<h3>Level Chart</h3>
|
||||
<Line data={levelData} options={options} />
|
||||
</Box>
|
||||
</div>
|
||||
<div className="chart-item">
|
||||
<Box boxShadow="0px 2px 5px rgba(0, 0, 0, 0.1)">
|
||||
<h3>Circle Chart</h3>
|
||||
<Doughnut data={circleData} options={options} />
|
||||
</Box>
|
||||
</div>
|
||||
<div className="chart-item">
|
||||
<h3>Performance Chart</h3>
|
||||
{/* <Bar data={performanceData} options={options} /> */}
|
||||
<Box
|
||||
display="flex"
|
||||
flexDirection="row"
|
||||
width={300}
|
||||
border="1px solid #ddd"
|
||||
borderRadius={4}
|
||||
overflow="hidden"
|
||||
boxShadow="0px 2px 5px rgba(0, 0, 0, 0.1)"
|
||||
>
|
||||
{/* Sidebar Menu */}
|
||||
<Box
|
||||
width="40%"
|
||||
bgcolor="#f9f9f9"
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
borderRight="1px solid #ddd"
|
||||
py={2}
|
||||
>
|
||||
<List disablePadding>
|
||||
{[
|
||||
"Settings",
|
||||
"Subscription",
|
||||
"Auto Renewal",
|
||||
"Achievements",
|
||||
"Logout",
|
||||
].map((text, index) => (
|
||||
<React.Fragment key={index}>
|
||||
<ListItem button>
|
||||
<ListItemText primary={text} />
|
||||
</ListItem>
|
||||
{index === 3 && <Divider />} {/* Divider after "Achievements" */}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</List>
|
||||
</Box>
|
||||
|
||||
{/* Active User Section */}
|
||||
<Box
|
||||
width="60%"
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
p={2}
|
||||
>
|
||||
<Typography variant="subtitle1" fontWeight="bold">
|
||||
Active User
|
||||
</Typography>
|
||||
<Box width={80} mt={1}>
|
||||
<CircularProgressbar
|
||||
value={percentage}
|
||||
text={`${percentage}%`}
|
||||
styles={buildStyles({
|
||||
textSize: "14px",
|
||||
pathColor: "#4caf50",
|
||||
textColor: "#4caf50",
|
||||
trailColor: "#ddd",
|
||||
pathTransitionDuration: 0.5,
|
||||
})}
|
||||
/>
|
||||
</Box>
|
||||
<Typography variant="body2" mt={1}>
|
||||
{`${percentage}%`}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MyCharts;
|
||||
@ -1,403 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
Drawer,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemText,
|
||||
Accordion,
|
||||
AccordionSummary,
|
||||
AccordionDetails,
|
||||
Typography,
|
||||
Button,
|
||||
// Divider,
|
||||
Box,
|
||||
Tooltip,
|
||||
Avatar,
|
||||
Link
|
||||
} from '@mui/material';
|
||||
|
||||
import SettingsIcon from "@mui/icons-material/Settings";
|
||||
import HelpIcon from "@mui/icons-material/Help";
|
||||
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
||||
import InfoIcon from "@mui/icons-material/Info";
|
||||
import Logout from "@mui/icons-material/Logout";
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import logo from '../logo/logo.jpeg';
|
||||
import Cookies from "js-cookie";
|
||||
import { Link as ReactRouterLink } from 'react-router-dom';
|
||||
|
||||
const Sidebar = () => {
|
||||
const [userRole, setUserRole] = useState('');
|
||||
const navigate = useNavigate();
|
||||
const adminMenu = [
|
||||
{
|
||||
title: 'Group',
|
||||
options: [
|
||||
{
|
||||
title: 'Manage Groups',
|
||||
path: '/manage-groups'
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Member',
|
||||
options: [
|
||||
{
|
||||
title: 'Manage Members',
|
||||
path: '/manage-members'
|
||||
},
|
||||
{
|
||||
title: 'KYC',
|
||||
path: '/manage-member-kyc'
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Access',
|
||||
options: [
|
||||
{
|
||||
title: 'Manage Access Type',
|
||||
path: '/manage-access'
|
||||
},
|
||||
{
|
||||
title: 'Create Member Credential',
|
||||
path: '/manage-member-credential'
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Account',
|
||||
options: [
|
||||
{
|
||||
title: 'Manage Account',
|
||||
path: '/manage-accounts'
|
||||
},
|
||||
{
|
||||
title: 'Manage Currency',
|
||||
path: '/manage-currency'
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Transfer Type',
|
||||
options: [
|
||||
{
|
||||
title: 'Manage Transfer Type',
|
||||
path: '/manage-transfers'
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Notification',
|
||||
options: [
|
||||
{
|
||||
title: 'Manage Notification',
|
||||
path: '/manage-notifications'
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Menu',
|
||||
options: [
|
||||
{
|
||||
title: 'Wellcome',
|
||||
},
|
||||
{
|
||||
title: 'Menu Category',
|
||||
},
|
||||
{
|
||||
title: 'Manage Menu',
|
||||
path: '/manage-menu'
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Message',
|
||||
options: [
|
||||
{
|
||||
title: 'Inbox',
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Webservice',
|
||||
options: [
|
||||
{
|
||||
title: 'Manage Webservice',
|
||||
path: '/manage-webservice'
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Setting',
|
||||
options: [
|
||||
{
|
||||
title: 'User Management',
|
||||
path: '/user-management'
|
||||
},
|
||||
{
|
||||
title: 'Role Management',
|
||||
path: '/role-management'
|
||||
},
|
||||
{
|
||||
title: 'Profile',
|
||||
path: '/profile'
|
||||
},
|
||||
{
|
||||
title: 'Setting',
|
||||
path: '/setting'
|
||||
},
|
||||
{
|
||||
title: 'Master Data',
|
||||
path: '/master-data'
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const esCrowMenu = [
|
||||
{
|
||||
title: 'Home',
|
||||
options: [
|
||||
{
|
||||
title: 'Dashboard',
|
||||
path: '/'
|
||||
},
|
||||
{
|
||||
title: 'Transaction History',
|
||||
path: '/transaction-history'
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Member',
|
||||
options: [
|
||||
{
|
||||
title: 'Manage Members',
|
||||
path: '/manage-members'
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Message',
|
||||
options: [
|
||||
{
|
||||
title: 'Inbox',
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Setting',
|
||||
options: [
|
||||
{
|
||||
title: 'Setting',
|
||||
path: '/setting'
|
||||
}
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const escrowSubMenu = [
|
||||
{
|
||||
title: 'Transaction',
|
||||
options: [
|
||||
{
|
||||
title: 'Transfer',
|
||||
path: '/transfer'
|
||||
},
|
||||
{
|
||||
title: 'Ticket Confirmation',
|
||||
path: '/ticket-confirmation'
|
||||
}
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
const tdsMenu = [
|
||||
{
|
||||
title: 'Home',
|
||||
path: '/'
|
||||
},
|
||||
{
|
||||
title: 'Transaction Report',
|
||||
options: [
|
||||
{
|
||||
title: 'Agent Balance',
|
||||
path: '/agent-balance'
|
||||
},
|
||||
{
|
||||
title: 'Deposit Report',
|
||||
path: '/deposit-report'
|
||||
},
|
||||
{
|
||||
title: 'Topup',
|
||||
path: '/topup'
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Operation',
|
||||
options: [
|
||||
{
|
||||
title: 'Topup Approval',
|
||||
path: '/topup-approval'
|
||||
},
|
||||
{
|
||||
title: 'Topup Request',
|
||||
path: '/topup-request'
|
||||
},
|
||||
{
|
||||
title: 'Transfer',
|
||||
path: '/operation-transfer'
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'User Management',
|
||||
options: [
|
||||
{
|
||||
title: 'Agent Registered',
|
||||
path: '/registered-agent'
|
||||
},
|
||||
{
|
||||
title: 'Supervisor Registered',
|
||||
path: '/registered-supervisor'
|
||||
}
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
useEffect(() => {
|
||||
let token = Cookies.get(`token`);
|
||||
let role = Cookies.get(`role`);
|
||||
if (token && role) setUserRole(role);
|
||||
}, []);
|
||||
|
||||
function roleMenu() {
|
||||
if (userRole === 'Super Admin') return adminMenu
|
||||
if (userRole === 'escrow') return esCrowMenu
|
||||
if (userRole === 'tds') return tdsMenu
|
||||
return []
|
||||
}
|
||||
|
||||
function logoutBtn() {
|
||||
Cookies.remove('token');
|
||||
Cookies.remove('role');
|
||||
Cookies.remove('userId');
|
||||
Cookies.remove('username');
|
||||
localStorage.removeItem('roles_list');
|
||||
navigate('/login');
|
||||
}
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
variant="permanent"
|
||||
sx={{
|
||||
width: 240,
|
||||
'& .MuiDrawer-paper': {
|
||||
width: 240,
|
||||
boxSizing: 'border-box',
|
||||
backgroundColor: '#BA151C',
|
||||
color: '#fff',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Typography variant="h5" sx={{ textAlign: 'center', margin: 2 }}>
|
||||
<Button onClick={() => navigate('/')} sx={{ textAlign: 'center', fontSize: '20px', color: 'wheat' }}>
|
||||
<Avatar
|
||||
src={logo}
|
||||
alt="T-PAY"
|
||||
sx={{ width: 40, height: 40, backgroundColor: 'red' }}
|
||||
/>
|
||||
T-PAY</Button>
|
||||
</Typography>
|
||||
{/* <Divider/> */}
|
||||
<ListOfMenus roleMenu={roleMenu} navigate={navigate} label={`GENERAL`}/>
|
||||
{
|
||||
userRole === 'escrow' ? (
|
||||
<ListOfMenus roleMenu={() => escrowSubMenu} navigate={navigate} label={`Transaction`}/>
|
||||
) : ('')
|
||||
}
|
||||
|
||||
|
||||
{/* FOOTER */}
|
||||
<Box
|
||||
sx={{
|
||||
backgroundColor: "black", // Dark grey color for the bottom
|
||||
padding: 1, // Add padding for content
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between", // Align content in the bottom section
|
||||
position: 'fixed',
|
||||
bottom: 0,
|
||||
maxWidth: 240,
|
||||
marginLeft: -2,
|
||||
}}
|
||||
>
|
||||
<Tooltip title="Setting" arrow>
|
||||
<Button size='small'><SettingsIcon sx={{ color: "white" }} /></Button>
|
||||
</Tooltip>
|
||||
<Tooltip title="Fullscreen" arrow>
|
||||
<Button size='small'><InfoIcon sx={{ color: "white" }} /></Button>
|
||||
</Tooltip>
|
||||
<Tooltip title="Help" arrow>
|
||||
<Button size='small'><HelpIcon sx={{ color: "white" }} /></Button>
|
||||
</Tooltip>
|
||||
<Tooltip title="Logout" arrow>
|
||||
<Button size='small' onClick={() => logoutBtn()}><Logout sx={{ color: "white" }} /></Button>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
|
||||
</Drawer>
|
||||
);
|
||||
};
|
||||
|
||||
function ListOfMenus({roleMenu, navigate, label}) {
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
const handleExpand = (index, menu) => {
|
||||
if (menu.options) return setExpanded((prevExpanded) => (prevExpanded === index ? false : index));
|
||||
};
|
||||
|
||||
function onClickParent(menu) {
|
||||
if (menu.options) return false
|
||||
return navigate(menu.path)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<p style={{ textAlign: 'left', marginLeft: '20px', fontSize: '12px' }}>{label}</p>
|
||||
<List sx={{ marginBottom: 5 }}>
|
||||
{roleMenu().map((menuItem, index) => (
|
||||
<Accordion
|
||||
key={index}
|
||||
expanded={expanded === index}
|
||||
onChange={() => handleExpand(index, menuItem)}
|
||||
sx={{
|
||||
backgroundColor: 'inherit',
|
||||
color: '#fff',
|
||||
boxShadow: 'none',
|
||||
}}
|
||||
>
|
||||
<AccordionSummary expandIcon={menuItem.options ? <ExpandMoreIcon sx={{ color: '#fff' }} /> : ''}>
|
||||
<SettingsIcon sx={{ color: "white" }} />
|
||||
<Typography onClick={() => onClickParent(menuItem)} ml={1}>{menuItem.title}</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
{menuItem.options && menuItem.options.map((option, subIndex) => (
|
||||
<ListItem key={subIndex} sx={{ pl: 2 }}>
|
||||
<ListItemText>
|
||||
<Link to={option.path} component={ReactRouterLink} underline="none">
|
||||
<Typography color='wheat' style={{ textAlign: 'left' }}>{option.title}</Typography>
|
||||
</Link>
|
||||
</ListItemText>
|
||||
</ListItem>
|
||||
))}
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
))}
|
||||
</List>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Sidebar;
|
||||
@ -1,24 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Card, CardContent, Typography } from '@mui/material';
|
||||
import '../style/StatsCard.css'
|
||||
|
||||
const StatsCard = ({ title, value, growth }) => {
|
||||
return (
|
||||
<Card sx={{ minWidth: 200, boxShadow: 2 }}>
|
||||
<CardContent>
|
||||
<Typography variant="h6" color="text.secondary">
|
||||
{title}
|
||||
</Typography>
|
||||
<Typography variant="h4">{value}</Typography>
|
||||
<Typography
|
||||
variant="body2"
|
||||
sx={{ color: growth >= 0 ? 'green' : 'red' }}
|
||||
>
|
||||
{growth}% From last week
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default StatsCard;
|
||||
@ -1,35 +0,0 @@
|
||||
import StatsCard from "../components/StatsCard";
|
||||
import ChartBox from "../components/Chart";
|
||||
import TransactionList from "../components/TransactionList";
|
||||
import MemberActivity from "../components/MemberActivity";
|
||||
import { Box, Grid } from "@mui/material";
|
||||
|
||||
export default function Summary() {
|
||||
return (
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12} sm={6} md={3}>
|
||||
<StatsCard title="Registered Users" value="2500" growth={4} />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={3}>
|
||||
<StatsCard title="Unregistered Users" value="2350" growth={3} />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={3}>
|
||||
<StatsCard title="Total Cash-in" value="2.5M" growth={34} />
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={6} md={3}>
|
||||
<StatsCard title="Total Cash-out" value="4.5M" growth={-12} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Box sx={{ marginTop: 4 }}>
|
||||
<div className="charts-container">
|
||||
<div className="chart-item" style={{ width: '65%' }}><ChartBox /></div>
|
||||
<div className="chart-item" style={{ width: '30%' }}><TransactionList /></div>
|
||||
</div>
|
||||
</Box>
|
||||
<Box sx={{ marginTop: 4 }}>
|
||||
<MemberActivity />
|
||||
</Box>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
@ -1,90 +0,0 @@
|
||||
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,30 +0,0 @@
|
||||
import React from 'react';
|
||||
import { List, ListItem, ListItemText, Box, LinearProgress, Typography } from '@mui/material';
|
||||
import '../style/TransactionList.css';
|
||||
|
||||
const TransactionList = () => {
|
||||
const transactions = [
|
||||
{ type: 'Member Transfer', percentage: 60 },
|
||||
{ type: 'Bill Payment', percentage: 30 },
|
||||
{ type: 'Topup', percentage: 20 },
|
||||
{ type: 'Purchase', percentage: 10 },
|
||||
];
|
||||
|
||||
return (
|
||||
<Box sx={{ padding: 2, backgroundColor: '#fff', borderRadius: 2, boxShadow: 1 }}>
|
||||
<Typography variant="h6" sx={{ marginBottom: 2 }}>
|
||||
Top Transactions
|
||||
</Typography>
|
||||
<List>
|
||||
{transactions.map((transaction, index) => (
|
||||
<ListItem key={index} sx={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>
|
||||
<ListItemText primary={transaction.type} />
|
||||
<LinearProgress variant="determinate" value={transaction.percentage} sx={{ width: '100%' }} />
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default TransactionList;
|
||||
@ -1,46 +0,0 @@
|
||||
// ErrorModal.js
|
||||
import React from "react";
|
||||
import { Modal, Box, Typography, Button } from "@mui/material";
|
||||
|
||||
const ErrorModal = ({ open, onClose, errorMessage }) => {
|
||||
const style = {
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
width: 400,
|
||||
bgcolor: "background.paper",
|
||||
border: "2px solid #000",
|
||||
boxShadow: 24,
|
||||
p: 4,
|
||||
borderRadius: 2,
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
aria-labelledby="error-modal-title"
|
||||
aria-describedby="error-modal-description"
|
||||
>
|
||||
<Box sx={style}>
|
||||
<Typography id="error-modal-title" variant="h6" component="h2">
|
||||
Error
|
||||
</Typography>
|
||||
<Typography id="error-modal-description" sx={{ mt: 2 }}>
|
||||
{errorMessage}
|
||||
</Typography>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="error"
|
||||
onClick={onClose}
|
||||
sx={{ mt: 2 }}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</Box>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default ErrorModal;
|
||||
@ -1,32 +0,0 @@
|
||||
import axios from "axios"
|
||||
import Cookies from "js-cookie"
|
||||
|
||||
const token = Cookies.get(`token`) || null
|
||||
const headers = {
|
||||
// "Access-Control-Allow-Origin": "*",
|
||||
// "content-type": "application/json",
|
||||
}
|
||||
if (token) headers["Authorization"] = `Bearer ${token}`
|
||||
|
||||
const instance = axios.create({
|
||||
// baseURL: `https://tpay.shiblysolution.id/dashboard/`,
|
||||
// baseURL: 'https://api.telkomcel.tl/tpay-stg-dash-api/',
|
||||
baseURL: process.env.REACT_APP_API_URL,
|
||||
headers: headers,
|
||||
})
|
||||
|
||||
export async function fetchApi(path, method, data, params) {
|
||||
try {
|
||||
let query = params || {}
|
||||
query.token = token
|
||||
let response = await instance({
|
||||
method: method,
|
||||
url: path,
|
||||
data: data,
|
||||
params: query,
|
||||
})
|
||||
return response
|
||||
} catch (error) {
|
||||
alert(error.message)
|
||||
}
|
||||
}
|
||||
@ -1,59 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
TextField,
|
||||
Button,
|
||||
Box,
|
||||
Typography,
|
||||
Paper,
|
||||
} from "@mui/material";
|
||||
|
||||
const TicketConfirmationPage = () => {
|
||||
// State for form fields
|
||||
const [ticketId, setTicketId] = useState("");
|
||||
|
||||
// Handle form submission
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
if (ticketId) {
|
||||
console.log("Registered with:", { ticketId });
|
||||
} else {
|
||||
alert("Please fill in all fields.");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-start', pr: 2, }}>
|
||||
<Typography sx={{ color: 'gray', fontSize: '30px' }}>Ticket Confirmation</Typography>
|
||||
</Box>
|
||||
<Box sx={{ paddingTop: 2 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-start', pr: 2, }}>
|
||||
<Typography sx={{ color: 'gray', fontSize: '20px' }}>Confirm Ticket</Typography>
|
||||
</Box>
|
||||
<Box sx={{ padding: 6 }}>
|
||||
<Paper sx={{ width: '100%', overflow: 'hidden' }}>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Box mb={2} m={2}>
|
||||
<TextField
|
||||
label="Ticket ID"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={ticketId}
|
||||
onChange={(e) => setTicketId(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Box mt={2} mb={2} textAlign="center">
|
||||
<Button style={{ marginRight: '5px' }} variant="contained">Reset</Button>
|
||||
<Button variant="contained" color="success">Submit</Button>
|
||||
</Box>
|
||||
</form>
|
||||
</Paper>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default TicketConfirmationPage;
|
||||
@ -1,57 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Box, Typography, Button, Grid, Card, CardContent } from '@mui/material';
|
||||
|
||||
export default function TransactionHistory() {
|
||||
const accounts = [
|
||||
{
|
||||
title: "Merchant Account",
|
||||
description: "Rekening Merchant"
|
||||
},
|
||||
{
|
||||
title: "Deposit Account",
|
||||
description: "Rekening Deposit"
|
||||
},
|
||||
{
|
||||
title: "Cash out/in account to bank",
|
||||
description: "Pooling account to maintain cash in/out member to bank"
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-start', pr: 2, }}>
|
||||
<Typography sx={{ color: 'gray', fontSize: '30px' }}>Transaction History</Typography>
|
||||
</Box>
|
||||
<Box p={3}>
|
||||
<Typography variant="h5" gutterBottom>
|
||||
Select Account
|
||||
</Typography>
|
||||
<Grid container spacing={2}>
|
||||
{accounts.map((account, index) => (
|
||||
<Grid item xs={12} key={index}>
|
||||
<Card variant="outlined">
|
||||
<CardContent>
|
||||
<Grid container justifyContent="space-between" alignItems="center">
|
||||
<Grid item>
|
||||
<Typography variant="h6" color="textSecondary">{account.title}</Typography>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-start', pr: 2, }}>
|
||||
<Typography variant="body2" color="textSecondary">{account.description}</Typography>
|
||||
</Box>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button variant="contained" color="success">
|
||||
View
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@ -1,93 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
TextField,
|
||||
Button,
|
||||
Box,
|
||||
Typography,
|
||||
Paper,
|
||||
} from "@mui/material";
|
||||
|
||||
const TransferPage = () => {
|
||||
// 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 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-start', pr: 2, }}>
|
||||
<Typography sx={{ color: 'gray', fontSize: '30px' }}>Transaction</Typography>
|
||||
</Box>
|
||||
<Box sx={{ paddingTop: 2 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-start', pr: 2, }}>
|
||||
<Typography sx={{ color: 'gray', fontSize: '20px' }}>Transfer</Typography>
|
||||
</Box>
|
||||
<Box sx={{ padding: 6 }}>
|
||||
<Paper sx={{ width: '100%', overflow: 'hidden' }}>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Box mb={2} m={2}>
|
||||
<TextField
|
||||
label="Transaction Type"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</Box>
|
||||
<Box mb={2} m={2}>
|
||||
<TextField
|
||||
label="Destination Account"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</Box>
|
||||
<Box mb={2} m={2}>
|
||||
<TextField
|
||||
label="Amount"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
type="text"
|
||||
required
|
||||
/>
|
||||
</Box>
|
||||
<Box mb={2} m={2}>
|
||||
<TextField
|
||||
label="Description"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
type="text"
|
||||
required
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Box mt={2} mb={2} textAlign="center">
|
||||
<Button style={{ marginRight: '5px' }} variant="contained">Reset</Button>
|
||||
<Button variant="contained" color="success">Submit</Button>
|
||||
</Box>
|
||||
</form>
|
||||
</Paper>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default TransferPage;
|
||||
@ -1,13 +0,0 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
24
src/index.js
24
src/index.js
@ -1,24 +0,0 @@
|
||||
import React from "react"
|
||||
import ReactDOM from "react-dom/client"
|
||||
import "./index.css"
|
||||
import App from "./routes/routes"
|
||||
import reportWebVitals from "./reportWebVitals"
|
||||
import { BrowserRouter } from "react-router-dom"
|
||||
import { Provider } from "react-redux"
|
||||
import store from "./store/store"
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById("root"))
|
||||
root.render(
|
||||
<Provider store={store}>
|
||||
<BrowserRouter basename={process.env.REACT_APP_BASE_URL}>
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
</BrowserRouter>
|
||||
</Provider>
|
||||
)
|
||||
|
||||
// If you want to start measuring performance in your app, pass a function
|
||||
// to log results (for example: reportWebVitals(console.log))
|
||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||
reportWebVitals()
|
||||
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 19 KiB |
@ -1,56 +0,0 @@
|
||||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
height: 40vmin;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.App-logo {
|
||||
animation: App-logo-spin infinite 20s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #282c34;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.App-link {
|
||||
color: #61dafb;
|
||||
}
|
||||
|
||||
@keyframes App-logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.main-content {
|
||||
margin-left: 250px;
|
||||
padding: 20px;
|
||||
background-color: #f9f9f9;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.stats {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.stats-card {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
// import logo from "./logo.svg";
|
||||
import "./Dashboard.css";
|
||||
import Chart from "chart.js/auto";
|
||||
import { CategoryScale } from "chart.js";
|
||||
import Summary from "../components/Summary";
|
||||
|
||||
Chart.register(CategoryScale);
|
||||
|
||||
function Dasboard() {
|
||||
return (
|
||||
<div className="App">
|
||||
<Summary />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Dasboard;
|
||||
@ -1,109 +0,0 @@
|
||||
import React, { useState } from "react"
|
||||
import { TextField, Button, Box, Typography, Grid, Paper, Avatar, Divider } from "@mui/material"
|
||||
import { Link, useNavigate } from "react-router-dom"
|
||||
import Cookies from "js-cookie"
|
||||
import { fetchApi } from "../config/axios"
|
||||
import logo from "../logo/logo.jpeg"
|
||||
|
||||
const LoginPage = () => {
|
||||
// State for email and password
|
||||
const [username, setUsername] = useState("")
|
||||
const [password, setPassword] = useState("")
|
||||
const navigate = useNavigate()
|
||||
|
||||
// Handle form submission
|
||||
const handleSubmit = async (e) => {
|
||||
try {
|
||||
e.preventDefault()
|
||||
if (username && password) {
|
||||
// GET CREDIENTIAL
|
||||
let user = await fetchApi("/d/login", "POST", { username, password })
|
||||
if (user) {
|
||||
if (user.data && user.data.data) {
|
||||
let resUserLogin = user.data.data
|
||||
console.log("resUserLogin", resUserLogin)
|
||||
let roleList = JSON.stringify(resUserLogin.roles_list)
|
||||
Cookies.set("token", resUserLogin.token.access_token, { expires: 1, path: "/" })
|
||||
Cookies.set("role", resUserLogin.role_name, { expires: 1, path: "/" })
|
||||
Cookies.set("userId", resUserLogin.user.id, { expires: 1, path: "/" })
|
||||
Cookies.set("username", resUserLogin.user.username, { expires: 1, path: "/" })
|
||||
// Cookies.set('roles_list', roleList, { expires: 1, path: '/' });
|
||||
localStorage.setItem("roles_list", roleList)
|
||||
navigate("/")
|
||||
} else {
|
||||
alert(user.response.data.message)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
alert("Please fill in both fields.")
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.response) alert(error.response.data.message)
|
||||
else alert(error.message)
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid container justifyContent="center" alignItems="center" style={{ minHeight: "100vh", backgroundColor: "#f4f6f8" }}>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<Paper elevation={3} sx={{ padding: 3 }}>
|
||||
<Typography variant="h5" align="center" gutterBottom>
|
||||
Login
|
||||
</Typography>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Box mb={2}>
|
||||
<TextField label="Email" variant="outlined" fullWidth value={username} onChange={(e) => setUsername(e.target.value)} type="text" required />
|
||||
</Box>
|
||||
<Box mb={2}>
|
||||
<TextField label="Password" variant="outlined" fullWidth value={password} onChange={(e) => setPassword(e.target.value)} type="password" required />
|
||||
</Box>
|
||||
<Box mt={2} textAlign="center">
|
||||
<Button>
|
||||
<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
|
||||
@ -1,156 +0,0 @@
|
||||
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: 'name', label: 'Name', minWidth: 100 },
|
||||
{
|
||||
id: 'internalName',
|
||||
label: 'Internal 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),
|
||||
},
|
||||
];
|
||||
|
||||
const rows = {
|
||||
"recordsFiltered": 5,
|
||||
"data": [
|
||||
{
|
||||
"description": "Default PIN Credential",
|
||||
"id": 1,
|
||||
"internalName": "pin_credential",
|
||||
"name": "PIN Credential"
|
||||
},
|
||||
{
|
||||
"description": "Partner Secret Auth Credential",
|
||||
"id": 2,
|
||||
"internalName": "secret_auth",
|
||||
"name": "Secret Auth"
|
||||
},
|
||||
{
|
||||
"description": "Partner API Key",
|
||||
"id": 3,
|
||||
"internalName": "api_key",
|
||||
"name": "APIKey"
|
||||
},
|
||||
{
|
||||
"description": "Web Access Credential",
|
||||
"id": 4,
|
||||
"internalName": "web_credential",
|
||||
"name": "Web Credential"
|
||||
},
|
||||
{
|
||||
"description": "One To Many Transfers",
|
||||
"id": 5,
|
||||
"internalName": "otm_tpay",
|
||||
"name": "OTM TPay"
|
||||
}
|
||||
],
|
||||
"recordsTotal": 5
|
||||
};
|
||||
|
||||
export default function ManageGroups() {
|
||||
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 Access</Typography>
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', pr: 2, }}>
|
||||
<Button variant="contained" color="primary">Create New Member</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.data
|
||||
.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.data.length}
|
||||
rowsPerPage={rowsPerPage}
|
||||
page={page}
|
||||
onPageChange={handleChangePage}
|
||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||
/>
|
||||
</Paper>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@ -1,211 +0,0 @@
|
||||
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: 'name', label: 'Name', minWidth: 100 },
|
||||
{
|
||||
id: 'description',
|
||||
label: 'Description',
|
||||
minWidth: 100,
|
||||
align: 'right',
|
||||
format: (value) => value.toLocaleString('en-US'),
|
||||
},
|
||||
{
|
||||
id: 'systemAccount',
|
||||
label: 'System Account',
|
||||
minWidth: 170,
|
||||
align: 'right',
|
||||
},
|
||||
{ id: 'createdDate', label: 'Created Date', minWidth: 100 },
|
||||
{
|
||||
id: 'action',
|
||||
label: 'Action',
|
||||
minWidth: 170,
|
||||
align: 'right',
|
||||
format: (value) => value.toFixed(2),
|
||||
},
|
||||
];
|
||||
|
||||
function generateData(data, column) {
|
||||
if (column === 'systemAccount') return data ? 'true' : 'false';
|
||||
return data;
|
||||
}
|
||||
|
||||
const rows = {
|
||||
"recordsFiltered": 5,
|
||||
"data": [
|
||||
{
|
||||
"createdDate": "2019-12-05T09:18:06.000+0000",
|
||||
"creditLimit": null,
|
||||
"currency": null,
|
||||
"description": "Rekening Member eMoney",
|
||||
"formattedCreatedDate": "2019-12-05 18:18:06",
|
||||
"formattedCreditLimit": null,
|
||||
"formattedLowerCreditLimit": null,
|
||||
"formattedUpperCreditLimit": null,
|
||||
"group": null,
|
||||
"id": 1,
|
||||
"lowerCreditLimit": null,
|
||||
"name": "eMoney Account",
|
||||
"systemAccount": false,
|
||||
"upperCreditLimit": null
|
||||
},
|
||||
{
|
||||
"createdDate": "2019-12-11T07:44:29.000+0000",
|
||||
"creditLimit": null,
|
||||
"currency": null,
|
||||
"description": "Topup Account",
|
||||
"formattedCreatedDate": "2019-12-11 16:44:29",
|
||||
"formattedCreditLimit": null,
|
||||
"formattedLowerCreditLimit": null,
|
||||
"formattedUpperCreditLimit": null,
|
||||
"group": null,
|
||||
"id": 24,
|
||||
"lowerCreditLimit": null,
|
||||
"name": "Topup Account",
|
||||
"systemAccount": true,
|
||||
"upperCreditLimit": null
|
||||
},
|
||||
{
|
||||
"createdDate": "2019-12-05T09:19:19.000+0000",
|
||||
"creditLimit": null,
|
||||
"currency": null,
|
||||
"description": "Rekening Merchant",
|
||||
"formattedCreatedDate": "2019-12-05 18:19:19",
|
||||
"formattedCreditLimit": null,
|
||||
"formattedLowerCreditLimit": null,
|
||||
"formattedUpperCreditLimit": null,
|
||||
"group": null,
|
||||
"id": 39,
|
||||
"lowerCreditLimit": null,
|
||||
"name": "Merchant Account",
|
||||
"systemAccount": false,
|
||||
"upperCreditLimit": null
|
||||
},
|
||||
{
|
||||
"createdDate": "2019-12-05T09:19:25.000+0000",
|
||||
"creditLimit": null,
|
||||
"currency": null,
|
||||
"description": "Rekening Deposit",
|
||||
"formattedCreatedDate": "2019-12-05 18:19:25",
|
||||
"formattedCreditLimit": null,
|
||||
"formattedLowerCreditLimit": null,
|
||||
"formattedUpperCreditLimit": null,
|
||||
"group": null,
|
||||
"id": 40,
|
||||
"lowerCreditLimit": null,
|
||||
"name": "Deposit Account",
|
||||
"systemAccount": false,
|
||||
"upperCreditLimit": null
|
||||
},
|
||||
{
|
||||
"createdDate": "2021-04-13T16:45:13.000+0000",
|
||||
"creditLimit": null,
|
||||
"currency": null,
|
||||
"description": "Pooling account to maintain cash in/out member to bank",
|
||||
"formattedCreatedDate": "2021-04-14 01:45:13",
|
||||
"formattedCreditLimit": null,
|
||||
"formattedLowerCreditLimit": null,
|
||||
"formattedUpperCreditLimit": null,
|
||||
"group": null,
|
||||
"id": 41,
|
||||
"lowerCreditLimit": null,
|
||||
"name": "Cash out/in account to bank",
|
||||
"systemAccount": true,
|
||||
"upperCreditLimit": null
|
||||
}
|
||||
],
|
||||
"recordsTotal": 5
|
||||
};
|
||||
|
||||
export default function ManageGroups() {
|
||||
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 Account</Typography>
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', pr: 2, }}>
|
||||
<Button variant="contained" color="primary">Create New Member</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.data
|
||||
.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>
|
||||
) : generateData(value, column.id)
|
||||
}
|
||||
</TableCell>
|
||||
);
|
||||
})}
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<TablePagination
|
||||
rowsPerPageOptions={[10, 25, 100]}
|
||||
component="div"
|
||||
count={rows.data.length}
|
||||
rowsPerPage={rowsPerPage}
|
||||
page={page}
|
||||
onPageChange={handleChangePage}
|
||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||
/>
|
||||
</Paper>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@ -1,113 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
TextField,
|
||||
Button,
|
||||
Box,
|
||||
Typography,
|
||||
Paper,
|
||||
InputLabel,
|
||||
Select,
|
||||
MenuItem
|
||||
} from "@mui/material";
|
||||
|
||||
const SettingPage = () => {
|
||||
// State for form fields
|
||||
const [accessType, setAccessType] = useState("");
|
||||
const [username, setUsername] = useState("");
|
||||
const [credential, setCredential] = useState("");
|
||||
const [confirmCredential, setConfirmCredential] = useState("");
|
||||
|
||||
// Handle form submission
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
if (credential !== confirmCredential) {
|
||||
alert("Credentials do not match!");
|
||||
return;
|
||||
}
|
||||
if (accessType && username && credential && setConfirmCredential) {
|
||||
// Handle registration logic, like calling an API to create the user
|
||||
console.log("Registered with:", { accessType, username, credential });
|
||||
} else {
|
||||
alert("Please fill in all fields.");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<Typography sx={{ color: 'gray', size: 'xl' }}>Access</Typography>
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<Paper sx={{ width: '100%', overflow: 'hidden' }}>
|
||||
<Typography sx={{ color: 'gray', size: 'xl' }}>Manage Member Credential</Typography>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Box mb={2} m={2}>
|
||||
<InputLabel id="demo-simple-select-label">Access Type</InputLabel>
|
||||
<Select
|
||||
labelId="demo-simple-select-label"
|
||||
id="demo-simple-select"
|
||||
value={accessType}
|
||||
label="Access Type"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
required
|
||||
onChange={(e) => setAccessType(e.target.value)}
|
||||
>
|
||||
<MenuItem value={10}>Ten</MenuItem>
|
||||
<MenuItem value={20}>Twenty</MenuItem>
|
||||
<MenuItem value={30}>Thirty</MenuItem>
|
||||
</Select>
|
||||
{/* <TextField
|
||||
label="Access Type"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={accessType}
|
||||
onChange={(e) => setAccessType(e.target.value)}
|
||||
required
|
||||
/> */}
|
||||
</Box>
|
||||
<Box mb={2} m={2}>
|
||||
<TextField
|
||||
label="Username"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</Box>
|
||||
<Box mb={2} m={2}>
|
||||
<TextField
|
||||
label="Credential"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={credential}
|
||||
onChange={(e) => setCredential(e.target.value)}
|
||||
type="password"
|
||||
required
|
||||
/>
|
||||
</Box>
|
||||
<Box mb={2} m={2}>
|
||||
<TextField
|
||||
label="Confirm Credential"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={confirmCredential}
|
||||
onChange={(e) => setConfirmCredential(e.target.value)}
|
||||
type="password"
|
||||
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 SettingPage;
|
||||
@ -1,128 +0,0 @@
|
||||
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: 'name', label: 'Name', minWidth: 100 },
|
||||
{ id: 'code', label: 'Code', minWidth: 100 },
|
||||
{ id: 'prefix', label: 'Prefix', minWidth: 100 },
|
||||
{ id: 'trailer', label: 'Trailer', minWidth: 100 },
|
||||
{ id: 'format', label: 'Format', minWidth: 100 },
|
||||
{ id: 'grouping', label: 'Grouping Separator', minWidth: 100 },
|
||||
{ id: 'decimal', label: 'Decimal Separator', minWidth: 100 },
|
||||
{
|
||||
id: 'action',
|
||||
label: 'Action',
|
||||
minWidth: 170,
|
||||
align: 'right',
|
||||
format: (value) => value.toFixed(2),
|
||||
},
|
||||
];
|
||||
|
||||
const rows = {
|
||||
"recordsFiltered": 1,
|
||||
"data": [
|
||||
{
|
||||
"code": "USD",
|
||||
"decimal": ".",
|
||||
"format": "#,##0.00",
|
||||
"grouping": ",",
|
||||
"id": 2,
|
||||
"name": "Dollar",
|
||||
"prefix": "$",
|
||||
"trailer": ""
|
||||
}
|
||||
],
|
||||
"recordsTotal": 1
|
||||
};
|
||||
|
||||
export default function ManageCurrency() {
|
||||
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 Currency</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.data
|
||||
.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.data.length}
|
||||
rowsPerPage={rowsPerPage}
|
||||
page={page}
|
||||
onPageChange={handleChangePage}
|
||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||
/>
|
||||
</Paper>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@ -1,142 +0,0 @@
|
||||
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 ManageGroups() {
|
||||
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>
|
||||
);
|
||||
}
|
||||
@ -1,240 +0,0 @@
|
||||
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: 'username', label: 'Username', minWidth: 100 },
|
||||
{
|
||||
id: 'group',
|
||||
label: 'Group',
|
||||
minWidth: 100,
|
||||
align: 'right',
|
||||
format: (value) => value.toLocaleString('en-US'),
|
||||
},
|
||||
{
|
||||
id: 'name',
|
||||
label: 'Name',
|
||||
minWidth: 170,
|
||||
align: 'right',
|
||||
format: (value) => value.toLocaleString('en-US'),
|
||||
},
|
||||
{
|
||||
id: 'email',
|
||||
label: 'Email',
|
||||
minWidth: 170,
|
||||
align: 'right',
|
||||
format: (value) => value.toLocaleString('en-US'),
|
||||
},
|
||||
{
|
||||
id: 'createdDate',
|
||||
label: 'Created Date',
|
||||
minWidth: 170,
|
||||
align: 'right',
|
||||
format: (value) => value.toLocaleString('en-US'),
|
||||
},
|
||||
{
|
||||
id: 'action',
|
||||
label: 'Action',
|
||||
minWidth: 170,
|
||||
align: 'right',
|
||||
format: (value) => value.toFixed(2),
|
||||
},
|
||||
];
|
||||
|
||||
const rows = {
|
||||
"recordsFiltered": 35023,
|
||||
"data": [
|
||||
{
|
||||
"createdDate": "2024-12-29 15:56:00",
|
||||
"groupID": 36871,
|
||||
"name": "Tomas Pinto Amaral",
|
||||
"id": 36871,
|
||||
"msisdn": "67074546696",
|
||||
"email": "tomasamaral1302@gmail.com",
|
||||
"username": "67074546696",
|
||||
"group": "REGULER"
|
||||
},
|
||||
{
|
||||
"createdDate": "2024-12-28 23:15:00",
|
||||
"groupID": 36870,
|
||||
"name": "Eleioterio Jeronimo Dos Santos Belmonte",
|
||||
"id": 36870,
|
||||
"msisdn": "67074677364",
|
||||
"email": "Ellebambros6@gmail.con",
|
||||
"username": "67074677364",
|
||||
"group": "REGULER"
|
||||
},
|
||||
{
|
||||
"createdDate": "2024-12-28 06:52:00",
|
||||
"groupID": 36869,
|
||||
"name": "Joao de Brito ximenes ",
|
||||
"id": 36869,
|
||||
"msisdn": "67073650842",
|
||||
"email": "ximenesjhon42@gmail.com",
|
||||
"username": "67073650842",
|
||||
"group": "REGULER"
|
||||
},
|
||||
{
|
||||
"createdDate": "2024-12-28 03:44:00",
|
||||
"groupID": 36868,
|
||||
"name": "nelson da costa moniz calau",
|
||||
"id": 36868,
|
||||
"msisdn": "67078525938",
|
||||
"email": "calaunelson842@gmail.com",
|
||||
"username": "67078525938",
|
||||
"group": "REGULER"
|
||||
},
|
||||
{
|
||||
"createdDate": "2024-12-27 10:35:00",
|
||||
"groupID": 36867,
|
||||
"name": "Arcenia Maria Martins",
|
||||
"id": 36867,
|
||||
"msisdn": "67078601536",
|
||||
"email": "arceniamartins04@gmail.com",
|
||||
"username": "67078601536",
|
||||
"group": "REGULER"
|
||||
},
|
||||
{
|
||||
"createdDate": "2024-12-26 22:29:00",
|
||||
"groupID": 36866,
|
||||
"name": "Yakov",
|
||||
"id": 36866,
|
||||
"msisdn": "79604742286",
|
||||
"email": "makarevichyakov2004@gmail.com",
|
||||
"username": "79604742286",
|
||||
"group": "REGULER"
|
||||
},
|
||||
{
|
||||
"createdDate": "2024-12-23 15:44:00",
|
||||
"groupID": 36865,
|
||||
"name": "Juliao Baptista",
|
||||
"id": 36865,
|
||||
"msisdn": "67078248108",
|
||||
"email": "juliao.baptista.1988@gmail.com",
|
||||
"username": "67078248108",
|
||||
"group": "REGULER"
|
||||
},
|
||||
{
|
||||
"createdDate": "2024-12-20 15:48:00",
|
||||
"groupID": 36864,
|
||||
"name": "Celicia A. Lina da Silva Pereira",
|
||||
"id": 36864,
|
||||
"msisdn": "67073565079",
|
||||
"email": "abulinadasilva@gamail.com",
|
||||
"username": "67073565079",
|
||||
"group": "PREMIUM"
|
||||
},
|
||||
{
|
||||
"createdDate": "2024-12-19 23:26:00",
|
||||
"groupID": 36863,
|
||||
"name": "Noe Afonso guterres",
|
||||
"id": 36863,
|
||||
"msisdn": "67077775543",
|
||||
"email": "noeguterres9@gmail.com",
|
||||
"username": "67077775543",
|
||||
"group": "REGULER"
|
||||
},
|
||||
{
|
||||
"createdDate": "2024-12-19 20:08:00",
|
||||
"groupID": 36862,
|
||||
"name": "Leandro Simões De Araújo ",
|
||||
"id": 36862,
|
||||
"msisdn": "67073854248",
|
||||
"email": "leoandroaraujo016@gmail.com",
|
||||
"username": "67073854248",
|
||||
"group": "REGULER"
|
||||
}
|
||||
],
|
||||
"recordsTotal": 35023
|
||||
};
|
||||
|
||||
export default function ManageGroups() {
|
||||
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 Member</Typography>
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', pr: 2, }}>
|
||||
<Button variant="contained" color="primary">Create New Member</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.data
|
||||
.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.data.length}
|
||||
rowsPerPage={rowsPerPage}
|
||||
page={page}
|
||||
onPageChange={handleChangePage}
|
||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||
/>
|
||||
</Paper>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@ -1,142 +0,0 @@
|
||||
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 ManageMenus() {
|
||||
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 Menu</Typography>
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', pr: 2, }}>
|
||||
<Button variant="contained" color="primary">Create New Member</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>
|
||||
);
|
||||
}
|
||||
@ -1,141 +0,0 @@
|
||||
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: 'name',
|
||||
label: 'Name',
|
||||
minWidth: 100,
|
||||
align: 'right',
|
||||
format: (value) => value.toLocaleString('en-US'),
|
||||
},
|
||||
{
|
||||
id: 'moduleURL',
|
||||
label: 'Destination Module',
|
||||
minWidth: 170,
|
||||
align: 'right',
|
||||
format: (value) => value.toLocaleString('en-US'),
|
||||
},
|
||||
{
|
||||
id: 'action',
|
||||
label: 'Action',
|
||||
minWidth: 170,
|
||||
align: 'right',
|
||||
format: (value) => value.toFixed(2),
|
||||
},
|
||||
];
|
||||
|
||||
const rows = {
|
||||
"recordsFiltered": 2,
|
||||
"data": [
|
||||
{
|
||||
"enabled": false,
|
||||
"id": 1,
|
||||
"moduleURL": "https://tpay.tl/middle-tpay/notif/sender",
|
||||
"name": "notifSender",
|
||||
"notificationType": null,
|
||||
"transferTypeID": null
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"id": 2,
|
||||
"moduleURL": "https://tpay.tl/middle-tpay/notif/receiver",
|
||||
"name": "notifBenefeciary",
|
||||
"notificationType": null,
|
||||
"transferTypeID": null
|
||||
}
|
||||
],
|
||||
"recordsTotal": 2
|
||||
}
|
||||
|
||||
export default function ManageGroups() {
|
||||
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 Notification</Typography>
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', pr: 2, }}>
|
||||
<Button variant="contained" color="primary">Create New Member</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.data
|
||||
.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>
|
||||
);
|
||||
}
|
||||
@ -1,257 +0,0 @@
|
||||
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: 'name',
|
||||
label: 'Name',
|
||||
minWidth: 100,
|
||||
align: 'right',
|
||||
format: (value) => value.toLocaleString('en-US'),
|
||||
},
|
||||
{ id: 'fromAccountName', label: 'From Account', minWidth: 100 },
|
||||
{ id: 'toAccountName', label: 'To Account', minWidth: 100 },
|
||||
{
|
||||
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),
|
||||
},
|
||||
];
|
||||
|
||||
const rows = {
|
||||
"recordsFiltered": 21,
|
||||
"data": [
|
||||
{
|
||||
"description": "Transaction for Payment Mytelkomcel",
|
||||
"fromAccountName": "eMoney Account",
|
||||
"fromAccounts": 1,
|
||||
"id": 58,
|
||||
"maxAmount": 0.00,
|
||||
"maxCount": 0,
|
||||
"minAmount": 0.01,
|
||||
"name": "Payment Mytelkomcel",
|
||||
"otpThreshold": 0.00,
|
||||
"toAccountName": "Merchant Account",
|
||||
"toAccounts": 39
|
||||
},
|
||||
{
|
||||
"description": "Disburse transaction EDTL from user to Agent",
|
||||
"fromAccountName": "Merchant Account",
|
||||
"fromAccounts": 39,
|
||||
"id": 57,
|
||||
"maxAmount": 0.00,
|
||||
"maxCount": 0,
|
||||
"minAmount": 0.00,
|
||||
"name": "Disburse transaction EDTL",
|
||||
"otpThreshold": 0.00,
|
||||
"toAccountName": "Merchant Account",
|
||||
"toAccounts": 39
|
||||
},
|
||||
{
|
||||
"description": "Transaction for payment EDTL",
|
||||
"fromAccountName": "eMoney Account",
|
||||
"fromAccounts": 1,
|
||||
"id": 56,
|
||||
"maxAmount": 0.00,
|
||||
"maxCount": 0,
|
||||
"minAmount": 0.01,
|
||||
"name": "Sosa Token EDTL",
|
||||
"otpThreshold": 0.00,
|
||||
"toAccountName": "Merchant Account",
|
||||
"toAccounts": 39
|
||||
},
|
||||
{
|
||||
"description": "Disburs myloja to agent",
|
||||
"fromAccountName": "Merchant Account",
|
||||
"fromAccounts": 39,
|
||||
"id": 55,
|
||||
"maxAmount": 0.00,
|
||||
"maxCount": 0,
|
||||
"minAmount": 0.01,
|
||||
"name": "Disburs myloja to agent",
|
||||
"otpThreshold": 0.00,
|
||||
"toAccountName": "Merchant Account",
|
||||
"toAccounts": 39
|
||||
},
|
||||
{
|
||||
"description": "Purchase Pulsa",
|
||||
"fromAccountName": "eMoney Account",
|
||||
"fromAccounts": 1,
|
||||
"id": 54,
|
||||
"maxAmount": 0.00,
|
||||
"maxCount": 0,
|
||||
"minAmount": 0.00,
|
||||
"name": "Rekarga Pulsa",
|
||||
"otpThreshold": 0.00,
|
||||
"toAccountName": "Merchant Account",
|
||||
"toAccounts": 39
|
||||
},
|
||||
{
|
||||
"description": "Transaction for payment MyLoja",
|
||||
"fromAccountName": "eMoney Account",
|
||||
"fromAccounts": 1,
|
||||
"id": 53,
|
||||
"maxAmount": 0.00,
|
||||
"maxCount": 0,
|
||||
"minAmount": 0.01,
|
||||
"name": "Payment MyLoja",
|
||||
"otpThreshold": 0.00,
|
||||
"toAccountName": "Merchant Account",
|
||||
"toAccounts": 39
|
||||
},
|
||||
{
|
||||
"description": "Cashout Member to Bank Account",
|
||||
"fromAccountName": "eMoney Account",
|
||||
"fromAccounts": 1,
|
||||
"id": 52,
|
||||
"maxAmount": 300.00,
|
||||
"maxCount": 10,
|
||||
"minAmount": 1.00,
|
||||
"name": "Dada Osan P24",
|
||||
"otpThreshold": 0.00,
|
||||
"toAccountName": "Cash out/in account to bank",
|
||||
"toAccounts": 41
|
||||
},
|
||||
{
|
||||
"description": "Topup Member e-money from Bank",
|
||||
"fromAccountName": "Cash out/in account to bank",
|
||||
"fromAccounts": 41,
|
||||
"id": 51,
|
||||
"maxAmount": 0.00,
|
||||
"maxCount": 0,
|
||||
"minAmount": 1.00,
|
||||
"name": "Top up P24",
|
||||
"otpThreshold": 0.00,
|
||||
"toAccountName": "eMoney Account",
|
||||
"toAccounts": 1
|
||||
},
|
||||
{
|
||||
"description": "Transaction for buying voucher games ",
|
||||
"fromAccountName": "eMoney Account",
|
||||
"fromAccounts": 1,
|
||||
"id": 50,
|
||||
"maxAmount": 0.00,
|
||||
"maxCount": 0,
|
||||
"minAmount": 0.01,
|
||||
"name": "Payment GamesTL",
|
||||
"otpThreshold": 0.00,
|
||||
"toAccountName": "Merchant Account",
|
||||
"toAccounts": 39
|
||||
},
|
||||
{
|
||||
"description": "Partner disburse to agent or driver account",
|
||||
"fromAccountName": "Merchant Account",
|
||||
"fromAccounts": 39,
|
||||
"id": 49,
|
||||
"maxAmount": 0.00,
|
||||
"maxCount": 0,
|
||||
"minAmount": 0.01,
|
||||
"name": "Disburse agent or driver",
|
||||
"otpThreshold": 0.00,
|
||||
"toAccountName": "Merchant Account",
|
||||
"toAccounts": 39
|
||||
}
|
||||
],
|
||||
"recordsTotal": 21
|
||||
};
|
||||
|
||||
export default function ManageGroups() {
|
||||
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 Transfer Type</Typography>
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', pr: 2, }}>
|
||||
<Button variant="contained" color="primary">Create New Member</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.data
|
||||
.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.data.length}
|
||||
rowsPerPage={rowsPerPage}
|
||||
page={page}
|
||||
onPageChange={handleChangePage}
|
||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||
/>
|
||||
</Paper>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@ -1,254 +0,0 @@
|
||||
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: 'name',
|
||||
label: 'Name',
|
||||
minWidth: 100,
|
||||
align: 'right',
|
||||
format: (value) => value.toLocaleString('en-US'),
|
||||
},
|
||||
{
|
||||
id: 'username',
|
||||
label: 'Username',
|
||||
minWidth: 170,
|
||||
align: 'right',
|
||||
format: (value) => value.toLocaleString('en-US'),
|
||||
},
|
||||
{
|
||||
id: 'active',
|
||||
label: 'Enabled',
|
||||
minWidth: 170,
|
||||
align: 'right',
|
||||
format: (value) => value.toLocaleString('en-US'),
|
||||
},
|
||||
{
|
||||
id: 'secureTransaction',
|
||||
label: 'Secure',
|
||||
minWidth: 170,
|
||||
align: 'right',
|
||||
format: (value) => value.toLocaleString('en-US'),
|
||||
},
|
||||
{
|
||||
id: 'action',
|
||||
label: 'Action',
|
||||
minWidth: 170,
|
||||
align: 'right',
|
||||
format: (value) => value.toFixed(2),
|
||||
},
|
||||
];
|
||||
|
||||
const rows = {
|
||||
"recordsFiltered": 13,
|
||||
"data": [
|
||||
{
|
||||
"active": true,
|
||||
"group": null,
|
||||
"hash": "edtl",
|
||||
"id": 20,
|
||||
"name": "dw-tpay-edtl",
|
||||
"password": "123456",
|
||||
"permissionID": null,
|
||||
"secureTransaction": true,
|
||||
"username": "doku_tpay_edtl"
|
||||
},
|
||||
{
|
||||
"active": true,
|
||||
"group": null,
|
||||
"hash": "scheduler",
|
||||
"id": 19,
|
||||
"name": "scheduler",
|
||||
"password": "123456",
|
||||
"permissionID": null,
|
||||
"secureTransaction": false,
|
||||
"username": "scheduler"
|
||||
},
|
||||
{
|
||||
"active": true,
|
||||
"group": null,
|
||||
"hash": "YL29DDQ66XZJ67TH",
|
||||
"id": 18,
|
||||
"name": "tpay-biller-nontransactional",
|
||||
"password": "tpay-biller",
|
||||
"permissionID": null,
|
||||
"secureTransaction": false,
|
||||
"username": "tpay-biller-nontransactional"
|
||||
},
|
||||
{
|
||||
"active": true,
|
||||
"group": null,
|
||||
"hash": "YL29DDQ66XZJ67TH",
|
||||
"id": 17,
|
||||
"name": "tpay-biller",
|
||||
"password": "tpay-biller",
|
||||
"permissionID": null,
|
||||
"secureTransaction": true,
|
||||
"username": "tpay-biller"
|
||||
},
|
||||
{
|
||||
"active": true,
|
||||
"group": null,
|
||||
"hash": "p24",
|
||||
"id": 16,
|
||||
"name": "dw-tpay-p24-nontransactional",
|
||||
"password": "123456",
|
||||
"permissionID": null,
|
||||
"secureTransaction": false,
|
||||
"username": "dokup24tpaynontransactional"
|
||||
},
|
||||
{
|
||||
"active": true,
|
||||
"group": null,
|
||||
"hash": "p24",
|
||||
"id": 15,
|
||||
"name": "dw-tpay-p24",
|
||||
"password": "123456",
|
||||
"permissionID": null,
|
||||
"secureTransaction": true,
|
||||
"username": "dokup24tpay"
|
||||
},
|
||||
{
|
||||
"active": true,
|
||||
"group": null,
|
||||
"hash": "doku",
|
||||
"id": 14,
|
||||
"name": "dw-mobileapi-tpay-non-transactional",
|
||||
"password": "123456",
|
||||
"permissionID": null,
|
||||
"secureTransaction": false,
|
||||
"username": "doku_dev_non"
|
||||
},
|
||||
{
|
||||
"active": true,
|
||||
"group": null,
|
||||
"hash": "dokusimpel",
|
||||
"id": 13,
|
||||
"name": "simpel-ads-tpay",
|
||||
"password": "simpel",
|
||||
"permissionID": null,
|
||||
"secureTransaction": false,
|
||||
"username": "simpel"
|
||||
},
|
||||
{
|
||||
"active": true,
|
||||
"group": null,
|
||||
"hash": "doku",
|
||||
"id": 12,
|
||||
"name": "dw-mobileapi-tpay",
|
||||
"password": "123456",
|
||||
"permissionID": null,
|
||||
"secureTransaction": true,
|
||||
"username": "doku_dev"
|
||||
},
|
||||
{
|
||||
"active": true,
|
||||
"group": null,
|
||||
"hash": "MW7389B8ikj83990",
|
||||
"id": 11,
|
||||
"name": "Middleware Bank",
|
||||
"password": "123456",
|
||||
"permissionID": null,
|
||||
"secureTransaction": false,
|
||||
"username": "mwbank"
|
||||
}
|
||||
],
|
||||
"recordsTotal": 13
|
||||
}
|
||||
|
||||
export default function ManageWebservice() {
|
||||
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);
|
||||
};
|
||||
|
||||
function generateData(data, column) {
|
||||
if (column === 'secureTransaction' || column === 'active') return data ? 'true' : 'false';
|
||||
return data;
|
||||
}
|
||||
|
||||
return (
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<Typography sx={{ color: 'gray', size: 'xl' }}>Manage Webservice</Typography>
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', pr: 2, }}>
|
||||
<Button variant="contained" color="primary">Create New Member</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.data
|
||||
.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>
|
||||
) : generateData(value, column.id)
|
||||
}
|
||||
</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>
|
||||
);
|
||||
}
|
||||
@ -1,133 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import { Grid, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, Box, Typography } from '@mui/material';
|
||||
import ReusableTable from '../components/Table';
|
||||
|
||||
const MasterDataPage = () => {
|
||||
const tableData1 = [
|
||||
{ id: 1, name: 'John Doe', age: 25 },
|
||||
{ id: 2, name: 'Jane Smith', age: 30 },
|
||||
{ id: 3, name: 'John Doe', age: 25 },
|
||||
{ id: 4, name: 'Jane Smith', age: 30 },
|
||||
{ id: 5, name: 'John Doe', age: 25 },
|
||||
];
|
||||
|
||||
const tableData2 = [
|
||||
{ id: 1, product: 'Laptop', price: '$1000' },
|
||||
{ id: 2, product: 'Phone', price: '$600' },
|
||||
];
|
||||
|
||||
return (
|
||||
<Box p={3}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-start', pr: 2, }}>
|
||||
<Typography sx={{ color: 'gray', fontSize: '30px' }}>Master Data</Typography>
|
||||
</Box>
|
||||
<Box p={3}>
|
||||
<Grid container spacing={2}>
|
||||
{/* First Table */}
|
||||
|
||||
{/* <ReusableTable columns={columns} data={users} /> */}
|
||||
|
||||
<Grid item xs={6}>
|
||||
<Typography sx={{ color: 'gray', fontSize: '30px' }}>Kecamatan</Typography>
|
||||
<TableContainer component={Paper}>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>ID</TableCell>
|
||||
<TableCell>Name</TableCell>
|
||||
<TableCell>Age</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{tableData1.map((row) => (
|
||||
<TableRow key={row.id}>
|
||||
<TableCell>{row.id}</TableCell>
|
||||
<TableCell>{row.name}</TableCell>
|
||||
<TableCell>{row.age}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Grid>
|
||||
|
||||
{/* Second Table */}
|
||||
<Grid item xs={6}>
|
||||
<Typography sx={{ color: 'gray', fontSize: '30px' }}>Kelurahan</Typography>
|
||||
<TableContainer component={Paper}>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>ID</TableCell>
|
||||
<TableCell>Product</TableCell>
|
||||
<TableCell>Price</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{tableData2.map((row) => (
|
||||
<TableRow key={row.id}>
|
||||
<TableCell>{row.id}</TableCell>
|
||||
<TableCell>{row.product}</TableCell>
|
||||
<TableCell>{row.price}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Grid>
|
||||
{/* 3rd Table */}
|
||||
<Grid item xs={6}>
|
||||
<Typography sx={{ color: 'gray', fontSize: '30px' }}>Kabupaten</Typography>
|
||||
<TableContainer component={Paper}>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>ID</TableCell>
|
||||
<TableCell>Name</TableCell>
|
||||
<TableCell>Age</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{tableData1.map((row) => (
|
||||
<TableRow key={row.id}>
|
||||
<TableCell>{row.id}</TableCell>
|
||||
<TableCell>{row.name}</TableCell>
|
||||
<TableCell>{row.age}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Grid>
|
||||
|
||||
{/* 4th Table */}
|
||||
<Grid item xs={6}>
|
||||
<Typography sx={{ color: 'gray', fontSize: '30px' }}>Kota</Typography>
|
||||
<TableContainer component={Paper}>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>ID</TableCell>
|
||||
<TableCell>Product</TableCell>
|
||||
<TableCell>Price</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{tableData2.map((row) => (
|
||||
<TableRow key={row.id}>
|
||||
<TableCell>{row.id}</TableCell>
|
||||
<TableCell>{row.product}</TableCell>
|
||||
<TableCell>{row.price}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default MasterDataPage;
|
||||
@ -1,142 +0,0 @@
|
||||
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 MemberKyc() {
|
||||
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 Member KYC</Typography>
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', pr: 2, }}>
|
||||
<Button variant="contained" color="primary">Create New Member</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>
|
||||
);
|
||||
}
|
||||
@ -1,290 +0,0 @@
|
||||
import React, { useState, useEffect } from "react"
|
||||
import { TextField, Button, Box, 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 = () => {
|
||||
// State for form fields
|
||||
const [formData, setFormData] = useState({
|
||||
username: "",
|
||||
name: "",
|
||||
email: "",
|
||||
status: "",
|
||||
idRole: "",
|
||||
password: "",
|
||||
oldPassword: "",
|
||||
confirmPassword: "",
|
||||
newPassword: "",
|
||||
// nik: '',
|
||||
// position: '',
|
||||
// telp: '',
|
||||
// address: '',
|
||||
// organisasi: '',
|
||||
// devisi: '',
|
||||
// unit: '',
|
||||
})
|
||||
const [roles, setRoles] = useState([])
|
||||
const [isModalOpen, setIsModalOpen] = useState(false) // ERROR MSG
|
||||
const [error, setError] = useState("") // ERROR MSG
|
||||
|
||||
useEffect(() => {
|
||||
fetchUser()
|
||||
fetchUserRoles()
|
||||
// eslint-disable-next-line
|
||||
}, [])
|
||||
|
||||
async function fetchUser(params) {
|
||||
try {
|
||||
let userId = Cookies.get(`userId`)
|
||||
let token = Cookies.get(`token`)
|
||||
|
||||
let fetchUsers = await fetchApi(`d/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) {
|
||||
try {
|
||||
let userRoles = await fetchApi("d/user_role/list", "GET", null, {
|
||||
limit: 10,
|
||||
page: 1,
|
||||
with_deleted: true,
|
||||
order_field: "id",
|
||||
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
|
||||
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.");
|
||||
// }
|
||||
}
|
||||
|
||||
const handleChange = (e) => {
|
||||
let { name, value } = e.target
|
||||
if (name === "status" && value === "Y") value = "N"
|
||||
else if (name === "status" && value === "N") value = "Y"
|
||||
setFormData((prev) => ({ ...prev, [name]: value }))
|
||||
}
|
||||
|
||||
const handleError = (msg) => {
|
||||
// ERROR MSG
|
||||
setError(msg)
|
||||
setIsModalOpen(true)
|
||||
}
|
||||
|
||||
const closeModal = () => {
|
||||
// ERROR MSG
|
||||
setIsModalOpen(false)
|
||||
setError("")
|
||||
}
|
||||
|
||||
async function updatePassword() {
|
||||
try {
|
||||
let updatePassword = await fetchApi(`d/user/update_password`, "PUT", {
|
||||
password: formData.password,
|
||||
retype_password: formData.confirmPassword,
|
||||
})
|
||||
console.log(updatePassword)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<WarningDialog // ERROR MSG
|
||||
open={isModalOpen}
|
||||
onClose={closeModal}
|
||||
errorMessage={error}
|
||||
/>
|
||||
<Box sx={{ display: "flex", justifyContent: "flex-start", pr: 2 }}>
|
||||
<Typography sx={{ color: "gray", fontSize: "30px" }}>User Profile</Typography>
|
||||
</Box>
|
||||
<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" name="username" variant="outlined" fullWidth value={formData.username} onChange={handleChange} required disabled />
|
||||
</Box>
|
||||
<Box mb={2} m={2}>
|
||||
<TextField label="Name" name="name" variant="outlined" fullWidth value={formData.name} onChange={handleChange} required />
|
||||
</Box>
|
||||
<Box mb={2} m={2}>
|
||||
<TextField label="Email" name="email" variant="outlined" fullWidth value={formData.email} onChange={handleChange} type="email" required />
|
||||
</Box>
|
||||
<Box mb={2} m={2} sx={{ display: "flex", justifyContent: "flex-start" }}>
|
||||
<FormLabel component="legend">
|
||||
Status :
|
||||
<FormControlLabel required label="Aktif" control={<Checkbox value={formData.status} name="status" onClick={handleChange} checked={formData.status === "Y" ? true : false} />} />
|
||||
</FormLabel>
|
||||
</Box>
|
||||
{/* <Box mb={2} m={2}>
|
||||
<TextField
|
||||
label="NIK"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={formData.nik}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
</Box>
|
||||
<Box mb={2} m={2}>
|
||||
<TextField
|
||||
label="Position"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={formData.position}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
</Box>
|
||||
<Box mb={2} m={2}>
|
||||
<TextField
|
||||
label="Telp"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={formData.telp}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
</Box>
|
||||
<Box mb={2} m={2}>
|
||||
<TextField
|
||||
label="Address"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={formData.address}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
</Box>
|
||||
<Box mb={2} m={2}>
|
||||
<FormControl fullWidth required>
|
||||
<InputLabel id="organization-label">Organization</InputLabel>
|
||||
<Select
|
||||
labelId="organization-label"
|
||||
id="organization"
|
||||
value={formData.organisasi}
|
||||
label="Organization"
|
||||
onChange={handleChange}
|
||||
name='organisasi'
|
||||
>
|
||||
<MenuItem value={'Koperasi'}>Koperasi</MenuItem>
|
||||
<MenuItem value={'Damkar'}>Damkar</MenuItem>
|
||||
<MenuItem value={'Kemasyarakatan'}>Kemasyarakatan</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Box>
|
||||
<Box mb={2} m={2}>
|
||||
<FormControl fullWidth required>
|
||||
<InputLabel id="organization-label">Devision</InputLabel>
|
||||
<Select
|
||||
labelId="organization-label"
|
||||
id="organization"
|
||||
value={formData.devisi}
|
||||
label="Devision"
|
||||
onChange={handleChange}
|
||||
name='devisi'
|
||||
>
|
||||
<MenuItem value={`Staff`}>Staff</MenuItem>
|
||||
<MenuItem value={`Lead`}>Lead</MenuItem>
|
||||
<MenuItem value={`Manager`}>Manager</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Box>
|
||||
<Box mb={2} m={2}>
|
||||
<FormControl fullWidth required>
|
||||
<InputLabel id="organization-label">Unit</InputLabel>
|
||||
<Select
|
||||
labelId="organization-label"
|
||||
id="organization"
|
||||
value={formData.unit}
|
||||
label="Unit"
|
||||
onChange={handleChange}
|
||||
name='unit'
|
||||
>
|
||||
<MenuItem value={1}>Satu</MenuItem>
|
||||
<MenuItem value={2}>Dua</MenuItem>
|
||||
<MenuItem value={3}>Tiga</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Box> */}
|
||||
<Box mb={2} m={2}>
|
||||
<FormControl fullWidth required>
|
||||
<InputLabel id="organization-label">Role</InputLabel>
|
||||
<Select labelId="organization-label" id="organization" value={formData.idRole} label="Role" onChange={handleChange} name="idRole">
|
||||
{roles.map((el, idx) => (
|
||||
<MenuItem key={idx} value={el.id}>
|
||||
{el.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</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">
|
||||
<Button style={{ marginRight: "5px" }} variant="contained">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="contained" color="success">
|
||||
Submit
|
||||
</Button>
|
||||
</Box>
|
||||
</form>
|
||||
</Paper>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<Typography sx={{ color: "gray", fontSize: "30px" }}>User Password</Typography>
|
||||
<Paper sx={{ width: "100%", overflow: "hidden" }}>
|
||||
<Box mb={2} m={2}>
|
||||
<TextField label="Old Password" name="oldPassword" value={formData.oldPassword} onChange={handleChange} fullWidth type="password" required />
|
||||
</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
|
||||
@ -1,141 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import {Link} from 'react-router-dom';
|
||||
import {
|
||||
TextField,
|
||||
Button,
|
||||
Box,
|
||||
Typography,
|
||||
Grid,
|
||||
Paper,
|
||||
InputAdornment,
|
||||
IconButton,
|
||||
FormControl,
|
||||
InputLabel,
|
||||
OutlinedInput,
|
||||
} from "@mui/material";
|
||||
import Visibility from "@mui/icons-material/Visibility";
|
||||
import VisibilityOff from "@mui/icons-material/VisibilityOff";
|
||||
|
||||
const RegisterPage = () => {
|
||||
// State for form fields
|
||||
const [name, setName] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [confirmPassword, setConfirmPassword] = useState("");
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
|
||||
// Handle password visibility toggle
|
||||
const handleClickShowPassword = () => setShowPassword(!showPassword);
|
||||
|
||||
// Handle form submission
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
if (password !== confirmPassword) {
|
||||
alert("Passwords do not match!");
|
||||
return;
|
||||
}
|
||||
if (name && email && password && confirmPassword) {
|
||||
// Handle registration logic, like calling an API to create the user
|
||||
console.log("Registered with:", { name, email, password });
|
||||
} else {
|
||||
alert("Please fill in all fields.");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
style={{ minHeight: "100vh", backgroundColor: "#f4f6f8" }}
|
||||
>
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
<Paper elevation={3} sx={{ padding: 3 }}>
|
||||
<Typography variant="h5" align="center" gutterBottom>
|
||||
Create an Account
|
||||
</Typography>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Box mb={2}>
|
||||
<TextField
|
||||
label="Name"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</Box>
|
||||
<Box mb={2}>
|
||||
<TextField
|
||||
label="Email"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
type="email"
|
||||
required
|
||||
/>
|
||||
</Box>
|
||||
<Box mb={2}>
|
||||
<FormControl variant="outlined" fullWidth required>
|
||||
<InputLabel>Password</InputLabel>
|
||||
<OutlinedInput
|
||||
label="Password"
|
||||
type={showPassword ? "text" : "password"}
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
endAdornment={
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
onClick={handleClickShowPassword}
|
||||
edge="end"
|
||||
>
|
||||
{showPassword ? <VisibilityOff /> : <Visibility />}
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
}
|
||||
/>
|
||||
</FormControl>
|
||||
</Box>
|
||||
<Box mb={2}>
|
||||
<FormControl variant="outlined" fullWidth required>
|
||||
<InputLabel>Confirm Password</InputLabel>
|
||||
<OutlinedInput
|
||||
label="Confirm Password"
|
||||
type={showPassword ? "text" : "password"}
|
||||
value={confirmPassword}
|
||||
onChange={(e) => setConfirmPassword(e.target.value)}
|
||||
endAdornment={
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
onClick={handleClickShowPassword}
|
||||
edge="end"
|
||||
>
|
||||
{showPassword ? <VisibilityOff /> : <Visibility />}
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
}
|
||||
/>
|
||||
</FormControl>
|
||||
</Box>
|
||||
<Box mt={2} textAlign="center">
|
||||
<Button>
|
||||
<Link to="/login">Login</Link>
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
type="submit"
|
||||
fullWidth
|
||||
>
|
||||
Register
|
||||
</Button>
|
||||
</Box>
|
||||
</form>
|
||||
</Paper>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default RegisterPage;
|
||||
@ -1,218 +0,0 @@
|
||||
import React, { useState, useEffect } 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"
|
||||
import { fetchApi } from "../config/axios"
|
||||
|
||||
// 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([])
|
||||
// const [roleMenus, setRoleMenus] = useState([]);
|
||||
const [menus, setMenus] = useState([])
|
||||
const [openDialog, setOpenDialog] = useState(false)
|
||||
const [newRole, setNewRole] = useState("")
|
||||
const [confirmDialog, setConfirmDialog] = useState({
|
||||
open: false,
|
||||
roleName: "",
|
||||
menuData: [],
|
||||
roleId: "",
|
||||
menuId: "",
|
||||
status: null,
|
||||
menuName: "",
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
fetchData()
|
||||
// eslint-disable-next-line
|
||||
}, [])
|
||||
|
||||
async function fetchData(params) {
|
||||
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("d/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) => {
|
||||
setConfirmDialog({ open: true, roleName, menuData, roleId, menuId, status, menuName })
|
||||
}
|
||||
|
||||
const handleConfirm = async (confirm) => {
|
||||
const { roleName, menuData, roleId, menuId, status } = confirmDialog
|
||||
try {
|
||||
if (confirm) {
|
||||
console.log(confirm, confirmDialog)
|
||||
if (status) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
const handleAddRole = async () => {
|
||||
try {
|
||||
await fetchApi("d/user_role/create", "POST", {
|
||||
name: newRole,
|
||||
roles: [],
|
||||
status: "Y",
|
||||
})
|
||||
await fetchData()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
setNewRole("")
|
||||
setOpenDialog(false)
|
||||
}
|
||||
|
||||
const deleteRole = async (role) => {
|
||||
try {
|
||||
let resDeleteRole = await fetchApi(`d/user_role/delete/${role.id}/true`, "DELETE")
|
||||
console.log(resDeleteRole)
|
||||
await fetchData()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
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, idx) => (
|
||||
<TableCell key={idx} align="center">
|
||||
<strong>{menu.name}</strong>
|
||||
</TableCell>
|
||||
))}
|
||||
<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 */}
|
||||
<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,81 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
TextField,
|
||||
Button,
|
||||
Box,
|
||||
Typography,
|
||||
Paper,
|
||||
} from "@mui/material";
|
||||
|
||||
const SettingPage = () => {
|
||||
// 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 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-start', pr: 2, }}>
|
||||
<Typography sx={{ color: 'gray', fontSize: '30px' }}>Setting</Typography>
|
||||
</Box>
|
||||
<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 SettingPage;
|
||||
@ -1,372 +0,0 @@
|
||||
// Import React and Material-UI components
|
||||
import React, { useState, useEffect } from "react"
|
||||
import { Paper, Button, Dialog, DialogActions, DialogContent, DialogTitle, TableContainer, FormLabel, Checkbox, FormControlLabel, Box, Typography, TextField, Grid, MenuItem, InputLabel, Select, FormControl } from "@mui/material"
|
||||
import ReusableTable from "../components/Table"
|
||||
import { fetchApi } from "../config/axios"
|
||||
import WarningDialog from "../components/WarningDialog" // ERROR MSG
|
||||
|
||||
const columns = [
|
||||
{ id: "username", label: "Username" },
|
||||
{ id: "name", label: "Name" },
|
||||
{ id: "email", label: "Email" },
|
||||
{ id: "role_name", label: "Roles" },
|
||||
{ id: "status", label: "Status" },
|
||||
{ id: "created_at", label: "Created" },
|
||||
{ id: "actions", label: "Actions" },
|
||||
]
|
||||
|
||||
const initiateForm = {
|
||||
username: "",
|
||||
name: "",
|
||||
email: "",
|
||||
status: "",
|
||||
id_role: "",
|
||||
password: "",
|
||||
confirmPassword: "",
|
||||
// nik: '',
|
||||
// position: '',
|
||||
// telp: '',
|
||||
// address: '',
|
||||
// organisasi: '',
|
||||
// devisi: '',
|
||||
// unit: '',
|
||||
}
|
||||
|
||||
export default function UserManagement() {
|
||||
const [users, setUsers] = useState([])
|
||||
const [open, setOpen] = useState(false)
|
||||
const [selectedUser, setSelectedUser] = useState(null)
|
||||
const [selectedRoles, setSelectedRoles] = useState([])
|
||||
const [roles, setRoles] = useState([])
|
||||
const [openDialog, setOpenDialog] = useState(false)
|
||||
const [labelDialog, setLabelDialog] = useState("")
|
||||
const [formData, setFormData] = useState(initiateForm)
|
||||
const [errors, setErrors] = useState({ passwordMatch: false })
|
||||
const [isModalOpen, setIsModalOpen] = useState(false) // ERROR MSG
|
||||
const [error, setError] = useState("") // ERROR MSG
|
||||
|
||||
useEffect(() => {
|
||||
fetchUserRoles()
|
||||
fetchUser()
|
||||
// eslint-disable-next-line
|
||||
}, [])
|
||||
|
||||
async function fetchUser(params) {
|
||||
try {
|
||||
let fetchUsers = await fetchApi("d/user/list", "GET", null, {
|
||||
limit: 5,
|
||||
page: 1,
|
||||
with_deleted: true,
|
||||
order_field: "id",
|
||||
order_direction: "ASC",
|
||||
})
|
||||
console.log(fetchUsers)
|
||||
if (fetchUsers.data && fetchUsers.data.data) {
|
||||
let resFetchUsers = fetchUsers.data.data.list
|
||||
let temp = resFetchUsers.map((el) => {
|
||||
if (el.status === "Y") el.status = "Aktif"
|
||||
else el.status = "Tidak Aktif"
|
||||
el.actions = [
|
||||
{ label: "Edit", color: "info", onClick: (row) => handleOpen(row) },
|
||||
{ label: "Delete", color: "secondary", onClick: (row) => handleDelete(row) },
|
||||
]
|
||||
return el
|
||||
})
|
||||
setUsers(temp)
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
handleError(`${error.message}. \n ${error.response.data.error}`)
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchUserRoles(params) {
|
||||
try {
|
||||
let userRoles = await fetchApi("d/user_role/list", "GET", null, {
|
||||
limit: 5,
|
||||
page: 1,
|
||||
with_deleted: true,
|
||||
order_field: "id",
|
||||
order_direction: "ASC",
|
||||
})
|
||||
if (userRoles.data && userRoles.data.data) setRoles(userRoles.data.data.list)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
handleError(`${error.message}. \n ${error.response.data.error}`)
|
||||
}
|
||||
}
|
||||
|
||||
const handleOpen = (user) => {
|
||||
setLabelDialog(`Edit User`)
|
||||
setFormData(user)
|
||||
setOpenDialog(true)
|
||||
// setSelectedUser(user);
|
||||
// setSelectedRoles(user.role_name);
|
||||
// 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 = async () => {
|
||||
try {
|
||||
if (!errors.passwordMatch) {
|
||||
console.log("Form Data:", formData)
|
||||
// setOpen(false);
|
||||
// setFormData(initiateForm);
|
||||
}
|
||||
console.log(formData)
|
||||
formData.status = "Y"
|
||||
if (labelDialog === `Create User`) {
|
||||
delete formData.confirmPassword
|
||||
let createUser = await fetchApi("d/user/create", "POST", formData)
|
||||
console.log(createUser)
|
||||
} else if (labelDialog === `Edit User`) {
|
||||
delete formData.created_at
|
||||
delete formData.updated_at
|
||||
delete formData.role_name
|
||||
delete formData.actions
|
||||
delete formData.confirmPassword
|
||||
console.log(formData)
|
||||
let editUser = await fetchApi(`d/user/update/${formData.id}`, "PUT", formData)
|
||||
console.log("editUser", editUser)
|
||||
}
|
||||
await fetchUser()
|
||||
setOpenDialog(false)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
handleError(`${error.message}. \n ${error.response.data.error}`)
|
||||
}
|
||||
}
|
||||
|
||||
const createNewUserBtn = () => {
|
||||
setLabelDialog(`Create User`)
|
||||
setFormData(initiateForm)
|
||||
setOpenDialog(true)
|
||||
}
|
||||
|
||||
const handleError = (msg) => {
|
||||
// ERROR MSG
|
||||
setError(msg)
|
||||
setIsModalOpen(true)
|
||||
}
|
||||
|
||||
const closeModal = () => {
|
||||
// ERROR MSG
|
||||
setIsModalOpen(false)
|
||||
setError("")
|
||||
}
|
||||
|
||||
return (
|
||||
<Box sx={{ padding: 3 }}>
|
||||
<WarningDialog // ERROR MSG
|
||||
open={isModalOpen}
|
||||
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}>
|
||||
<DialogTitle>Add Roles to {selectedUser?.name}</DialogTitle>
|
||||
<DialogContent>
|
||||
{roles.map((role) => (
|
||||
<FormControlLabel key={role.id} control={<Checkbox checked={selectedRoles.includes(role.name)} onChange={() => handleRoleChange(role.name)} />} label={role.name} />
|
||||
))}
|
||||
</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>{labelDialog}</DialogTitle>
|
||||
<DialogContent sx={{ marginTop: 2 }}>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12}>
|
||||
<TextField sx={{ marginTop: 2 }} label="Username" name="username" value={formData.username} onChange={handleChange} fullWidth required />
|
||||
</Grid>
|
||||
<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}>
|
||||
<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
|
||||
sx={{ marginTop: 2 }}
|
||||
label="Nik"
|
||||
name="nik"
|
||||
value={formData.nik}
|
||||
onChange={handleChange}
|
||||
fullWidth
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<TextField
|
||||
sx={{ marginTop: 2 }}
|
||||
label="Position"
|
||||
name="position"
|
||||
value={formData.position}
|
||||
onChange={handleChange}
|
||||
fullWidth
|
||||
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}>
|
||||
<FormControl fullWidth required>
|
||||
<InputLabel id="organization-label">Organization</InputLabel>
|
||||
<Select
|
||||
labelId="organization-label"
|
||||
id="organization"
|
||||
value={formData.organisasi}
|
||||
label="Organization"
|
||||
onChange={handleChange}
|
||||
name='organisasi'
|
||||
>
|
||||
<MenuItem value={'Koperasi'}>Koperasi</MenuItem>
|
||||
<MenuItem value={'Damkar'}>Damkar</MenuItem>
|
||||
<MenuItem value={'Kemasyarakatan'}>Kemasyarakatan</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<FormControl fullWidth required>
|
||||
<InputLabel id="organization-label">Devision</InputLabel>
|
||||
<Select
|
||||
labelId="organization-label"
|
||||
id="organization"
|
||||
value={formData.devisi}
|
||||
label="Devision"
|
||||
onChange={handleChange}
|
||||
name='devisi'
|
||||
>
|
||||
<MenuItem value={`Staff`}>Staff</MenuItem>
|
||||
<MenuItem value={`Lead`}>Lead</MenuItem>
|
||||
<MenuItem value={`Manager`}>Manager</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<FormControl fullWidth required>
|
||||
<InputLabel id="organization-label">Unit</InputLabel>
|
||||
<Select
|
||||
labelId="organization-label"
|
||||
id="organization"
|
||||
value={formData.unit}
|
||||
label="Unit"
|
||||
onChange={handleChange}
|
||||
name='unit'
|
||||
>
|
||||
<MenuItem value={1}>Satu</MenuItem>
|
||||
<MenuItem value={2}>Dua</MenuItem>
|
||||
<MenuItem value={3}>Tiga</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Grid> */}
|
||||
<Grid item xs={12}>
|
||||
<FormControl fullWidth required>
|
||||
<InputLabel id="organization-label">Role</InputLabel>
|
||||
<Select labelId="organization-label" id="organization" value={formData.id_role} label="Role" onChange={handleChange} name="id_role">
|
||||
{roles.map((el, idx) => (
|
||||
<MenuItem key={idx} value={el.id}>
|
||||
{el.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</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.password || errors.passwordMatch || !formData.id_role || !formData.status || !formData.username}>
|
||||
Submit
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</Box>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
const reportWebVitals = onPerfEntry => {
|
||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
||||
getCLS(onPerfEntry);
|
||||
getFID(onPerfEntry);
|
||||
getFCP(onPerfEntry);
|
||||
getLCP(onPerfEntry);
|
||||
getTTFB(onPerfEntry);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default reportWebVitals;
|
||||
@ -1,384 +0,0 @@
|
||||
import React, { useEffect } from "react"
|
||||
import { Routes, Route, useLocation, Navigate } from "react-router-dom"
|
||||
import "../pages/Dashboard.css"
|
||||
import Sidebar from "../components/SideBar"
|
||||
import Header from "../components/Header"
|
||||
import { Box, Toolbar } from "@mui/material"
|
||||
import Cookies from "js-cookie"
|
||||
// GENERAL
|
||||
import Dasboard from "../pages/Dashboard"
|
||||
import LoginPage from "../pages/Login"
|
||||
import RegisterPage from "../pages/Register"
|
||||
import ProfilePage from "../pages/Profile"
|
||||
// ADMIN
|
||||
import ManageTransfers from "../pages/ManageTransfers"
|
||||
import ManageNotifications from "../pages/ManageNotifications"
|
||||
import ManageAccess from "../pages/ManageAccess"
|
||||
import ManageAccounts from "../pages/ManageAccount"
|
||||
import ManageGroups from "../pages/ManageGroups"
|
||||
import ManageMembers from "../pages/ManageMembers"
|
||||
import ManageMenus from "../pages/ManageMenu"
|
||||
import MemberKyc from "../pages/MemberKYC"
|
||||
import ManageCredential from "../pages/ManageCredential"
|
||||
import ManageCurrency from "../pages/ManageCurrency"
|
||||
import ManageWebservice from "../pages/ManageWebservice"
|
||||
import SettingPage from "../pages/Setting"
|
||||
import UserManagement from "../pages/UserManagement"
|
||||
import RoleMenus from "../pages/RoleManagement"
|
||||
import MasterDataPage from "../pages/MasterData"
|
||||
// ESCROW
|
||||
import TransactionHistory from "../escrowPages/TransactionHistory"
|
||||
import TransferPage from "../escrowPages/Transfer"
|
||||
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"
|
||||
|
||||
// Mock Authentication Function
|
||||
const isAuthenticated = () => {
|
||||
let token = Cookies.get(`token`)
|
||||
let role = Cookies.get(`role`)
|
||||
if (token && role) return true
|
||||
return false
|
||||
}
|
||||
|
||||
// Middleware Component for Protected Routes
|
||||
const ProtectedRoute = ({ children }) => {
|
||||
if (!isAuthenticated()) {
|
||||
return <Navigate to="/login" replace />
|
||||
}
|
||||
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
|
||||
@ -1,5 +0,0 @@
|
||||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom';
|
||||
@ -1,9 +0,0 @@
|
||||
import { configureStore } from '@reduxjs/toolkit';
|
||||
|
||||
export default configureStore({
|
||||
reducer: {
|
||||
users: () => {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
})
|
||||
@ -1,13 +0,0 @@
|
||||
.chart {
|
||||
margin: 20px 250px 0 270px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.chart h3 {
|
||||
margin-bottom: 20px;
|
||||
color: #333;
|
||||
font-size: 18px;
|
||||
}
|
||||
@ -1,26 +0,0 @@
|
||||
.header {
|
||||
height: 60px;
|
||||
background-color: #f5f5f5;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
margin-left: 250px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.welcome h4 {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.actions i {
|
||||
margin-left: 20px;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.actions i:hover {
|
||||
color: #d32f2f;
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
/* src/MyCharts.css */
|
||||
.charts-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 20px;
|
||||
flex-wrap: wrap;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.chart-item {
|
||||
width: 30%;
|
||||
min-width: 250px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.chart-item h3 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
background-color: #d32f2f;
|
||||
color: #fff;
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.sidebar h2 {
|
||||
font-size: 24px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.sidebar ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar ul li {
|
||||
margin: 15px 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.sidebar ul li:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
.stats-card {
|
||||
width: 200px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
text-align: center;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.stats-card h4 {
|
||||
font-size: 16px;
|
||||
color: #666;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
.stats-card h2 {
|
||||
font-size: 28px;
|
||||
margin: 0;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.stats-card span {
|
||||
font-size: 14px;
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.stats-card span.positive {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.stats-card span.negative {
|
||||
color: red;
|
||||
}
|
||||
@ -1,38 +0,0 @@
|
||||
.transaction-list {
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
padding: 20px;
|
||||
margin: 20px 250px 0 270px;
|
||||
}
|
||||
|
||||
.transaction-list h3 {
|
||||
margin-bottom: 20px;
|
||||
color: #333;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.transaction-list ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.transaction-list li {
|
||||
margin: 15px 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.progress {
|
||||
width: 70%;
|
||||
background-color: #eee;
|
||||
height: 8px;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 8px;
|
||||
background-color: #d32f2f;
|
||||
}
|
||||
@ -1,149 +0,0 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
@ -1,149 +0,0 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
@ -1,142 +0,0 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
@ -1,142 +0,0 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
@ -1,142 +0,0 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
@ -1,142 +0,0 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
@ -1,77 +0,0 @@
|
||||
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;
|
||||
@ -1,77 +0,0 @@
|
||||
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