react
This commit is contained in:
		
						commit
						509d01a4e7
					
				
							
								
								
									
										70
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | |||||||
|  | # 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) | ||||||
							
								
								
									
										18867
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										18867
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										61
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | |||||||
|  | { | ||||||
|  |   "name": "log", | ||||||
|  |   "version": "0.1.0", | ||||||
|  |   "private": true, | ||||||
|  |   "dependencies": { | ||||||
|  |     "@emotion/react": "^11.11.3", | ||||||
|  |     "@emotion/styled": "^11.11.0", | ||||||
|  |     "@fortawesome/free-solid-svg-icons": "^6.5.2", | ||||||
|  |     "@fortawesome/react-fontawesome": "^0.2.2", | ||||||
|  |     "@mui/icons-material": "^5.15.20", | ||||||
|  |     "@mui/material": "^5.15.20", | ||||||
|  |     "@mui/styles": "^5.16.4", | ||||||
|  |     "@mui/x-charts": "^7.6.2", | ||||||
|  |     "@mui/x-data-grid": "^7.6.2", | ||||||
|  |     "@popperjs/core": "^2.11.8", | ||||||
|  |     "@testing-library/jest-dom": "^5.17.0", | ||||||
|  |     "@testing-library/react": "^13.4.0", | ||||||
|  |     "@testing-library/user-event": "^13.5.0", | ||||||
|  |     "axios": "^1.6.7", | ||||||
|  |     "mdb-react-ui-kit": "^7.1.0", | ||||||
|  |     "react": "^18.2.0", | ||||||
|  |     "react-barcode": "^1.5.3", | ||||||
|  |     "react-data-grid": "^7.0.0-beta.44", | ||||||
|  |     "react-dom": "^18.2.0", | ||||||
|  |     "react-google-recaptcha": "^3.1.0", | ||||||
|  |     "react-qr-code": "^2.0.14", | ||||||
|  |     "react-router-dom": "^6.21.3", | ||||||
|  |     "react-scripts": "^5.0.1", | ||||||
|  |     "web-vitals": "^2.1.4" | ||||||
|  |   }, | ||||||
|  |   "scripts": { | ||||||
|  |     "start": "react-scripts start", | ||||||
|  |     "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", | ||||||
|  |     "autoprefixer": "^10.4.19", | ||||||
|  |     "postcss": "^8.4.38", | ||||||
|  |     "tailwindcss": "^3.4.4" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										8
									
								
								postcss.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								postcss.config.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | // postcss.config.js
 | ||||||
|  | module.exports = { | ||||||
|  |     plugins: { | ||||||
|  |       tailwindcss: {}, | ||||||
|  |       autoprefixer: {}, | ||||||
|  |     }, | ||||||
|  |   }; | ||||||
|  |    | ||||||
							
								
								
									
										
											BIN
										
									
								
								public/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 3.8 KiB | 
							
								
								
									
										44
									
								
								public/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								public/index.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | |||||||
|  | <!DOCTYPE html> | ||||||
|  | <html lang="en"> | ||||||
|  |   <head> | ||||||
|  |     <meta charset="utf-8" /> | ||||||
|  |     <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> | ||||||
|  |     <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 href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet"> | ||||||
|  |     <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> | ||||||
|  |     <!-- | ||||||
|  |       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>React App</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/logo192.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/logo192.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 5.2 KiB | 
							
								
								
									
										
											BIN
										
									
								
								public/logo512.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/logo512.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 9.4 KiB | 
							
								
								
									
										25
									
								
								public/manifest.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								public/manifest.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | { | ||||||
|  |   "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" | ||||||
|  | } | ||||||
							
								
								
									
										3
									
								
								public/robots.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								public/robots.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | # https://www.robotstxt.org/robotstxt.html | ||||||
|  | User-agent: * | ||||||
|  | Disallow: | ||||||
							
								
								
									
										
											BIN
										
									
								
								src/.DS_Store
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/.DS_Store
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										48
									
								
								src/App.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/App.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | /* src/components/Login.css */ | ||||||
|  | /* .login-container { | ||||||
|  |   width: 300px; | ||||||
|  |   margin: auto; | ||||||
|  |   padding: 20px; | ||||||
|  |   border: 2px solid #3498db; /* Blue border */ | ||||||
|  |   /* border-radius: 10px; | ||||||
|  |   background: linear-gradient(to right, #3498db, #2980b9); /* Gradient background */ | ||||||
|  |   /* color: white; | ||||||
|  |   text-align: center; | ||||||
|  |   box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5); /* Box shadow for depth */ | ||||||
|  | /* } */  | ||||||
|  | 
 | ||||||
|  | /* .login-container label { | ||||||
|  |   display: block; | ||||||
|  |   margin-bottom: 8px; | ||||||
|  | } */ | ||||||
|  | 
 | ||||||
|  | /* .login-container input { | ||||||
|  |   width: 100%; | ||||||
|  |   padding: 8px; | ||||||
|  |   margin-bottom: 16px; | ||||||
|  |   border: 1px solid #ccc; | ||||||
|  |   border-radius: 5px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .login-container button { | ||||||
|  |   width: 100%; | ||||||
|  |   padding: 10px; | ||||||
|  |   background-color: #3498db;  | ||||||
|  |   color: white; | ||||||
|  |   border: none; | ||||||
|  |   border-radius: 5px; | ||||||
|  |   cursor: pointer; | ||||||
|  | } */ | ||||||
|  | 
 | ||||||
|  | /* .login-container a { | ||||||
|  |   color: #fff;  | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .login-container a:hover { | ||||||
|  |   text-decoration: underline; | ||||||
|  | } */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* .login-container input[type="checkbox"] { | ||||||
|  |   margin-right: 5px; | ||||||
|  | }   */ | ||||||
							
								
								
									
										46
									
								
								src/App.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/App.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | |||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | import React from "react"; | ||||||
|  | import { Routes, Route } from "react-router-dom"; | ||||||
|  | import Login from "./components/Login/Login"; | ||||||
|  | import Dashboard from "./components/Dashboard/dashboard"; | ||||||
|  | import UserMaintance from "./components/Dashboard/UserMaintance"; | ||||||
|  | import UserGroupMaintance from "./components/Dashboard/UserGroupMaintance/UserGroupMaintance"; | ||||||
|  | import CodeExtension from "./components/Dashboard/Codeextension"; | ||||||
|  | import Extension from "./components/Dashboard/Extension"; | ||||||
|  | import DynamicTable from "./components/Dashboard/Dynamictable"; | ||||||
|  | import Form from "./components/Dashboard/Form"; | ||||||
|  | import ForgotPassword from "./components/Login/ForgotPassword"; | ||||||
|  | import CreateAccount from "./components/Login/CreateAccount"; | ||||||
|  | import Apitest from "./components/Dashboard/Test/Apitest"; | ||||||
|  | 
 | ||||||
|  | const App = () => { | ||||||
|  |   return ( | ||||||
|  |     <Routes> | ||||||
|  |       <Route path="/" element={<Login />} /> | ||||||
|  |       <Route path="/Dashboard" element={<Dashboard />} /> | ||||||
|  |       <Route path="/UserGroupMaintance" element={<UserGroupMaintance />} /> | ||||||
|  |       <Route path="/Dashboard/UserMaintance" element={<UserMaintance />} /> | ||||||
|  |       <Route path="/CodeExtension" element={<CodeExtension />} /> | ||||||
|  |       <Route | ||||||
|  |         path="/Dashboard/DashboardBuilder" | ||||||
|  |         element={<dashboardBuilder />} | ||||||
|  |       /> | ||||||
|  |       <Route path="/Extension" element={<Extension />} /> | ||||||
|  |       <Route path="/Dynamictable" element={<DynamicTable />} /> | ||||||
|  |       <Route path="/Form" element={<Form />} /> | ||||||
|  |       <Route path="/ForgotPassword" element={<ForgotPassword />} /> | ||||||
|  |       <Route path="/CreateAccount" element={<CreateAccount />} /> | ||||||
|  |       <Route path="/Test" element={<Apitest />} /> | ||||||
|  | 
 | ||||||
|  |       {/* buildercomponents */} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     </Routes> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default App; | ||||||
							
								
								
									
										8
									
								
								src/App.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/App.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | 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(); | ||||||
|  | }); | ||||||
							
								
								
									
										26
									
								
								src/ErrorBoundary.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/ErrorBoundary.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | import React, { Component } from 'react'; | ||||||
|  | 
 | ||||||
|  | class ErrorBoundary extends Component { | ||||||
|  |   constructor(props) { | ||||||
|  |     super(props); | ||||||
|  |     this.state = { hasError: false }; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static getDerivedStateFromError(error) { | ||||||
|  |     return { hasError: true }; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   componentDidCatch(error, errorInfo) { | ||||||
|  |     console.error("Error Boundary Caught an Error", error, errorInfo); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   render() { | ||||||
|  |     if (this.state.hasError) { | ||||||
|  |       return <h1>Something went wrong.</h1>; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return this.props.children;  | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default ErrorBoundary; | ||||||
							
								
								
									
										197
									
								
								src/components/Dashboard/AccessType/AccessType.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								src/components/Dashboard/AccessType/AccessType.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,197 @@ | |||||||
|  | import React, { useState, useEffect } from "react"; | ||||||
|  | import { Button, Checkbox, Container, FormControlLabel, Modal, Table, TextField, Typography } from "@mui/material"; | ||||||
|  | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
|  | import { faEdit, faTrashAlt, faPlus } from "@fortawesome/free-solid-svg-icons"; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | const api = process.env.REACT_APP_API_BASE_URL; | ||||||
|  | function AccessTypeManagement() { | ||||||
|  |   const [accessTypes, setAccessTypes] = useState([]); | ||||||
|  |   const [showAddEditModal, setShowAddEditModal] = useState(false); | ||||||
|  |   const [currentAccessType, setCurrentAccessType] = useState({ | ||||||
|  |     typeId: "", | ||||||
|  |     typeName: "", | ||||||
|  |     description: "", | ||||||
|  |     isActive: false | ||||||
|  |   }); | ||||||
|  |   const [isEditing, setIsEditing] = useState(false); | ||||||
|  |   const [recordsPerPage, setRecordsPerPage] = useState(10); | ||||||
|  |   const [visibleColumns, setVisibleColumns] = useState({ | ||||||
|  |     typeId: true, | ||||||
|  |     typeName: true, | ||||||
|  |     description: true, | ||||||
|  |     isActive: true, | ||||||
|  |     actions: true | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     const token = localStorage.getItem("token") | ||||||
|  |     const apiUrl = `${api}/api/getAllAccessTypes`; | ||||||
|  |     const fetchAccessTypes = async () => { | ||||||
|  |       try { | ||||||
|  |         const response = await fetch(apiUrl, { | ||||||
|  |           method: "GET", | ||||||
|  |           headers: { | ||||||
|  |             "Content-Type": "application/json", | ||||||
|  |             Authorization: `Bearer ${token}`, | ||||||
|  |           }, | ||||||
|  |         }); | ||||||
|  |         if (!response.ok) { | ||||||
|  |           throw new Error(`HTTP error! status: ${response.status}`); | ||||||
|  |         } | ||||||
|  |         const data = await response.json(); | ||||||
|  |         setAccessTypes(data); | ||||||
|  |       } catch (error) { | ||||||
|  |         console.error("Error fetching access types:", error); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |     fetchAccessTypes(); | ||||||
|  |   }, []); | ||||||
|  | 
 | ||||||
|  |   const toggleColumn = (column) => { | ||||||
|  |     setVisibleColumns((prev) => ({ | ||||||
|  |       ...prev, | ||||||
|  |       [column]: !prev[column], | ||||||
|  |     })); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleInputChange = (event) => { | ||||||
|  |     const { name, value, checked } = event.target; | ||||||
|  |     setCurrentAccessType(prev => ({ | ||||||
|  |       ...prev, | ||||||
|  |       [name]: name === "isActive" ? checked : value | ||||||
|  |     })); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleSubmit = (event) => { | ||||||
|  |     event.preventDefault(); | ||||||
|  |     if (isEditing) { | ||||||
|  |       setAccessTypes(accessTypes.map(type => | ||||||
|  |         type.typeId === currentAccessType.typeId ? currentAccessType : type | ||||||
|  |       )); | ||||||
|  |     } else { | ||||||
|  |       const newTypeId = `ID${accessTypes.length + 1}`; | ||||||
|  |       setAccessTypes([...accessTypes, { ...currentAccessType, typeId: newTypeId }]); | ||||||
|  |     } | ||||||
|  |     setShowAddEditModal(false); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const openModal = (type = { typeId: "", typeName: "", description: "", isActive: false }) => { | ||||||
|  |     setIsEditing(!!type.typeId); | ||||||
|  |     setCurrentAccessType(type); | ||||||
|  |     setShowAddEditModal(true); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleDelete = (typeId) => { | ||||||
|  |     setAccessTypes(accessTypes.filter(type => type.typeId !== typeId)); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <Container className="mt-5"> | ||||||
|  |       <div style={{ display: "flex", justifyContent: "flex-end", marginBottom: "1rem" }}> | ||||||
|  |         <Button onClick={() => openModal()} variant="contained" startIcon={<FontAwesomeIcon icon={faPlus} />}> | ||||||
|  |           ADD | ||||||
|  |         </Button> | ||||||
|  |       </div> | ||||||
|  |       <div className="table-responsive"> | ||||||
|  |         <Table striped bordered hover> | ||||||
|  |           <thead> | ||||||
|  |             <tr> | ||||||
|  |               {Object.entries(visibleColumns).map(([key, visible]) => | ||||||
|  |                 visible ? <th key={key}>{key.charAt(0).toUpperCase() + key.slice(1)}</th> : null | ||||||
|  |               )} | ||||||
|  |             </tr> | ||||||
|  |           </thead> | ||||||
|  |           <tbody> | ||||||
|  |             {accessTypes.slice(0, recordsPerPage).map((type, index) => ( | ||||||
|  |               <tr key={index}> | ||||||
|  |                 {Object.entries(visibleColumns).map(([key, visible]) => | ||||||
|  |                   visible ? ( | ||||||
|  |                     <td key={key}> | ||||||
|  |                       {key === "actions" ? ( | ||||||
|  |                         <> | ||||||
|  |                           <Button variant="light" size="small" onClick={() => openModal(type)}> | ||||||
|  |                             <FontAwesomeIcon icon={faEdit} /> | ||||||
|  |                           </Button> | ||||||
|  |                           <Button variant="light" size="small" onClick={() => handleDelete(type.typeId)}> | ||||||
|  |                             <FontAwesomeIcon icon={faTrashAlt} /> | ||||||
|  |                           </Button> | ||||||
|  |                         </> | ||||||
|  |                       ) : ( | ||||||
|  |                         key === "isActive" ? ( | ||||||
|  |                           <FormControlLabel | ||||||
|  |                             control={<Checkbox checked={type[key]} onChange={handleInputChange} name={key} />} | ||||||
|  |                             label="" | ||||||
|  |                           /> | ||||||
|  |                         ) : ( | ||||||
|  |                           type[key] | ||||||
|  |                         ) | ||||||
|  |                       )} | ||||||
|  |                     </td> | ||||||
|  |                   ) : null | ||||||
|  |                 )} | ||||||
|  |               </tr> | ||||||
|  |             ))} | ||||||
|  |           </tbody> | ||||||
|  |         </Table> | ||||||
|  |       </div> | ||||||
|  | 
 | ||||||
|  |       <div style={{ display: "flex", justifyContent: "space-between", marginTop: "1rem" }}> | ||||||
|  |         <div> | ||||||
|  |           <Typography variant="body1">Manage Columns</Typography> | ||||||
|  |           {Object.keys(visibleColumns).map((key) => ( | ||||||
|  |             <FormControlLabel | ||||||
|  |               key={key} | ||||||
|  |               control={<Checkbox checked={visibleColumns[key]} onChange={() => toggleColumn(key)} />} | ||||||
|  |               label={key.charAt(0).toUpperCase() + key.slice(1)} | ||||||
|  |             /> | ||||||
|  |           ))} | ||||||
|  |         </div> | ||||||
|  |         <div> | ||||||
|  |           <Typography variant="body1">Records Per Page</Typography> | ||||||
|  |           {[10, 20, 30, 50].map((number) => ( | ||||||
|  |             <Button key={number} onClick={() => setRecordsPerPage(number)} variant="outlined"> | ||||||
|  |               {number} | ||||||
|  |             </Button> | ||||||
|  |           ))} | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  | 
 | ||||||
|  |       <Modal open={showAddEditModal} onClose={() => setShowAddEditModal(false)}> | ||||||
|  |         <div style={{ padding: "1rem", backgroundColor: "white", borderRadius: "8px", maxWidth: "400px", margin: "auto" }}> | ||||||
|  |           <Typography variant="h6" gutterBottom>{isEditing ? "Edit Access Type" : "Add Access Type"}</Typography> | ||||||
|  |           <form onSubmit={handleSubmit}> | ||||||
|  |             <TextField | ||||||
|  |               fullWidth | ||||||
|  |               label="Type Name" | ||||||
|  |               name="typeName" | ||||||
|  |               value={currentAccessType.typeName} | ||||||
|  |               onChange={handleInputChange} | ||||||
|  |               required | ||||||
|  |               style={{ marginBottom: "1rem" }} | ||||||
|  |             /> | ||||||
|  |             <TextField | ||||||
|  |               fullWidth | ||||||
|  |               label="Description" | ||||||
|  |               name="description" | ||||||
|  |               value={currentAccessType.description} | ||||||
|  |               onChange={handleInputChange} | ||||||
|  |               style={{ marginBottom: "1rem" }} | ||||||
|  |             /> | ||||||
|  |             <FormControlLabel | ||||||
|  |               control={<Checkbox checked={currentAccessType.isActive} onChange={handleInputChange} name="isActive" />} | ||||||
|  |               label="Active?" | ||||||
|  |               style={{ marginBottom: "1rem" }} | ||||||
|  |             /> | ||||||
|  |             <div style={{ display: "flex", justifyContent: "flex-end" }}> | ||||||
|  |               <Button variant="outlined" onClick={() => setShowAddEditModal(false)} style={{ marginRight: "1rem" }}>Close</Button> | ||||||
|  |               <Button variant="contained" type="submit">{isEditing ? "Update" : "Add"}</Button> | ||||||
|  |             </div> | ||||||
|  |           </form> | ||||||
|  |         </div> | ||||||
|  |       </Modal> | ||||||
|  |     </Container> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default AccessTypeManagement; | ||||||
							
								
								
									
										137
									
								
								src/components/Dashboard/ApiRegistery/ApiRegistery.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								src/components/Dashboard/ApiRegistery/ApiRegistery.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,137 @@ | |||||||
|  | import React, { useState, useEffect, useRef } from "react"; | ||||||
|  | import { Box, Button } from "@mui/material"; | ||||||
|  | import { DataGrid, GridToolbarContainer } from "@mui/x-data-grid"; | ||||||
|  | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
|  | import { faEllipsisV } from "@fortawesome/free-solid-svg-icons"; | ||||||
|  | 
 | ||||||
|  | const api = process.env.REACT_APP_API_BASE_URL; | ||||||
|  | 
 | ||||||
|  | function CustomToolbar({ apiRef, handleModal }) { | ||||||
|  |   const handleGoToPage1 = () => { | ||||||
|  |     if (apiRef.current) { | ||||||
|  |       apiRef.current.setPage(1); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <GridToolbarContainer className="flex justify-between p-2 bg-gray-200"> | ||||||
|  |       <Button | ||||||
|  |         onClick={handleGoToPage1} | ||||||
|  |         className="bg-blue-500 text-white px-4 py-2 rounded shadow hover:bg-blue-600" | ||||||
|  |       > | ||||||
|  |         Go to page 1 | ||||||
|  |       </Button> | ||||||
|  |       <Button | ||||||
|  |         onClick={handleModal} | ||||||
|  |         className="bg-green-500 text-white px-4 py-2 rounded shadow hover:bg-green-600" | ||||||
|  |       > | ||||||
|  |         Add item | ||||||
|  |       </Button> | ||||||
|  |     </GridToolbarContainer> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function ApiRegistery() { | ||||||
|  |   const [menuItems, setMenuItems] = useState([]); | ||||||
|  |   const [selectedMenuItem, setSelectedMenuItem] = useState(null); | ||||||
|  |   const [isModalOpen, setIsModalOpen] = useState(false); | ||||||
|  |   const apiRef = useRef(null); | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     const fetchData = async () => { | ||||||
|  |       const token = localStorage.getItem("token"); // Get token from local storage
 | ||||||
|  |       try { | ||||||
|  |         const response = await fetch( | ||||||
|  |           `${api}/Api_registery_header/Api_registery_header`, | ||||||
|  |           { | ||||||
|  |             headers: { | ||||||
|  |               Authorization: `Bearer ${token}`, | ||||||
|  |             }, | ||||||
|  |           } | ||||||
|  |         ); | ||||||
|  |         const data = await response.json(); | ||||||
|  |         setMenuItems(data); | ||||||
|  |       } catch (error) { | ||||||
|  |         console.error("Error fetching data:", error); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     fetchData(); | ||||||
|  |   }, []); | ||||||
|  | 
 | ||||||
|  |   const handleThreeDotsClick = (menuItemId) => { | ||||||
|  |     setSelectedMenuItem(menuItemId === selectedMenuItem ? null : menuItemId); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const columns = [ | ||||||
|  |     { | ||||||
|  |       field: "id", | ||||||
|  |       headerName: "ID", | ||||||
|  |       width: 300, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "table_name", | ||||||
|  |       headerName: "Table Name", | ||||||
|  |       width: 350, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "actions", | ||||||
|  |       headerName: "Actions", | ||||||
|  |       width: 150, | ||||||
|  |       renderCell: ({ row }) => ( | ||||||
|  |         <div className="relative"> | ||||||
|  |           <div | ||||||
|  |             className="cursor-pointer" | ||||||
|  |             onClick={() => handleThreeDotsClick(row.id)} | ||||||
|  |           > | ||||||
|  |             <FontAwesomeIcon icon={faEllipsisV} /> | ||||||
|  |           </div> | ||||||
|  |           {selectedMenuItem === row.id && ( | ||||||
|  |             <div className="absolute right-0 mt-2 py-2 w-48 bg-white rounded-lg shadow-xl"> | ||||||
|  |               <button className="block px-4 py-2 text-gray-800 hover:bg-gray-200 w-full text-left"> | ||||||
|  |                 Edit | ||||||
|  |               </button> | ||||||
|  |               <button className="block px-4 py-2 text-gray-800 hover:bg-gray-200 w-full text-left"> | ||||||
|  |                 Delete | ||||||
|  |               </button> | ||||||
|  |             </div> | ||||||
|  |           )} | ||||||
|  |         </div> | ||||||
|  |       ), | ||||||
|  |     }, | ||||||
|  |   ]; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className="flex justify-center mt-5"> | ||||||
|  |       <Box className="w-full max-w-7xl"> | ||||||
|  |         <div className="bg-white p-4 rounded shadow-md"> | ||||||
|  |           <h1 className="text-2xl font-bold mb-4 text-white bg-gray-400 p-3"> | ||||||
|  |             API Registry | ||||||
|  |           </h1> | ||||||
|  |           <DataGrid | ||||||
|  |             rows={menuItems} | ||||||
|  |             columns={columns} | ||||||
|  |             components={{ | ||||||
|  |               Toolbar: () => ( | ||||||
|  |                 <CustomToolbar | ||||||
|  |                   apiRef={apiRef} | ||||||
|  |                   handleModal={() => setIsModalOpen(true)} | ||||||
|  |                 /> | ||||||
|  |               ), | ||||||
|  |             }} | ||||||
|  |             pageSize={10} | ||||||
|  |             onGridReady={(gridApi) => { | ||||||
|  |               apiRef.current = gridApi; | ||||||
|  |             }} | ||||||
|  |           /> | ||||||
|  |         </div> | ||||||
|  |       </Box> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default ApiRegistery; | ||||||
							
								
								
									
										64
									
								
								src/components/Dashboard/Codeextension.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/components/Dashboard/Codeextension.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | |||||||
|  | .modal-overlay { | ||||||
|  |     position: fixed; | ||||||
|  |     top: 0; | ||||||
|  |     left: 0; | ||||||
|  |     width: 100%; | ||||||
|  |     height: 100%; | ||||||
|  |     background-color: rgba(0, 0, 0, 0.5); | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: center; | ||||||
|  |     align-items: center; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   .modal { | ||||||
|  |     background-color: #fff; | ||||||
|  |     padding: 20px; | ||||||
|  |     border-radius: 8px; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   .modal-content { | ||||||
|  |     margin-top: 20px; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   .close { | ||||||
|  |     position: absolute; | ||||||
|  |     top: 10px; | ||||||
|  |     right: 10px; | ||||||
|  |     cursor: pointer; | ||||||
|  |     font-size: 20px; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   .close:hover { | ||||||
|  |     color: red; | ||||||
|  |   } | ||||||
|  |   .popup { | ||||||
|  |     position: fixed; | ||||||
|  |     top: 0; | ||||||
|  |     left: 0; | ||||||
|  |     width: 100%; | ||||||
|  |     height: 100%; | ||||||
|  |     background-color: rgba(0, 0, 0, 0.5); | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: center; | ||||||
|  |     align-items: center; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   .popup-content { | ||||||
|  |     background-color: #fff; | ||||||
|  |     padding: 20px; | ||||||
|  |     border-radius: 8px; | ||||||
|  |     width: 400px; /* Adjust width as needed */ | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   .close { | ||||||
|  |     position: absolute; | ||||||
|  |     top: 10px; | ||||||
|  |     right: 10px; | ||||||
|  |     cursor: pointer; | ||||||
|  |     font-size: 20px; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   .close:hover { | ||||||
|  |     color: red; | ||||||
|  |   } | ||||||
|  |    | ||||||
							
								
								
									
										302
									
								
								src/components/Dashboard/Codeextension.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										302
									
								
								src/components/Dashboard/Codeextension.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,302 @@ | |||||||
|  | import React, { useState, useEffect, useRef } from "react"; | ||||||
|  | import { | ||||||
|  |   Box, | ||||||
|  |   Button, | ||||||
|  |   Modal, | ||||||
|  |   TextField, | ||||||
|  |   Typography, | ||||||
|  |   FormControl, | ||||||
|  |   FormControlLabel, | ||||||
|  |   Checkbox, | ||||||
|  |   Radio, | ||||||
|  |   RadioGroup, | ||||||
|  |   Autocomplete, | ||||||
|  | } from "@mui/material"; | ||||||
|  | import { DataGrid, GridToolbarContainer } from "@mui/x-data-grid"; | ||||||
|  | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
|  | import { faEllipsisV } from "@fortawesome/free-solid-svg-icons"; | ||||||
|  | import AirplanemodeActiveIcon from "@mui/icons-material/AirplanemodeActive"; | ||||||
|  | import { Link } from "react-router-dom"; | ||||||
|  | import Extension from "./Extension"; | ||||||
|  | 
 | ||||||
|  | function CustomToolbar({ handleModal }) { | ||||||
|  |   return ( | ||||||
|  |     <GridToolbarContainer className="flex justify-between p-2 bg-gray-200"> | ||||||
|  |       <Button | ||||||
|  |         className="bg-blue-500 text-white px-4 py-2 rounded shadow hover:bg-blue-600" | ||||||
|  |         onClick={handleModal} | ||||||
|  |       > | ||||||
|  |         + | ||||||
|  |       </Button> | ||||||
|  |     </GridToolbarContainer> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function CodeExtension() { | ||||||
|  |   const [menuItems, setMenuItems] = useState([]); | ||||||
|  |   const [selectedMenuItem, setSelectedMenuItem] = useState(null); | ||||||
|  |   const [isModalOpen, setIsModalOpen] = useState(false); | ||||||
|  |   const [formData, setFormData] = useState({ | ||||||
|  |     name: "", | ||||||
|  |     email: "", | ||||||
|  |     testing: "", | ||||||
|  |     dataType: "", | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     const fetchData = async () => { | ||||||
|  |       const token = localStorage.getItem("token"); // Get token from local storage
 | ||||||
|  |       try { | ||||||
|  |         const response = await fetch(`${process.env.REACT_APP_API_BASE_URL}/api/extension`, { | ||||||
|  |           headers: { | ||||||
|  |             Authorization: `Bearer ${token}`, | ||||||
|  |           }, | ||||||
|  |         }); | ||||||
|  |         const data = await response.json(); | ||||||
|  |         setMenuItems(data); | ||||||
|  |       } catch (error) { | ||||||
|  |         console.error("Error fetching data:", error); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     fetchData(); | ||||||
|  |   }, []); | ||||||
|  | 
 | ||||||
|  |   const handleThreeDotsClick = (menuItemId) => { | ||||||
|  |     setSelectedMenuItem(menuItemId === selectedMenuItem ? null : menuItemId); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleModalOpen = () => { | ||||||
|  |     setIsModalOpen(true); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleModalClose = () => { | ||||||
|  |     setIsModalOpen(false); | ||||||
|  |     setFormData({ | ||||||
|  |       name: "", | ||||||
|  |       email: "", | ||||||
|  |       testing: "", | ||||||
|  |       dataType: "", | ||||||
|  |     }); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleChange = (e) => { | ||||||
|  |     const { name, value } = e.target; | ||||||
|  |     setFormData({ ...formData, [name]: value }); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleFormSubmit = (submittedDataType) => { | ||||||
|  |     setFormData({ ...formData, dataType: submittedDataType }); | ||||||
|  |     handleModalOpen(); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const columns = [ | ||||||
|  |     { field: "goto", headerName: "Goto", width: 200 }, | ||||||
|  |     { field: "field_name", headerName: "Field Name", width: 250 }, | ||||||
|  |     { field: "mapping", headerName: "Mapping", width: 200 }, | ||||||
|  |     { field: "data_type", headerName: "Data Type", width: 200 }, | ||||||
|  |     { | ||||||
|  |       field: "actions", | ||||||
|  |       headerName: "Actions", | ||||||
|  |       width: 150, | ||||||
|  |       renderCell: ({ row }) => ( | ||||||
|  |         <div className="relative"> | ||||||
|  |           <div | ||||||
|  |             className="cursor-pointer" | ||||||
|  |             onClick={() => handleThreeDotsClick(row.id)} | ||||||
|  |           > | ||||||
|  |             <FontAwesomeIcon icon={faEllipsisV} /> | ||||||
|  |           </div> | ||||||
|  |           {selectedMenuItem === row.id && ( | ||||||
|  |             <div className="absolute right-0 mt-2 py-2 w-48 bg-white rounded-lg shadow-xl"> | ||||||
|  |               {/* Implement your actions buttons here */} | ||||||
|  |             </div> | ||||||
|  |           )} | ||||||
|  |         </div> | ||||||
|  |       ), | ||||||
|  |     }, | ||||||
|  |   ]; | ||||||
|  | 
 | ||||||
|  |   const renderInputField = () => { | ||||||
|  |     switch (formData.dataType) { | ||||||
|  |       case "date": | ||||||
|  |         return ( | ||||||
|  |           <TextField | ||||||
|  |             label="Date" | ||||||
|  |             name="date" | ||||||
|  |             type="date" | ||||||
|  |             value={formData.date} | ||||||
|  |             onChange={handleChange} | ||||||
|  |             fullWidth | ||||||
|  |             className="mt-2" | ||||||
|  |           /> | ||||||
|  |         ); | ||||||
|  |       case "textfield": | ||||||
|  |         return ( | ||||||
|  |           <TextField | ||||||
|  |             label="Text Field" | ||||||
|  |             name="textfield" | ||||||
|  |             value={formData.textfield} | ||||||
|  |             onChange={handleChange} | ||||||
|  |             fullWidth | ||||||
|  |             className="mt-2" | ||||||
|  |           /> | ||||||
|  |         ); | ||||||
|  |       case "longtext": | ||||||
|  |         return ( | ||||||
|  |           <TextField | ||||||
|  |             label="Long Text" | ||||||
|  |             name="longtext" | ||||||
|  |             value={formData.longtext} | ||||||
|  |             onChange={handleChange} | ||||||
|  |             multiline | ||||||
|  |             rows={4} | ||||||
|  |             fullWidth | ||||||
|  |             className="mt-2" | ||||||
|  |           /> | ||||||
|  |         ); | ||||||
|  |       case "checkbox": | ||||||
|  |         return ( | ||||||
|  |           <FormControlLabel | ||||||
|  |             className="mt-2" | ||||||
|  |             control={ | ||||||
|  |               <Checkbox | ||||||
|  |                 checked={formData.checkbox || false} | ||||||
|  |                 onChange={(e) => | ||||||
|  |                   setFormData({ ...formData, checkbox: e.target.checked }) | ||||||
|  |                 } | ||||||
|  |               /> | ||||||
|  |             } | ||||||
|  |             label="Checkbox" | ||||||
|  |           /> | ||||||
|  |         ); | ||||||
|  |       case "radiobutton": | ||||||
|  |         return ( | ||||||
|  |           <FormControl component="fieldset" className="mt-2"> | ||||||
|  |             <RadioGroup | ||||||
|  |               name="radiobutton" | ||||||
|  |               value={formData.radiobutton || ""} | ||||||
|  |               onChange={(e) => | ||||||
|  |                 setFormData({ ...formData, radiobutton: e.target.value }) | ||||||
|  |               } | ||||||
|  |             > | ||||||
|  |               <FormControlLabel | ||||||
|  |                 value="option1" | ||||||
|  |                 control={<Radio />} | ||||||
|  |                 label="Option 1" | ||||||
|  |               /> | ||||||
|  |               <FormControlLabel | ||||||
|  |                 value="option2" | ||||||
|  |                 control={<Radio />} | ||||||
|  |                 label="Option 2" | ||||||
|  |               /> | ||||||
|  |             </RadioGroup> | ||||||
|  |           </FormControl> | ||||||
|  |         ); | ||||||
|  |       case "autocomplete": | ||||||
|  |         return ( | ||||||
|  |           <Autocomplete | ||||||
|  |             options={["Option 1", "Option 2", "Option 3"]} | ||||||
|  |             renderInput={(params) => ( | ||||||
|  |               <TextField {...params} label="Autocomplete" /> | ||||||
|  |             )} | ||||||
|  |             value={formData.autocomplete || ""} | ||||||
|  |             onChange={(e, newValue) => | ||||||
|  |               setFormData({ ...formData, autocomplete: newValue }) | ||||||
|  |             } | ||||||
|  |             fullWidth | ||||||
|  |             className="mt-2" | ||||||
|  |           /> | ||||||
|  |         ); | ||||||
|  |       default: | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <> | ||||||
|  |       <Box className="fixed top-0 left-0 w-full z-10 bg-white shadow"> | ||||||
|  |         {/* Your header content here */} | ||||||
|  |       </Box> | ||||||
|  |       <Box className="flex justify-center items-center min-h-screen bg-gray-100 py-4"> | ||||||
|  |         <Box className="w-full max-w-6xl bg-white p-4 rounded shadow-md"> | ||||||
|  |           <Typography | ||||||
|  |             variant="h4" | ||||||
|  |             className="text-center mb-4 text-3xl text-white bg-gray-400 p-3" | ||||||
|  |           > | ||||||
|  |             Token Registry | ||||||
|  |           </Typography> | ||||||
|  |           <div className="bg-gray-50 p-2 rounded shadow-inner"> | ||||||
|  |             <DataGrid | ||||||
|  |               rows={menuItems} | ||||||
|  |               columns={columns} | ||||||
|  |               pageSize={10} | ||||||
|  |               components={{ | ||||||
|  |                 Toolbar: () => <CustomToolbar handleModal={handleModalOpen} />, | ||||||
|  |               }} | ||||||
|  |               className="data-grid" | ||||||
|  |             /> | ||||||
|  |           </div> | ||||||
|  |           <Modal open={isModalOpen} onClose={handleModalClose} centered> | ||||||
|  |             <Box className="w-full max-w-lg bg-white p-4 rounded shadow-md fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"> | ||||||
|  |               <Extension onSubmit={handleFormSubmit} /> | ||||||
|  |               <Typography variant="h5" className="flex items-center mb-4"> | ||||||
|  |                 <Link to="/Extension"> | ||||||
|  |                   <AirplanemodeActiveIcon className="mr-2" /> | ||||||
|  |                 </Link> | ||||||
|  |                 Add Item | ||||||
|  |               </Typography> | ||||||
|  |               <form | ||||||
|  |                 onSubmit={(e) => { | ||||||
|  |                   e.preventDefault(); | ||||||
|  |                   handleFormSubmit(formData.dataType); | ||||||
|  |                 }} | ||||||
|  |               > | ||||||
|  |                 <div className="mb-2"> | ||||||
|  |                   <TextField | ||||||
|  |                     label="Name" | ||||||
|  |                     name="name" | ||||||
|  |                     value={formData.name} | ||||||
|  |                     onChange={handleChange} | ||||||
|  |                     fullWidth | ||||||
|  |                   /> | ||||||
|  |                 </div> | ||||||
|  |                 <div className="mb-2"> | ||||||
|  |                   <TextField | ||||||
|  |                     label="Email" | ||||||
|  |                     name="email" | ||||||
|  |                     value={formData.email} | ||||||
|  |                     onChange={handleChange} | ||||||
|  |                     fullWidth | ||||||
|  |                   /> | ||||||
|  |                 </div> | ||||||
|  |                 <div className="mb-2"> | ||||||
|  |                   <TextField | ||||||
|  |                     label="Testing" | ||||||
|  |                     name="testing" | ||||||
|  |                     value={formData.testing} | ||||||
|  |                     onChange={handleChange} | ||||||
|  |                     fullWidth | ||||||
|  |                   /> | ||||||
|  |                 </div> | ||||||
|  |                 {renderInputField()} | ||||||
|  |                 <div className="mt-4"> | ||||||
|  |                   <Button | ||||||
|  |                     type="submit" | ||||||
|  |                     variant="contained" | ||||||
|  |                     color="primary" | ||||||
|  |                     fullWidth | ||||||
|  |                   > | ||||||
|  |                     Submit | ||||||
|  |                   </Button> | ||||||
|  |                 </div> | ||||||
|  |               </form> | ||||||
|  |             </Box> | ||||||
|  |           </Modal> | ||||||
|  |         </Box> | ||||||
|  |       </Box> | ||||||
|  |     </> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default CodeExtension; | ||||||
							
								
								
									
										0
									
								
								src/components/Dashboard/DashboardBuilder.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/components/Dashboard/DashboardBuilder.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										161
									
								
								src/components/Dashboard/Dynamictable.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								src/components/Dashboard/Dynamictable.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,161 @@ | |||||||
|  | import React, { useState, useEffect } from "react"; | ||||||
|  | import axios from "axios"; | ||||||
|  | import { useLocation, useNavigate } from "react-router-dom"; | ||||||
|  | import { | ||||||
|  |   Button, | ||||||
|  |   IconButton, | ||||||
|  |   Table, | ||||||
|  |   TableBody, | ||||||
|  |   TableCell, | ||||||
|  |   TableContainer, | ||||||
|  |   TableHead, | ||||||
|  |   TableRow, | ||||||
|  |   Paper, | ||||||
|  |   Typography, | ||||||
|  |   Box, | ||||||
|  | } from "@mui/material"; | ||||||
|  | import DeleteIcon from "@mui/icons-material/Delete"; | ||||||
|  | import BuildIcon from "@mui/icons-material/Build"; | ||||||
|  | import AddIcon from "@mui/icons-material/Add"; | ||||||
|  | 
 | ||||||
|  | // Define the API base URL using the environment variable
 | ||||||
|  | const api = process.env.REACT_APP_API_BASE_URL; | ||||||
|  | 
 | ||||||
|  | const DynamicTable = () => { | ||||||
|  |   const [forms, setForms] = useState([]); | ||||||
|  |   const location = useLocation(); | ||||||
|  |   const navigate = useNavigate(); | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     if (location.state && location.state.formData) { | ||||||
|  |       setForms((prevForms) => [...prevForms, location.state.formData]); | ||||||
|  |     } else { | ||||||
|  |       fetchForms(); | ||||||
|  |     } | ||||||
|  |   }, [location.state]); | ||||||
|  | 
 | ||||||
|  |   const fetchForms = async () => { | ||||||
|  |     const token = localStorage.getItem("token"); // Get token from local storage
 | ||||||
|  |     try { | ||||||
|  |       const response = await axios.get(`${api}/api/form_setup`, { | ||||||
|  |         headers: { | ||||||
|  |           Authorization: `Bearer ${token}`, | ||||||
|  |         }, | ||||||
|  |       }); | ||||||
|  |       if (Array.isArray(response.data)) { | ||||||
|  |         setForms(response.data); | ||||||
|  |       } else { | ||||||
|  |         console.error("Unexpected response format:", response.data); | ||||||
|  |         setForms([]); | ||||||
|  |       } | ||||||
|  |     } catch (error) { | ||||||
|  |       console.error("Error fetching data:", error); | ||||||
|  |       setForms([]); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleDelete = async (id) => { | ||||||
|  |     const token = localStorage.getItem("token"); // Get token from local storage
 | ||||||
|  |     try { | ||||||
|  |       await axios.delete(`${api}/api/form_setup/${id}`, { | ||||||
|  |         headers: { | ||||||
|  |           Authorization: `Bearer ${token}`, | ||||||
|  |         }, | ||||||
|  |       }); | ||||||
|  |       fetchForms(); | ||||||
|  |     } catch (error) { | ||||||
|  |       console.error("Error deleting form:", error); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleBuild = async (id) => { | ||||||
|  |     const token = localStorage.getItem("token"); // Get token from local storage
 | ||||||
|  |     try { | ||||||
|  |       await axios.post( | ||||||
|  |         `${api}/api/dynamic_form_build`, | ||||||
|  |         { id }, | ||||||
|  |         { | ||||||
|  |           headers: { | ||||||
|  |             Authorization: `Bearer ${token}`, | ||||||
|  |           }, | ||||||
|  |         } | ||||||
|  |       ); | ||||||
|  |     } catch (error) { | ||||||
|  |       console.error("Error building form:", error); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleAdd = () => { | ||||||
|  |     navigate("/form"); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <Box className="p-5 bg-gray-100 min-h-screen"> | ||||||
|  |       <Typography | ||||||
|  |         variant="h4" | ||||||
|  |         gutterBottom | ||||||
|  |         className="text-center text-white bg-gray-700 text-3xl p-3 mb-5 rounded" | ||||||
|  |       > | ||||||
|  |         Dynamic Form | ||||||
|  |       </Typography> | ||||||
|  |       <Button | ||||||
|  |         variant="contained" | ||||||
|  |         color="primary" | ||||||
|  |         startIcon={<AddIcon />} | ||||||
|  |         onClick={handleAdd} | ||||||
|  |         className="mb-5 bg-blue-500 hover:bg-blue-600" | ||||||
|  |       > | ||||||
|  |         Add | ||||||
|  |       </Button> | ||||||
|  |       <TableContainer component={Paper} className="overflow-x-auto"> | ||||||
|  |         <Table> | ||||||
|  |           <TableHead className="bg-gray-300 text-black"> | ||||||
|  |             <TableRow> | ||||||
|  |               <TableCell>Go To</TableCell> | ||||||
|  |               <TableCell>Form Name</TableCell> | ||||||
|  |               <TableCell>Form Description</TableCell> | ||||||
|  |               <TableCell>Related To</TableCell> | ||||||
|  |               <TableCell>Page Event</TableCell> | ||||||
|  |               <TableCell>Button Caption</TableCell> | ||||||
|  |               <TableCell>Go To Form</TableCell> | ||||||
|  |               <TableCell>Action</TableCell> | ||||||
|  |             </TableRow> | ||||||
|  |           </TableHead> | ||||||
|  |           <TableBody> | ||||||
|  |             {forms.map((form, index) => ( | ||||||
|  |               <TableRow key={index}> | ||||||
|  |                 <TableCell> | ||||||
|  |                   <Button | ||||||
|  |                     variant="outlined" | ||||||
|  |                     startIcon={<BuildIcon />} | ||||||
|  |                     onClick={() => handleBuild(form.id)} | ||||||
|  |                     className="border-blue-500 text-blue-500 hover:bg-blue-100" | ||||||
|  |                   > | ||||||
|  |                     Build | ||||||
|  |                   </Button> | ||||||
|  |                 </TableCell> | ||||||
|  |                 <TableCell>{form.formName}</TableCell> | ||||||
|  |                 <TableCell>{form.formDescription}</TableCell> | ||||||
|  |                 <TableCell>{form.relatedTo}</TableCell> | ||||||
|  |                 <TableCell>{form.pageEvent}</TableCell> | ||||||
|  |                 <TableCell>{form.buttonCaption}</TableCell> | ||||||
|  |                 <TableCell>{form.goToForm}</TableCell> | ||||||
|  |                 <TableCell> | ||||||
|  |                   <IconButton | ||||||
|  |                     color="secondary" | ||||||
|  |                     onClick={() => handleDelete(form.id)} | ||||||
|  |                     className="text-red-500 hover:text-red-700" | ||||||
|  |                   > | ||||||
|  |                     <DeleteIcon /> | ||||||
|  |                   </IconButton> | ||||||
|  |                 </TableCell> | ||||||
|  |               </TableRow> | ||||||
|  |             ))} | ||||||
|  |           </TableBody> | ||||||
|  |         </Table> | ||||||
|  |       </TableContainer> | ||||||
|  |     </Box> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default DynamicTable; | ||||||
							
								
								
									
										93
									
								
								src/components/Dashboard/Extension.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								src/components/Dashboard/Extension.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,93 @@ | |||||||
|  | import React, { useState } from 'react'; | ||||||
|  | import { TextField, Button, Typography, Select, MenuItem } from '@mui/material'; | ||||||
|  | import { useNavigate } from 'react-router-dom'; | ||||||
|  | 
 | ||||||
|  | const Extension = ({ onSubmit }) => { | ||||||
|  |   const [formData, setFormData] = useState({ | ||||||
|  |     type: '', | ||||||
|  |     fieldName: '', | ||||||
|  |     mapping: '', | ||||||
|  |     dataType: '' | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   const navigate = useNavigate(); | ||||||
|  | 
 | ||||||
|  |   const handleChange = (e) => { | ||||||
|  |     const { name, value } = e.target; | ||||||
|  |     setFormData({ ...formData, [name]: value }); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleSubmit = (e) => { | ||||||
|  |     e.preventDefault(); | ||||||
|  |     if (typeof onSubmit === 'function') { | ||||||
|  |       onSubmit(formData.dataType); | ||||||
|  |     } | ||||||
|  |     // Navigate to CodeExtension page with the form data
 | ||||||
|  |     navigate('/Codeextension', { state: { formData } }); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div style={{ maxWidth: '600px', margin: '0 auto' }}> | ||||||
|  |       <Typography variant="h4" gutterBottom>Add Item</Typography> | ||||||
|  |       <form onSubmit={handleSubmit}> | ||||||
|  |         <div> | ||||||
|  |           <Select | ||||||
|  |             label="Type" | ||||||
|  |             name="type" | ||||||
|  |             value={formData.type} | ||||||
|  |             onChange={handleChange} | ||||||
|  |             fullWidth | ||||||
|  |             required | ||||||
|  |           > | ||||||
|  |             <MenuItem value="Header">Header</MenuItem> | ||||||
|  |             <MenuItem value="Line">Line</MenuItem> | ||||||
|  |           </Select> | ||||||
|  |         </div> | ||||||
|  |         <div> | ||||||
|  |           <TextField | ||||||
|  |             label="Field Name" | ||||||
|  |             name="fieldName" | ||||||
|  |             value={formData.fieldName} | ||||||
|  |             onChange={handleChange} | ||||||
|  |             fullWidth | ||||||
|  |             required | ||||||
|  |           /> | ||||||
|  |         </div> | ||||||
|  |         <div> | ||||||
|  |           <Select | ||||||
|  |             label="Mapping" | ||||||
|  |             name="mapping" | ||||||
|  |             value={formData.mapping} | ||||||
|  |             onChange={handleChange} | ||||||
|  |             fullWidth | ||||||
|  |             required | ||||||
|  |           > | ||||||
|  |             {[...Array(15).keys()].map(num => ( | ||||||
|  |               <MenuItem key={num + 1} value={`EXTN${num + 1}`}>{`EXTN${num + 1}`}</MenuItem> | ||||||
|  |             ))} | ||||||
|  |           </Select> | ||||||
|  |         </div> | ||||||
|  |         <div> | ||||||
|  |           <Select | ||||||
|  |             label="Data Type" | ||||||
|  |             name="dataType" | ||||||
|  |             value={formData.dataType} | ||||||
|  |             onChange={handleChange} | ||||||
|  |             fullWidth | ||||||
|  |             required | ||||||
|  |           > | ||||||
|  |             <MenuItem value="textfield">Textfield</MenuItem> | ||||||
|  |             <MenuItem value="longtext">Longtext</MenuItem> | ||||||
|  |             <MenuItem value="date">Date</MenuItem> | ||||||
|  |             <MenuItem value="checkbox">Checkbox</MenuItem> | ||||||
|  |             <MenuItem value="radiobutton">Radiobutton</MenuItem> | ||||||
|  |             <MenuItem value="autocomplete">Autocomplete</MenuItem> | ||||||
|  |           </Select> | ||||||
|  |         </div> | ||||||
|  |         <Button type="submit" variant="contained" sx={{ mt: 2 }}>Submit</Button> | ||||||
|  |       </form> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default Extension; | ||||||
							
								
								
									
										217
									
								
								src/components/Dashboard/Form.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								src/components/Dashboard/Form.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,217 @@ | |||||||
|  | import React, { useState } from "react"; | ||||||
|  | import { useNavigate } from "react-router-dom"; | ||||||
|  | import { v4 as uuidv4 } from "uuid"; | ||||||
|  | 
 | ||||||
|  | function DynamicForm() { | ||||||
|  |   const [components, setComponents] = useState([ | ||||||
|  |     { | ||||||
|  |       id: uuidv4(), | ||||||
|  |       label: "", | ||||||
|  |       type: "", | ||||||
|  |       mapping: "", | ||||||
|  |       readonly: false, | ||||||
|  |       values: "", | ||||||
|  |     }, | ||||||
|  |   ]); | ||||||
|  |   const [formDetails, setFormDetails] = useState({ | ||||||
|  |     formName: "", | ||||||
|  |     formDescription: "", | ||||||
|  |     relatedTo: "", | ||||||
|  |     pageEvent: "", | ||||||
|  |     buttonName: "", | ||||||
|  |   }); | ||||||
|  |   const navigate = useNavigate(); | ||||||
|  | 
 | ||||||
|  |   const handleFormChange = (e) => { | ||||||
|  |     const { name, value } = e.target; | ||||||
|  |     setFormDetails({ ...formDetails, [name]: value }); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleComponentChange = (index, field, value) => { | ||||||
|  |     const updatedComponents = components.map((component, i) => | ||||||
|  |       i === index ? { ...component, [field]: value } : component | ||||||
|  |     ); | ||||||
|  |     setComponents(updatedComponents); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const addComponent = () => { | ||||||
|  |     setComponents([ | ||||||
|  |       ...components, | ||||||
|  |       { | ||||||
|  |         id: uuidv4(), | ||||||
|  |         label: "", | ||||||
|  |         type: "", | ||||||
|  |         mapping: "", | ||||||
|  |         readonly: false, | ||||||
|  |         values: "", | ||||||
|  |       }, | ||||||
|  |     ]); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const removeComponent = (index) => { | ||||||
|  |     setComponents(components.filter((_, i) => i !== index)); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleSubmit = (e) => { | ||||||
|  |     e.preventDefault(); | ||||||
|  |     const formData = { ...formDetails, components }; | ||||||
|  |     navigate("/Dynamictable", { state: { formData } }); // Navigate to DynamicTable with formData
 | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className="p-5 min-h-screen"> | ||||||
|  |       <h1 className="text-3xl font-bold text-center text-white bg-gray-400 mb-8 p-3"> | ||||||
|  |         Dynamic Form Setup | ||||||
|  |       </h1> | ||||||
|  |       <form onSubmit={handleSubmit} className="space-y-6"> | ||||||
|  |         <div className="grid grid-cols-1 md:grid-cols-3 gap-6"> | ||||||
|  |           <div className="flex flex-col"> | ||||||
|  |             <label className="text-gray-700">Form Name</label> | ||||||
|  |             <input | ||||||
|  |               type="text" | ||||||
|  |               name="formName" | ||||||
|  |               value={formDetails.formName} | ||||||
|  |               onChange={handleFormChange} | ||||||
|  |               className="mt-1 p-2 border rounded" | ||||||
|  |             /> | ||||||
|  |           </div> | ||||||
|  |           <div className="flex flex-col"> | ||||||
|  |             <label className="text-gray-700">Form Description</label> | ||||||
|  |             <input | ||||||
|  |               type="text" | ||||||
|  |               name="formDescription" | ||||||
|  |               value={formDetails.formDescription} | ||||||
|  |               onChange={handleFormChange} | ||||||
|  |               className="mt-1 p-2 border rounded" | ||||||
|  |             /> | ||||||
|  |           </div> | ||||||
|  |           <div className="flex flex-col"> | ||||||
|  |             <label className="text-gray-700">Related To</label> | ||||||
|  |             <select | ||||||
|  |               name="relatedTo" | ||||||
|  |               value={formDetails.relatedTo} | ||||||
|  |               onChange={handleFormChange} | ||||||
|  |               className="mt-1 p-2 border rounded" | ||||||
|  |             > | ||||||
|  |               <option value=""> | ||||||
|  |                 <em>None</em> | ||||||
|  |               </option> | ||||||
|  |               <option value="Menu">Menu</option> | ||||||
|  |               <option value="Related to">Related to</option> | ||||||
|  |             </select> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |         <div className="grid grid-cols-1 md:grid-cols-2 gap-6"> | ||||||
|  |           <div className="flex flex-col"> | ||||||
|  |             <label className="text-gray-700">Page Event</label> | ||||||
|  |             <select | ||||||
|  |               name="pageEvent" | ||||||
|  |               value={formDetails.pageEvent} | ||||||
|  |               onChange={handleFormChange} | ||||||
|  |               className="mt-1 p-2 border rounded" | ||||||
|  |             > | ||||||
|  |               <option value="Onclick">Onclick</option> | ||||||
|  |               <option value="Onblur">Onblur</option> | ||||||
|  |             </select> | ||||||
|  |           </div> | ||||||
|  |           <div className="flex flex-col"> | ||||||
|  |             <label className="text-gray-700">Button Name</label> | ||||||
|  |             <input | ||||||
|  |               type="text" | ||||||
|  |               name="buttonName" | ||||||
|  |               value={formDetails.buttonName} | ||||||
|  |               onChange={handleFormChange} | ||||||
|  |               className="mt-1 p-2 border rounded" | ||||||
|  |             /> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |         <h2 className="text-2xl font-semibold text-gray-700 mt-8"> | ||||||
|  |           Component Details | ||||||
|  |         </h2> | ||||||
|  |         {components.map((component, index) => ( | ||||||
|  |           <div | ||||||
|  |             key={component.id} | ||||||
|  |             className="grid grid-cols-1 md:grid-cols-5 gap-4 items-center mt-4" | ||||||
|  |           > | ||||||
|  |             <input | ||||||
|  |               type="text" | ||||||
|  |               placeholder="Label" | ||||||
|  |               value={component.label} | ||||||
|  |               onChange={(e) => | ||||||
|  |                 handleComponentChange(index, "label", e.target.value) | ||||||
|  |               } | ||||||
|  |               className="p-2 border rounded col-span-1" | ||||||
|  |             /> | ||||||
|  |             <select | ||||||
|  |               value={component.type} | ||||||
|  |               onChange={(e) => | ||||||
|  |                 handleComponentChange(index, "type", e.target.value) | ||||||
|  |               } | ||||||
|  |               className="p-2 border rounded col-span-1" | ||||||
|  |             > | ||||||
|  |               <option value=""> | ||||||
|  |                 <em>None</em> | ||||||
|  |               </option> | ||||||
|  |               <option value="textfield">TextField</option> | ||||||
|  |               <option value="checkbox">Checkbox</option> | ||||||
|  |               <option value="select">Select</option> | ||||||
|  |             </select> | ||||||
|  |             <input | ||||||
|  |               type="text" | ||||||
|  |               placeholder="Mapping" | ||||||
|  |               value={component.mapping} | ||||||
|  |               onChange={(e) => | ||||||
|  |                 handleComponentChange(index, "mapping", e.target.value) | ||||||
|  |               } | ||||||
|  |               className="p-2 border rounded col-span-1" | ||||||
|  |             /> | ||||||
|  |             <div className="flex items-center"> | ||||||
|  |               <input | ||||||
|  |                 type="checkbox" | ||||||
|  |                 checked={component.readonly} | ||||||
|  |                 onChange={(e) => | ||||||
|  |                   handleComponentChange(index, "readonly", e.target.checked) | ||||||
|  |                 } | ||||||
|  |                 className="mr-2" | ||||||
|  |               /> | ||||||
|  |               <label>Readonly</label> | ||||||
|  |             </div> | ||||||
|  |             <input | ||||||
|  |               type="text" | ||||||
|  |               placeholder="Enter Values" | ||||||
|  |               value={component.values} | ||||||
|  |               onChange={(e) => | ||||||
|  |                 handleComponentChange(index, "values", e.target.value) | ||||||
|  |               } | ||||||
|  |               className="p-2 border rounded col-span-1" | ||||||
|  |             /> | ||||||
|  |             <button | ||||||
|  |               type="button" | ||||||
|  |               onClick={() => removeComponent(index)} | ||||||
|  |               className="text-red-500 hover:text-red-700" | ||||||
|  |             > | ||||||
|  |               {/* <DeleteIcon /> */} | ||||||
|  |             </button> | ||||||
|  |           </div> | ||||||
|  |         ))} | ||||||
|  |         <div className="flex justify-between mt-6"> | ||||||
|  |           <button | ||||||
|  |             type="button" | ||||||
|  |             onClick={addComponent} | ||||||
|  |             className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600" | ||||||
|  |           > | ||||||
|  |             Add Component | ||||||
|  |           </button> | ||||||
|  |           <button | ||||||
|  |             type="submit" | ||||||
|  |             className="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600" | ||||||
|  |           > | ||||||
|  |             Submit | ||||||
|  |           </button> | ||||||
|  |         </div> | ||||||
|  |       </form> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default DynamicForm; | ||||||
							
								
								
									
										50
									
								
								src/components/Dashboard/HomePage.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/components/Dashboard/HomePage.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | |||||||
|  | /* HomePage.css */ | ||||||
|  | 
 | ||||||
|  | .container { | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  |   justify-content: center; | ||||||
|  |   align-items: center; | ||||||
|  |   height: 100vh; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .heading { | ||||||
|  |   font-size: 24px; | ||||||
|  |   margin-bottom: 20px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .card-container { | ||||||
|  |   display: flex; | ||||||
|  |   justify-content: center; | ||||||
|  |   align-items: center; | ||||||
|  |   flex-wrap: wrap; /* Allow cards to wrap to the next line */ | ||||||
|  |   margin-top: 20px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .card { | ||||||
|  |   background-color: #9ee2f5; | ||||||
|  |   padding: 40px; | ||||||
|  |   border-radius: 8px; | ||||||
|  |   box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); | ||||||
|  |   width: 30%; /* Adjust card width for larger screens */ | ||||||
|  |   margin: 10px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .chart-container { | ||||||
|  |   display: flex; | ||||||
|  |   justify-content: center; | ||||||
|  |   align-items: center; | ||||||
|  |   margin-top: 20px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @media (max-width: 768px) { | ||||||
|  |   .card { | ||||||
|  |     width: 45%; /* Adjust card width for screens up to 768px */ | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @media (max-width: 480px) { | ||||||
|  |   .card { | ||||||
|  |     width: 100%; /* Make cards occupy full width on screens up to 480px */ | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										37
									
								
								src/components/Dashboard/HomePage.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/components/Dashboard/HomePage.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | // HomePage.js
 | ||||||
|  | 
 | ||||||
|  | import React from 'react'; | ||||||
|  | import { BarChart } from '@mui/x-charts/BarChart'; // Import BarChart component
 | ||||||
|  | 
 | ||||||
|  | const Card = ({ index }) => { | ||||||
|  |   return ( | ||||||
|  |     <div className="bg-white border border-gray-300 rounded-lg shadow-md p-6 m-4 cursor-pointer transition-transform transform hover:scale-105 hover:shadow-lg flex flex-col items-center justify-center text-center"> | ||||||
|  |       <h3 className="text-lg font-semibold mb-2">INDEX {index}</h3> | ||||||
|  |       <p className="text-gray-600">{index}.</p> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const HomePage = () => { | ||||||
|  |   return ( | ||||||
|  |     <div className="min-h-screen flex flex-col items-center justify-center bg-gray-100 p-4"> | ||||||
|  |       <h2 className="text-3xl font-semibold text-gray-700 mb-6">Welcome to the Dashboard!</h2> | ||||||
|  |       <div className="flex flex-wrap justify-center"> | ||||||
|  |         <Card index={1} /> | ||||||
|  |         <Card index={2} /> | ||||||
|  |         <Card index={3} /> | ||||||
|  |       </div> | ||||||
|  |       <div className="w-full mt-8 flex justify-center"> | ||||||
|  |         {/* Add BarChart component */} | ||||||
|  |         <BarChart | ||||||
|  |           xAxis={[{ scaleType: 'band', data: ['group A', 'group B', 'group C'] }]} | ||||||
|  |           series={[{ data: [4, 3, 5] }, { data: [1, 6, 3] }, { data: [2, 5, 6] }]} | ||||||
|  |           width={700} | ||||||
|  |           height={400} | ||||||
|  |         /> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default HomePage; | ||||||
| @ -0,0 +1,7 @@ | |||||||
|  | @import url('https://fonts.googleapis.com/css2?family=EB+Garamond:ital,wght@0,400..800;1,400..800&family=PT+Serif:ital,wght@0,400;0,700;1,400;1,700&family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap'); | ||||||
|  | .custom-header, .custom-cell { | ||||||
|  |   font-family: 'PT Serif", serif ';  | ||||||
|  |    | ||||||
|  |   font-style: normal; | ||||||
|  |   font-weight: bold; | ||||||
|  | } | ||||||
							
								
								
									
										162
									
								
								src/components/Dashboard/MenuAccessControl/MenuAccessControl.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								src/components/Dashboard/MenuAccessControl/MenuAccessControl.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,162 @@ | |||||||
|  | import React, { useState, useEffect, useRef } from 'react'; | ||||||
|  | import { Box, Button } from '@mui/material'; | ||||||
|  | import { DataGrid, GridToolbarContainer } from '@mui/x-data-grid'; | ||||||
|  | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; | ||||||
|  | import { faEllipsisV } from '@fortawesome/free-solid-svg-icons'; | ||||||
|  | 
 | ||||||
|  | function CustomToolbar({ apiRef, handleThreeDotsClick, handleModal }) { | ||||||
|  |   const handleGoToPage1 = () => { | ||||||
|  |     if (apiRef.current) { | ||||||
|  |       apiRef.current.setPage(1); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <GridToolbarContainer> | ||||||
|  |       <Button onClick={handleGoToPage1}>Go to page 1</Button> | ||||||
|  |       <Button onClick={handleModal}>+</Button>  | ||||||
|  |     </GridToolbarContainer> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function MenuAccessControl() { | ||||||
|  |   const [menuItems, setMenuItems] = useState([]); | ||||||
|  |   const [selectedMenuItem, setSelectedMenuItem] = useState(null); | ||||||
|  |   const [isModalOpen, setIsModalOpen] = useState(false); | ||||||
|  |   const [isUpdateModalOpen, setIsUpdateModalOpen] = useState(false); | ||||||
|  |   const [newMenuItem, setNewMenuItem] = useState({ | ||||||
|  |     // Define initial values for the new menu item in the modal
 | ||||||
|  |     No: '', | ||||||
|  |     menuItemname: '', | ||||||
|  |     view: '', | ||||||
|  |     create: '', | ||||||
|  |     edit: '', | ||||||
|  |     delete: '', | ||||||
|  |     query: '', | ||||||
|  |     export: [], | ||||||
|  |   }); | ||||||
|  |   const apiRef = useRef(null); | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     const fetchData = async () => { | ||||||
|  |       try { | ||||||
|  |         const response = await fetch(''); | ||||||
|  |         const data = await response.json(); | ||||||
|  |          | ||||||
|  |         // Set unique IDs for each menu item
 | ||||||
|  |         const menuItemsWithIds = data.map((menuItem, index) => ({ ...menuItem, id: index + 1 })); | ||||||
|  |         setMenuItems(menuItemsWithIds); | ||||||
|  |       } catch (error) { | ||||||
|  |         console.error('Error fetching data:', error); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     fetchData(); | ||||||
|  |   }, []); | ||||||
|  | 
 | ||||||
|  |   const handleThreeDotsClick = (menuItemId) => { | ||||||
|  |     setSelectedMenuItem(menuItemId === selectedMenuItem ? null : menuItemId); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleDelete = (menuItemId) => { | ||||||
|  |     // Implement delete logic here
 | ||||||
|  |     console.log('Delete menu item with ID:', menuItemId); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleUpdate = (menuItem) => { | ||||||
|  |     // Implement update logic here
 | ||||||
|  |     console.log('Update menu item:', menuItem); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleModal = () => { | ||||||
|  |     setIsModalOpen(true); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleModalSave = () => { | ||||||
|  |     // Implement save logic for adding a new menu item here
 | ||||||
|  |     setIsModalOpen(false); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleUpdateSave = () => { | ||||||
|  |     // Implement save logic for updating a menu item here
 | ||||||
|  |     setIsUpdateModalOpen(false); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const columns = [ | ||||||
|  |     { field: 'No', headerName: 'No', width: 100,headerClassName: 'custom-header', cellClassName: 'custom-cell' }, | ||||||
|  |     { field: 'menuItemname', headerName: 'Menu Item Name', width: 200,headerClassName: 'custom-header', cellClassName: 'custom-cell' }, | ||||||
|  |     { field: 'view', headerName: 'View', width: 100,headerClassName: 'custom-header', cellClassName: 'custom-cell' }, | ||||||
|  |     { field: 'create', headerName: 'Create', width: 100,headerClassName: 'custom-header', cellClassName: 'custom-cell' }, | ||||||
|  |     { field: 'edit', headerName: 'Edit', width: 100 ,headerClassName: 'custom-header', cellClassName: 'custom-cell'}, | ||||||
|  |     { field: 'delete', headerName: 'Delete', width: 100 ,headerClassName: 'custom-header', cellClassName: 'custom-cell'}, | ||||||
|  |     { field: 'query', headerName: 'Query', width: 100 ,headerClassName: 'custom-header', cellClassName: 'custom-cell'}, | ||||||
|  |     { field: 'export', headerName: 'Export', width: 100 ,headerClassName: 'custom-header', cellClassName: 'custom-cell'}, | ||||||
|  |     { | ||||||
|  |       field: 'actions', | ||||||
|  |       headerName: 'Actions', | ||||||
|  |       width: 100, | ||||||
|  |       renderCell: ({ row }) => ( | ||||||
|  |         <div> | ||||||
|  |           <div className="three-dots" onClick={() => handleThreeDotsClick(row.menuItemId)}> | ||||||
|  |             <FontAwesomeIcon icon={faEllipsisV} /> | ||||||
|  |           </div> | ||||||
|  |           {selectedMenuItem === row.menuItemId && ( | ||||||
|  |             <div className="popover"> | ||||||
|  |               <button onClick={() => handleDelete(row.menuItemId)}>Delete</button> | ||||||
|  |               <button onClick={() => handleUpdate(row)}>Update</button> | ||||||
|  |             </div> | ||||||
|  |           )} | ||||||
|  |         </div> | ||||||
|  |       ), | ||||||
|  |     }, | ||||||
|  |   ]; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className="flex flex-col items-center justify-center min-h-screen bg-gray-100 p-4"> | ||||||
|  |       <div className="w-full mb-3 md:w-3/4 lg:w-2/3 xl:w-1/2"> | ||||||
|  |         <div className='text-center text-3xl text-white bg-gray-400 p-2 rounded-lg'>Menu Access Control</div> | ||||||
|  |       </div> | ||||||
|  |       <Box className="w-full p-4 md:w-3/4 lg:w-2/3 xl:w-1/2 bg-white border border-gray-200 shadow-lg rounded-lg" sx={{ height: 500, width: '100%' }} > | ||||||
|  |         <DataGrid | ||||||
|  |           rows={menuItems} | ||||||
|  |           columns={columns} | ||||||
|  |           components={{ | ||||||
|  |             Toolbar: () => ( | ||||||
|  |               <CustomToolbar | ||||||
|  |                 apiRef={apiRef} | ||||||
|  |                 handleThreeDotsClick={handleThreeDotsClick} | ||||||
|  |                 handleModal={handleModal} | ||||||
|  |               /> | ||||||
|  |             ), | ||||||
|  |           }} | ||||||
|  |           pageSize={10} | ||||||
|  |           onGridReady={(gridApi) => { | ||||||
|  |             apiRef.current = gridApi; | ||||||
|  |           }} | ||||||
|  |           className="bg-gray-400" | ||||||
|  |         /> | ||||||
|  |       </Box> | ||||||
|  |       {/* Your modals and other components */} | ||||||
|  |       {isModalOpen && ( | ||||||
|  |         <div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 p-4"> | ||||||
|  |           <div className="bg-white p-8 rounded-lg shadow-lg max-w-lg w-full"> | ||||||
|  |             <h2 className="text-xl font-bold mb-4">Add New Menu Item</h2> | ||||||
|  |             {/* Modal content here */} | ||||||
|  |             <Button onClick={() => setIsModalOpen(false)}>Close</Button> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       )} | ||||||
|  |       {isUpdateModalOpen && ( | ||||||
|  |         <div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 p-4"> | ||||||
|  |           <div className="bg-white p-8 rounded-lg shadow-lg max-w-lg w-full"> | ||||||
|  |             <h2 className="text-xl font-bold mb-4">Update Menu Item</h2> | ||||||
|  |             {/* Modal content here */} | ||||||
|  |             <Button onClick={() => setIsUpdateModalOpen(false)}>Close</Button> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       )} | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default MenuAccessControl; | ||||||
							
								
								
									
										7
									
								
								src/components/Dashboard/MenuMaintance/MenuMaintance.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/components/Dashboard/MenuMaintance/MenuMaintance.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | @import url('https://fonts.googleapis.com/css2?family=EB+Garamond:ital,wght@0,400..800;1,400..800&family=PT+Serif:ital,wght@0,400;0,700;1,400;1,700&family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap'); | ||||||
|  | .custom-header, .custom-cell { | ||||||
|  |   font-family: 'PT Serif", serif ';  | ||||||
|  |    | ||||||
|  |   font-style: normal; | ||||||
|  |   font-weight: bold; | ||||||
|  | } | ||||||
							
								
								
									
										180
									
								
								src/components/Dashboard/MenuMaintance/MenuMaintance.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								src/components/Dashboard/MenuMaintance/MenuMaintance.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,180 @@ | |||||||
|  | import React, { useState, useEffect, useRef } from "react"; | ||||||
|  | import { Box, Button } from "@mui/material"; | ||||||
|  | import { DataGrid, GridToolbarContainer } from "@mui/x-data-grid"; | ||||||
|  | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
|  | import { faEllipsisV } from "@fortawesome/free-solid-svg-icons"; | ||||||
|  | import "./MenuMaintance.css"; | ||||||
|  | 
 | ||||||
|  | const api = process.env.REACT_APP_API_BASE_URL; | ||||||
|  | 
 | ||||||
|  | function CustomToolbar({ apiRef, handleThreeDotsClick, handleModal }) { | ||||||
|  |   const handleGoToPage1 = () => { | ||||||
|  |     if (apiRef.current) { | ||||||
|  |       apiRef.current.setPage(1); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <GridToolbarContainer> | ||||||
|  |       <Button onClick={handleGoToPage1}>Go to page 1</Button> | ||||||
|  |       <Button onClick={handleModal}>+</Button> | ||||||
|  |     </GridToolbarContainer> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function MenuMaintenance() { | ||||||
|  |   const [menuItems, setMenuItems] = useState([]); | ||||||
|  |   const [selectedMenuItem, setSelectedMenuItem] = useState(null); | ||||||
|  |   const [isModalOpen, setIsModalOpen] = useState(false); | ||||||
|  |   const apiRef = useRef(null); | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     const fetchData = async () => { | ||||||
|  |       const token = localStorage.getItem("token"); | ||||||
|  |       try { | ||||||
|  |         const response = await fetch(`${api}/api1/submenu1`, { | ||||||
|  |           headers: { | ||||||
|  |             Authorization: `Bearer ${token}`, | ||||||
|  |           }, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         if (!response.ok) { | ||||||
|  |           throw new Error(`HTTP error! status: ${response.status}`); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const data = await response.json(); | ||||||
|  |         // Flatten the nested subMenus array
 | ||||||
|  |         const flattenedData = data.flatMap((menuItem) => [ | ||||||
|  |           menuItem, | ||||||
|  |           ...menuItem.subMenus, | ||||||
|  |         ]); | ||||||
|  |         // Set unique IDs for each menu item
 | ||||||
|  |         const menuItemsWithIds = flattenedData.map((menuItem, index) => ({ | ||||||
|  |           ...menuItem, | ||||||
|  |           id: index + 1, | ||||||
|  |         })); | ||||||
|  |         setMenuItems(menuItemsWithIds); | ||||||
|  |       } catch (error) { | ||||||
|  |         console.error("Error fetching data:", error); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     fetchData(); | ||||||
|  |   }, []); | ||||||
|  | 
 | ||||||
|  |   const handleThreeDotsClick = (menuItemId) => { | ||||||
|  |     setSelectedMenuItem(menuItemId === selectedMenuItem ? null : menuItemId); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const columns = [ | ||||||
|  |     { | ||||||
|  |       field: "menuItemId", | ||||||
|  |       headerName: "Menu Item ID", | ||||||
|  |       width: 200, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "menuItemDesc", | ||||||
|  |       headerName: "Menu Item Description", | ||||||
|  |       width: 250, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "moduleName", | ||||||
|  |       headerName: "Module Name", | ||||||
|  |       width: 200, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "main_menu_action_name", | ||||||
|  |       headerName: "Main Menu Action", | ||||||
|  |       width: 200, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "main_menu_icon_name", | ||||||
|  |       headerName: "Main Menu Icon", | ||||||
|  |       width: 200, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "actions", | ||||||
|  |       headerName: "Actions", | ||||||
|  |       width: 150, | ||||||
|  |       renderCell: ({ row }) => ( | ||||||
|  |         <div className="relative"> | ||||||
|  |           <div | ||||||
|  |             className="three-dots" | ||||||
|  |             onClick={() => handleThreeDotsClick(row.menuItemId)} | ||||||
|  |           > | ||||||
|  |             <FontAwesomeIcon | ||||||
|  |               icon={faEllipsisV} | ||||||
|  |               className="cursor-pointer text-gray-800 hover:text-gray-600" | ||||||
|  |             /> | ||||||
|  |           </div> | ||||||
|  |           {selectedMenuItem === row.menuItemId && ( | ||||||
|  |             <div className="absolute bg-white border border-gray-200 shadow-lg p-4 mt-2 rounded-lg"> | ||||||
|  |               {/* Implement your actions buttons here */} | ||||||
|  |             </div> | ||||||
|  |           )} | ||||||
|  |         </div> | ||||||
|  |       ), | ||||||
|  |     }, | ||||||
|  |   ]; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className="flex flex-col items-center justify-center min-h-screen bg-gray-100"> | ||||||
|  |       <div className="text-3xl text-center text-black mb-3 bg-slate-400"> | ||||||
|  |         Menu Maintenance | ||||||
|  |       </div> | ||||||
|  |       <Box | ||||||
|  |         className="w-full p-4 md:w-3/4 lg:w-2/3 xl:w-1/2" | ||||||
|  |         sx={{ height: 500, width: "100%" }} | ||||||
|  |       > | ||||||
|  |         <DataGrid | ||||||
|  |           rows={menuItems} | ||||||
|  |           columns={columns} | ||||||
|  |           components={{ | ||||||
|  |             Toolbar: () => ( | ||||||
|  |               <CustomToolbar | ||||||
|  |                 apiRef={apiRef} | ||||||
|  |                 handleThreeDotsClick={handleThreeDotsClick} | ||||||
|  |                 handleModal={() => setIsModalOpen(true)} | ||||||
|  |               /> | ||||||
|  |             ), | ||||||
|  |           }} | ||||||
|  |           pageSize={10} | ||||||
|  |           onGridReady={(gridApi) => { | ||||||
|  |             apiRef.current = gridApi; | ||||||
|  |           }} | ||||||
|  |           sx={{ | ||||||
|  |             "& .MuiDataGrid-columnHeaders": { | ||||||
|  |               backgroundColor: "rgba(107, 114, 128, 0.5)", // Tailwind CSS bg-gray-400 with opacity
 | ||||||
|  |             }, | ||||||
|  |             "& .MuiDataGrid-columnHeaderTitle": { | ||||||
|  |               fontWeight: "bold", | ||||||
|  |             }, | ||||||
|  |           }} | ||||||
|  |           className=" border border-gray-200 shadow-lg rounded-lg bg-gray-400" | ||||||
|  |         /> | ||||||
|  |       </Box> | ||||||
|  |       {/* Your modals and other components */} | ||||||
|  |       {isModalOpen && ( | ||||||
|  |         <div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50"> | ||||||
|  |           <div className="bg-white p-8 rounded-lg shadow-lg"> | ||||||
|  |             <h2 className="text-xl font-bold mb-4">Modal Title</h2> | ||||||
|  |             {/* Modal content here */} | ||||||
|  |             <Button onClick={() => setIsModalOpen(false)}>Close</Button> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       )} | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default MenuMaintenance; | ||||||
							
								
								
									
										101
									
								
								src/components/Dashboard/Modal.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								src/components/Dashboard/Modal.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,101 @@ | |||||||
|  | import React, { useState } from 'react'; | ||||||
|  | import './Model.css'; | ||||||
|  | 
 | ||||||
|  | const Modal = ({ setNewUser, newUser, onSave }) => { | ||||||
|  |   const [newUserState, setNewUserState] = useState(newUser); | ||||||
|  |   const [isModalOpen, setIsModalOpen] = useState(false); | ||||||
|  | 
 | ||||||
|  |   const handleSave = () => { | ||||||
|  |     const data = {  ...newUserState }; | ||||||
|  |     onSave(data); // Pass the new data to the parent component
 | ||||||
|  |     setIsModalOpen(false); // Close the modal after saving
 | ||||||
|  |   }; | ||||||
|  |    | ||||||
|  | 
 | ||||||
|  |   const handleClose = () => { | ||||||
|  |     setIsModalOpen(false); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleOpenModal = () => { | ||||||
|  |     setIsModalOpen(true); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <> | ||||||
|  |       <button onClick={handleOpenModal}>ADD ITEM</button> | ||||||
|  | 
 | ||||||
|  |       {isModalOpen && ( | ||||||
|  |         <div className='modalWrapper'> | ||||||
|  |           <div className='modal'> | ||||||
|  |             <button className="closeBtn" onClick={handleClose}>X</button> | ||||||
|  | 
 | ||||||
|  |             <div className="input-group"> | ||||||
|  |               <label htmlFor="userId">User ID:</label> | ||||||
|  |               <input | ||||||
|  |                 type="text" | ||||||
|  |                 id="userId" | ||||||
|  |                 value={newUserState.userId} | ||||||
|  |                 onChange={(e) => setNewUserState({ ...newUserState, userId: e.target.value })} | ||||||
|  |               /> | ||||||
|  |             </div> | ||||||
|  | 
 | ||||||
|  |             <div className="input-group"> | ||||||
|  |               <label htmlFor="username">Username:</label> | ||||||
|  |               <input | ||||||
|  |                 type="text" | ||||||
|  |                 id="username" | ||||||
|  |                 value={newUserState.username} | ||||||
|  |                 onChange={(e) => setNewUserState({ ...newUserState, username: e.target.value })} | ||||||
|  |               /> | ||||||
|  |             </div> | ||||||
|  |             <div className="input-group"> | ||||||
|  |               <label htmlFor="fullName">Full Name:</label> | ||||||
|  |               <input | ||||||
|  |                 type="text" | ||||||
|  |                 id="fullName" | ||||||
|  |                 value={newUserState.fullName} | ||||||
|  |                 onChange={(e) => setNewUserState({ ...newUserState, fullName: e.target.value })} | ||||||
|  |               /> | ||||||
|  |             </div> | ||||||
|  | 
 | ||||||
|  |             <div className="input-group"> | ||||||
|  |               <label htmlFor="email">Email:</label> | ||||||
|  |               <input | ||||||
|  |                 type="text" | ||||||
|  |                 id="email" | ||||||
|  |                 value={newUserState.email} | ||||||
|  |                 onChange={(e) => setNewUserState({ ...newUserState, email: e.target.value })} | ||||||
|  |               /> | ||||||
|  |             </div> | ||||||
|  | 
 | ||||||
|  |              | ||||||
|  | 
 | ||||||
|  |             <div className="input-group"> | ||||||
|  |               <label htmlFor="mobileNumber">Mobile Number:</label> | ||||||
|  |               <input | ||||||
|  |                 type="text" | ||||||
|  |                 id="mobileNumber" | ||||||
|  |                 value={newUserState.mobileNumber} | ||||||
|  |                 onChange={(e) => setNewUserState({ ...newUserState, mobileNumber: e.target.value })} | ||||||
|  |               /> | ||||||
|  |             </div> | ||||||
|  | 
 | ||||||
|  |             <div className="input-group"> | ||||||
|  |               <label htmlFor="userGroup">User Group:</label> | ||||||
|  |               <input | ||||||
|  |                 type="text" | ||||||
|  |                 id="userGroup" | ||||||
|  |                 value={newUserState.userGroup} | ||||||
|  |                 onChange={(e) => setNewUserState({ ...newUserState, userGroup: e.target.value })} | ||||||
|  |               /> | ||||||
|  |             </div> | ||||||
|  | 
 | ||||||
|  |             <button onClick={handleSave}>Save</button> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       )} | ||||||
|  |     </> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default Modal; | ||||||
							
								
								
									
										69
									
								
								src/components/Dashboard/Model.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/components/Dashboard/Model.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,69 @@ | |||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | .modalWrapper { | ||||||
|  |     position: fixed; | ||||||
|  |     top: 0; | ||||||
|  |     left: 0; | ||||||
|  |     width: 100%; | ||||||
|  |     height: 100%; | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: center; | ||||||
|  |     align-items: center; | ||||||
|  |     background: rgba(0, 0, 0, 0.5); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   .modal { | ||||||
|  |     background: white; | ||||||
|  |     padding: 20px; | ||||||
|  |     border-radius: 8px; | ||||||
|  |     width: 300px; | ||||||
|  |     text-align: left; | ||||||
|  |     position: relative; | ||||||
|  |     box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   .closeBtn { | ||||||
|  |     position: absolute; | ||||||
|  |     top: 10px; | ||||||
|  |     right: 10px; | ||||||
|  |     font-size: 16px; | ||||||
|  |     cursor: pointer; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   label { | ||||||
|  |     display: block; | ||||||
|  |     margin-bottom: 8px; | ||||||
|  |     color: #333; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   input { | ||||||
|  |     width: 100%; | ||||||
|  |     padding: 10px; | ||||||
|  |     margin-bottom: 16px; | ||||||
|  |     border: 1px solid #ddd; | ||||||
|  |     border-radius: 4px; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   button { | ||||||
|  |     background-color: #4caf50; | ||||||
|  |     color: white; | ||||||
|  |     padding: 12px; | ||||||
|  |     border: none; | ||||||
|  |     border-radius: 4px; | ||||||
|  |     cursor: pointer; | ||||||
|  |      | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   .savedData { | ||||||
|  |     margin-top: 20px; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   .savedData h2 { | ||||||
|  |     font-size: 16px; | ||||||
|  |     margin-bottom: 10px; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   .savedData p { | ||||||
|  |     margin: 5px 0; | ||||||
|  |   } | ||||||
|  |    | ||||||
							
								
								
									
										71
									
								
								src/components/Dashboard/Report.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/components/Dashboard/Report.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | |||||||
|  | /* Report.css */ | ||||||
|  | 
 | ||||||
|  | .app { | ||||||
|  |   font-family: Arial, sans-serif; | ||||||
|  |   margin: 20px auto; /* Adjust margin to create space between cards and navbar */ | ||||||
|  |   padding: 0 20px; | ||||||
|  |   max-width: 800px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | h1 { | ||||||
|  |   text-align: center; | ||||||
|  |   color: #333; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .card-container { | ||||||
|  |   display: grid; | ||||||
|  |   grid-template-columns: minmax(350px, 1fr) minmax(350px, 1fr) minmax(350px, 1fr) repeat(auto-fill, minmax(250px, 1fr)); /* Ensure first three cards are in the same row and increase their width */ | ||||||
|  |   gap: 20px; | ||||||
|  |   max-width: 100%; /* Limit the maximum width of the card container */ | ||||||
|  |   margin: 0 auto; /* Center the card container */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .card { | ||||||
|  |   background-color: #ffffff; | ||||||
|  |   border: 1px solid #e0e0e0; | ||||||
|  |   border-radius: 10px; | ||||||
|  |   padding: 30px; /* Increase padding for better spacing */ | ||||||
|  |   box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* Adjust box shadow for a more pronounced effect */ | ||||||
|  |   transition: transform 0.3s ease-in-out; | ||||||
|  |   width: 100%; /* Make cards take up full width of their container */ | ||||||
|  |   height: auto; /* Allow cards to expand vertically based on content */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .card:hover { | ||||||
|  |   transform: translateY(-5px); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .card h2 { | ||||||
|  |   margin-top: 0; | ||||||
|  |   color: #333; | ||||||
|  |   font-size: 20px; /* Increase font size of card headings */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .card p { | ||||||
|  |   margin: 10px 0; /* Increase margin for better spacing */ | ||||||
|  |   color: #666; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @media (max-width: 1400px) { | ||||||
|  |   .card-container { | ||||||
|  |     grid-template-columns: minmax(300px, 1fr) minmax(300px, 1fr) repeat(auto-fill, minmax(250px, 1fr)); /* Adjust columns for smaller screens */ | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @media (max-width: 1100px) { | ||||||
|  |   .card-container { | ||||||
|  |     grid-template-columns: minmax(250px, 1fr) repeat(auto-fill, minmax(200px, 1fr)); /* Further adjust columns for even smaller screens */ | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @media (max-width: 900px) { | ||||||
|  |   .card-container { | ||||||
|  |     grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); /* Adjust columns for smaller screens */ | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @media (max-width: 600px) { | ||||||
|  |   .card-container { | ||||||
|  |     grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); /* Adjust columns for smaller screens */ | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										74
									
								
								src/components/Dashboard/Report.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/components/Dashboard/Report.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,74 @@ | |||||||
|  | import React, { useState, useEffect } from "react"; | ||||||
|  | 
 | ||||||
|  | const Card = ({ report }) => { | ||||||
|  |   return ( | ||||||
|  |     <div className="bg-white border border-gray-300 rounded-lg shadow-md p-6 m-4 cursor-pointer transition-transform transform hover:scale-105 hover:shadow-lg flex flex-col items-center justify-center text-center"> | ||||||
|  |       <h2 className="text-lg font-semibold mb-2">{report.reportName}</h2> | ||||||
|  |       <p className="text-gray-600 mb-2">{report.description}</p> | ||||||
|  |       <p className="text-gray-600 mb-2"> | ||||||
|  |         Active: {report.active ? "Yes" : "No"} | ||||||
|  |       </p> | ||||||
|  |       <p className="text-gray-600">Is SQL: {report.isSql ? "Yes" : "No"}</p> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // Define the API base URL using the environment variable
 | ||||||
|  | const api = process.env.REACT_APP_API_BASE_URL; | ||||||
|  | 
 | ||||||
|  | const Report = () => { | ||||||
|  |   const [reports, setReports] = useState([]); | ||||||
|  |   const [loading, setLoading] = useState(true); | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     const fetchData = async () => { | ||||||
|  |       const token = localStorage.getItem("authToken"); | ||||||
|  | 
 | ||||||
|  |       if (!token) { | ||||||
|  |         console.error("No auth token found. Redirecting to login."); | ||||||
|  |         // You can redirect to the login page here if needed
 | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       try { | ||||||
|  |         const response = await fetch(`${api}/Rpt_builder2/Rpt_builder2`, { | ||||||
|  |           headers: { | ||||||
|  |             Authorization: `Bearer ${token}`, | ||||||
|  |           }, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         if (!response.ok) { | ||||||
|  |           throw new Error("Failed to fetch data"); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const data = await response.json(); | ||||||
|  |         setReports(data); | ||||||
|  |         setLoading(false); | ||||||
|  |       } catch (error) { | ||||||
|  |         console.error("Error fetching data:", error); | ||||||
|  |         setLoading(false); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     fetchData(); | ||||||
|  |   }, []); | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className="min-h-screen bg-gray-100 p-4 flex flex-col items-center"> | ||||||
|  |       <div className="mb-6"> | ||||||
|  |         <h1 className="text-3xl font-semibold text-gray-700">Reports</h1> | ||||||
|  |       </div> | ||||||
|  |       {loading ? ( | ||||||
|  |         <p className="text-gray-700">Loading...</p> | ||||||
|  |       ) : ( | ||||||
|  |         <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6"> | ||||||
|  |           {reports.map((report) => ( | ||||||
|  |             <Card key={report.id} report={report} /> | ||||||
|  |           ))} | ||||||
|  |         </div> | ||||||
|  |       )} | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default Report; | ||||||
							
								
								
									
										29
									
								
								src/components/Dashboard/Setup.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/components/Dashboard/Setup.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | .card-list { | ||||||
|  |     display: flex; | ||||||
|  |     flex-wrap: wrap; /* Allow cards to wrap to the next line */ | ||||||
|  |     justify-content: center; /* Horizontally center the cards */ | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   .card { | ||||||
|  |     border: 1px solid black; | ||||||
|  |     padding: 10px; | ||||||
|  |     margin: 10px; /* Adjust margin for better spacing */ | ||||||
|  |     width: calc(33.33% - 20px); /* Adjust card width based on container width */ | ||||||
|  |     max-width: 200px; /* Set maximum card width */ | ||||||
|  |     height: 150px; /* Adjust card height */ | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   @media (max-width: 768px) { | ||||||
|  |     .card { | ||||||
|  |       width: calc(50% - 20px); /* Two cards per row on smaller screens */ | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   @media (max-width: 480px) { | ||||||
|  |     .card { | ||||||
|  |       width: calc(100% - 20px); /* Single card per row on mobile devices */ | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |    | ||||||
							
								
								
									
										80
									
								
								src/components/Dashboard/Setup.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/components/Dashboard/Setup.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,80 @@ | |||||||
|  | import React, { useState } from 'react'; | ||||||
|  | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; | ||||||
|  | import { faUser, faUsers, faUtensils, faLock, faCogs, faKey } from '@fortawesome/free-solid-svg-icons'; | ||||||
|  | import UserMaintance from './UserMaintance';  | ||||||
|  | import UserGroupMaintance from './UserGroupMaintance/UserGroupMaintance';  | ||||||
|  | import MenuMaintance from './MenuMaintance/MenuMaintance';  | ||||||
|  | import MenuAccessControl from './MenuAccessControl/MenuAccessControl';  | ||||||
|  | import SystemParameters from './SystemParameters/SystemParameters';  | ||||||
|  | import AccessType from './AccessType/AccessType'; | ||||||
|  | import ApiRegistery from './ApiRegistery/ApiRegistery'; | ||||||
|  | import TokenRegistery from './TokenRegistery/TokenRegistery'; | ||||||
|  | import Codeextension from './Codeextension.js'; | ||||||
|  | import DynamicTable from './Dynamictable.js'; | ||||||
|  | 
 | ||||||
|  | const Card = ({ title, content, icon, onClick }) => ( | ||||||
|  |   <div onClick={onClick} className="bg-white border border-gray-300 rounded-lg shadow-md p-6 m-4 cursor-pointer transition-transform transform hover:scale-105 hover:shadow-lg flex flex-col items-center justify-center text-center"> | ||||||
|  |     <FontAwesomeIcon icon={icon} className="text-4xl text-gray-800 mb-4" /> | ||||||
|  |     <h3 className="text-lg font-semibold">{title}</h3> | ||||||
|  |     <p className="text-gray-600">{content}</p> | ||||||
|  |   </div> | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | const CardList = () => { | ||||||
|  |   const [showUserMaintance, setShowUserMaintance] = useState(false); | ||||||
|  |   const [showUserGroupMaintance, setShowUserGroupMaintance] = useState(false); | ||||||
|  |   const [showMenuMaintance, setShowMenuMaintance] = useState(false); | ||||||
|  |   const [showMenuAccessControl, setShowMenuAccessControl] = useState(false); | ||||||
|  |   const [showSystemParameters, setShowSystemParameters] = useState(false); | ||||||
|  |   const [showAccessType, setShowAccessType] = useState(false); | ||||||
|  |   const [showApiRegistery, setShowApiRegistery] = useState(false); | ||||||
|  |   const [showTokenRegistery, setShowTokenRegistery] = useState(false); | ||||||
|  |   const [showCodeExtension, setShowCodeExtension] = useState(false); | ||||||
|  |   const [showDynamicTable, setShowDynamicTable] = useState(false); | ||||||
|  | 
 | ||||||
|  |   const handleCardClick = (menuItemDesc) => { | ||||||
|  |     setShowUserMaintance(menuItemDesc === 'User Maintance'); | ||||||
|  |     setShowUserGroupMaintance(menuItemDesc === 'User Group Maintance'); | ||||||
|  |     setShowMenuMaintance(menuItemDesc === 'Menu Maintance'); | ||||||
|  |     setShowMenuAccessControl(menuItemDesc === 'Menu Access Control'); | ||||||
|  |     setShowSystemParameters(menuItemDesc === 'System Parameters'); | ||||||
|  |     setShowAccessType(menuItemDesc === 'Access Type'); | ||||||
|  |     setShowApiRegistery(menuItemDesc === 'Api Registery'); | ||||||
|  |     setShowTokenRegistery(menuItemDesc === 'Token Registery'); | ||||||
|  |     setShowCodeExtension(menuItemDesc === 'Code Extension'); | ||||||
|  |     setShowDynamicTable(menuItemDesc === 'Dynamic Table'); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <> | ||||||
|  |       {!showUserMaintance && !showUserGroupMaintance && !showMenuMaintance && !showMenuAccessControl && !showSystemParameters && !showAccessType && !showApiRegistery && !showTokenRegistery && !showCodeExtension && !showDynamicTable && ( | ||||||
|  |         <div className="min-h-screen flex items-center justify-center bg-gray-100 p-4"> | ||||||
|  |           <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-3 xl:grid-cols-4 gap-6"> | ||||||
|  |             <Card title="User Maintance" content="Manage users" icon={faUser} onClick={() => handleCardClick('User Maintance')} /> | ||||||
|  |             <Card title="User Group Maintance" content="Manage user groups" icon={faUsers} onClick={() => handleCardClick('User Group Maintance')} /> | ||||||
|  |             <Card title="Menu Maintance" content="Manage menus" icon={faUtensils} onClick={() => handleCardClick('Menu Maintance')} /> | ||||||
|  |             <Card title="Menu Access Control" content="Control menu access" icon={faLock} onClick={() => handleCardClick('Menu Access Control')} /> | ||||||
|  |             <Card title="System Parameters" content="Configure system parameters" icon={faCogs} onClick={() => handleCardClick('System Parameters')} /> | ||||||
|  |             <Card title="Access Type" content="Manage access types" icon={faKey} onClick={() => handleCardClick('Access Type')} /> | ||||||
|  |             <Card title="Api Registery" content="Manage APIs" icon={faUser} onClick={() => handleCardClick('Api Registery')} /> | ||||||
|  |             <Card title="Token Registery" content="Manage tokens" icon={faKey} onClick={() => handleCardClick('Token Registery')} /> | ||||||
|  |             <Card title="Code Extension" content="Extend code functionalities" icon={faLock} onClick={() => handleCardClick('Code Extension')} /> | ||||||
|  |             <Card title="Dynamic Table" content="Dynamic data tables" icon={faKey} onClick={() => handleCardClick('Dynamic Table')} /> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       )} | ||||||
|  |       {showUserMaintance && <UserMaintance />} | ||||||
|  |       {showUserGroupMaintance && <UserGroupMaintance />} | ||||||
|  |       {showMenuMaintance && <MenuMaintance />} | ||||||
|  |       {showMenuAccessControl && <MenuAccessControl />} | ||||||
|  |       {showSystemParameters && <SystemParameters />} | ||||||
|  |       {showAccessType && <AccessType />} | ||||||
|  |       {showApiRegistery && <ApiRegistery />} | ||||||
|  |       {showTokenRegistery && <TokenRegistery />} | ||||||
|  |       {showCodeExtension && <Codeextension />} | ||||||
|  |       {showDynamicTable && <DynamicTable />} | ||||||
|  |     </> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default CardList; | ||||||
							
								
								
									
										128
									
								
								src/components/Dashboard/SystemParameters/SystemParameters.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								src/components/Dashboard/SystemParameters/SystemParameters.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,128 @@ | |||||||
|  | import React, { useState } from "react"; | ||||||
|  | import { Button, Container, Grid, TextField } from "@mui/material"; | ||||||
|  | 
 | ||||||
|  | const SystemParameterForm = () => { | ||||||
|  |   const [formData, setFormData] = useState({ | ||||||
|  |     schedulerTimer: "", | ||||||
|  |     leaseTaxCode: "", | ||||||
|  |     vesselConfirmationProcessLimit: "", | ||||||
|  |     rowToDisplay: "", | ||||||
|  |     linkToDisplay: "", | ||||||
|  |     rowToAdd: "", | ||||||
|  |     lovRowToDisplay: "", | ||||||
|  |     lovLinkToDisplay: "", | ||||||
|  |     oldServerName: "", | ||||||
|  |     oldBase: "", | ||||||
|  |     oldAdminUser: "", | ||||||
|  |     oldServerPort: "", | ||||||
|  |     userDefaultGroup: "", | ||||||
|  |     defaultDepartment: "", | ||||||
|  |     defaultPosition: "", | ||||||
|  |     singleCharge: "", | ||||||
|  |     firstDayOfWeek: "", | ||||||
|  |     hourPerShift: "", | ||||||
|  |     cnBillingFrequency: "", | ||||||
|  |     billingDepartmentCode: "", | ||||||
|  |     basePriceList: "", | ||||||
|  |     nonContainerServiceOrderAutoApprovalDeptCode: "", | ||||||
|  |     ediMAESchedulerOnOff: "", | ||||||
|  |     ediSchedulerOnOff: "", | ||||||
|  |     companyDisplayName: "", | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   const handleInputChange = (event) => { | ||||||
|  |     const { name, value } = event.target; | ||||||
|  |     setFormData((prevState) => ({ | ||||||
|  |       ...prevState, | ||||||
|  |       [name]: value, | ||||||
|  |     })); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleFileChange = (event) => { | ||||||
|  |     setFormData((prevState) => ({ | ||||||
|  |       ...prevState, | ||||||
|  |       logo: event.target.files[0], | ||||||
|  |     })); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleSubmit = (event) => { | ||||||
|  |     event.preventDefault(); | ||||||
|  |     alert("Form submitted successfully!"); | ||||||
|  |     console.log("Form Data:", formData); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleClear = () => { | ||||||
|  |     setFormData({ | ||||||
|  |       schedulerTimer: "", | ||||||
|  |       leaseTaxCode: "", | ||||||
|  |       vesselConfirmationProcessLimit: "", | ||||||
|  |       rowToDisplay: "", | ||||||
|  |       linkToDisplay: "", | ||||||
|  |       rowToAdd: "", | ||||||
|  |       lovRowToDisplay: "", | ||||||
|  |       lovLinkToDisplay: "", | ||||||
|  |       oldServerName: "", | ||||||
|  |       oldBase: "", | ||||||
|  |       oldAdminUser: "", | ||||||
|  |       oldServerPort: "", | ||||||
|  |       userDefaultGroup: "", | ||||||
|  |       defaultDepartment: "", | ||||||
|  |       defaultPosition: "", | ||||||
|  |       singleCharge: "", | ||||||
|  |       firstDayOfWeek: "", | ||||||
|  |       hourPerShift: "", | ||||||
|  |       cnBillingFrequency: "", | ||||||
|  |       billingDepartmentCode: "", | ||||||
|  |       basePriceList: "", | ||||||
|  |       nonContainerServiceOrderAutoApprovalDeptCode: "", | ||||||
|  |       ediMAESchedulerOnOff: "", | ||||||
|  |       ediSchedulerOnOff: "", | ||||||
|  |       companyDisplayName: "", | ||||||
|  |     }); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <Container className="mt-5"> | ||||||
|  |       <p className="bg-gray-400 text-center text-white text-3xl m-3 p-2"> | ||||||
|  |         System Parameters | ||||||
|  |       </p> | ||||||
|  |       <form onSubmit={handleSubmit} className="m-5 p-5"> | ||||||
|  |         <Grid container spacing={3}> | ||||||
|  |           {Object.keys(formData).map((key, index) => ( | ||||||
|  |             <Grid item xs={12} sm={6} key={index}> | ||||||
|  |               <TextField | ||||||
|  |                 fullWidth | ||||||
|  |                 label={key | ||||||
|  |                   .split(/(?=[A-Z])/) | ||||||
|  |                   .join(" ") | ||||||
|  |                   .replace(/\b\w/g, (l) => l.toUpperCase())} | ||||||
|  |                 name={key} | ||||||
|  |                 value={formData[key]} | ||||||
|  |                 onChange={handleInputChange} | ||||||
|  |                 variant="outlined" | ||||||
|  |               /> | ||||||
|  |             </Grid> | ||||||
|  |           ))} | ||||||
|  |           <Grid item xs={12}> | ||||||
|  |             <input type="file" onChange={handleFileChange} /> | ||||||
|  |           </Grid> | ||||||
|  |         </Grid> | ||||||
|  |         <div style={{ textAlign: "end", marginTop: 20 }}> | ||||||
|  |           <Button | ||||||
|  |             variant="contained" | ||||||
|  |             color="primary" | ||||||
|  |             type="submit" | ||||||
|  |             style={{ marginRight: 10 }} | ||||||
|  |           > | ||||||
|  |             Save | ||||||
|  |           </Button> | ||||||
|  |           <Button variant="outlined" color="primary" onClick={handleClear}> | ||||||
|  |             Clear | ||||||
|  |           </Button> | ||||||
|  |         </div> | ||||||
|  |       </form> | ||||||
|  |     </Container> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default SystemParameterForm; | ||||||
							
								
								
									
										427
									
								
								src/components/Dashboard/Test/Apitest.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										427
									
								
								src/components/Dashboard/Test/Apitest.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,427 @@ | |||||||
|  | import React, { useEffect, useState } from "react"; | ||||||
|  | import axios from "axios"; | ||||||
|  | import { | ||||||
|  |   Button, | ||||||
|  |   Dialog, | ||||||
|  |   DialogActions, | ||||||
|  |   DialogContent, | ||||||
|  |   DialogTitle, | ||||||
|  |   Snackbar, | ||||||
|  |   Alert, | ||||||
|  |   Typography, | ||||||
|  |   TextField, | ||||||
|  |   Table, | ||||||
|  |   TableBody, | ||||||
|  |   TableCell, | ||||||
|  |   TableContainer, | ||||||
|  |   TableHead, | ||||||
|  |   TableRow, | ||||||
|  |   TablePagination, | ||||||
|  |   Paper, | ||||||
|  |   IconButton, | ||||||
|  |   InputAdornment | ||||||
|  | } from "@mui/material"; | ||||||
|  | import { makeStyles } from '@mui/styles'; | ||||||
|  | import SearchIcon from '@mui/icons-material/Search'; | ||||||
|  | 
 | ||||||
|  | const API_URL = "http://34.198.218.30:30179/entityBuilder/Gaurav_testing"; | ||||||
|  | const token = localStorage.getItem("authToken"); | ||||||
|  | // Custom styles using makeStyles
 | ||||||
|  | const useStyles = makeStyles((theme) => ({ | ||||||
|  |   tableHeader: { | ||||||
|  |     backgroundColor: "#000000", | ||||||
|  |     color: "#ffffff", | ||||||
|  |   }, | ||||||
|  |   searchContainer: { | ||||||
|  |     display: 'flex', | ||||||
|  |     alignItems: 'center', | ||||||
|  |     marginBottom: theme.spacing(2), | ||||||
|  |   }, | ||||||
|  |   searchInput: { | ||||||
|  |     marginRight: theme.spacing(2), | ||||||
|  |     flex: 1, | ||||||
|  |   }, | ||||||
|  |   tableContainer: { | ||||||
|  |     marginTop: theme.spacing(2), | ||||||
|  |   }, | ||||||
|  |   dialogContent: { | ||||||
|  |     display: 'flex', | ||||||
|  |     flexDirection: 'column', | ||||||
|  |     gap: theme.spacing(2), | ||||||
|  |   }, | ||||||
|  |   formControl: { | ||||||
|  |     marginBottom: theme.spacing(2), | ||||||
|  |   }, | ||||||
|  |   button: { | ||||||
|  |     margin: theme.spacing(1), | ||||||
|  |   }, | ||||||
|  | })); | ||||||
|  | 
 | ||||||
|  | const EntityTable = () => { | ||||||
|  |   const classes = useStyles(); | ||||||
|  |   const [data, setData] = useState([]); | ||||||
|  |   const [filteredData, setFilteredData] = useState([]); | ||||||
|  |   const [newEntity, setNewEntity] = useState({ | ||||||
|  |     name: "", | ||||||
|  |     email: "", | ||||||
|  |     mobno: "", | ||||||
|  |     address: "", | ||||||
|  |     pincode: "", | ||||||
|  |   }); | ||||||
|  |   const [editEntity, setEditEntity] = useState(null); | ||||||
|  |   const [showEditModal, setShowEditModal] = useState(false); | ||||||
|  |   const [showAddModal, setShowAddModal] = useState(false); | ||||||
|  |   const [showDeleteModal, setShowDeleteModal] = useState(false); | ||||||
|  |   const [deleteEntityId, setDeleteEntityId] = useState(null); | ||||||
|  |   const [currentPage, setCurrentPage] = useState(0); | ||||||
|  |   const [itemsPerPage] = useState(5); // Adjust this value as needed
 | ||||||
|  |   const [searchQuery, setSearchQuery] = useState(""); | ||||||
|  |   const [openSnackbar, setOpenSnackbar] = useState(false); | ||||||
|  |   const [snackbarMessage, setSnackbarMessage] = useState(""); | ||||||
|  |   const [snackbarSeverity, setSnackbarSeverity] = useState("success"); | ||||||
|  | 
 | ||||||
|  |   const handlePageChange = (event, newPage) => { | ||||||
|  |     setCurrentPage(newPage); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     fetchData(); | ||||||
|  |   }, []); | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     handleSearch(); | ||||||
|  |   }, [searchQuery, data]); | ||||||
|  | 
 | ||||||
|  |   const fetchData = async () => { | ||||||
|  |     try { | ||||||
|  |       const response = await axios.get(API_URL, { | ||||||
|  |         headers: { Authorization: `Bearer ${token}` }, | ||||||
|  |       }); | ||||||
|  |       setData(response.data); | ||||||
|  |     } catch (error) { | ||||||
|  |       console.error("Error fetching data:", error); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleDelete = async () => { | ||||||
|  |     try { | ||||||
|  |       await axios.delete(`${API_URL}/${deleteEntityId}`, { | ||||||
|  |         headers: { Authorization: `Bearer ${token}` }, | ||||||
|  |       }); | ||||||
|  |       fetchData(); | ||||||
|  |       setSnackbarMessage("Successfully deleted!"); | ||||||
|  |       setSnackbarSeverity("success"); | ||||||
|  |       setOpenSnackbar(true); | ||||||
|  |       setShowDeleteModal(false); | ||||||
|  |     } catch (error) { | ||||||
|  |       console.error("Error deleting data:", error); | ||||||
|  |       setSnackbarMessage("Failed to delete!"); | ||||||
|  |       setSnackbarSeverity("error"); | ||||||
|  |       setOpenSnackbar(true); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleAdd = async () => { | ||||||
|  |     try { | ||||||
|  |       await axios.post(API_URL, newEntity, { | ||||||
|  |         headers: { Authorization: `Bearer ${token}` }, | ||||||
|  |       }); | ||||||
|  |       fetchData(); | ||||||
|  |       setNewEntity({ | ||||||
|  |         name: "", | ||||||
|  |         email: "", | ||||||
|  |         mobno: "", | ||||||
|  |         address: "", | ||||||
|  |         pincode: "", | ||||||
|  |       }); | ||||||
|  |       setShowAddModal(false); | ||||||
|  |       setSnackbarMessage("Successfully added!"); | ||||||
|  |       setSnackbarSeverity("success"); | ||||||
|  |       setOpenSnackbar(true); | ||||||
|  |     } catch (error) { | ||||||
|  |       console.error("Error adding data:", error); | ||||||
|  |       setSnackbarMessage("Failed to add!"); | ||||||
|  |       setSnackbarSeverity("error"); | ||||||
|  |       setOpenSnackbar(true); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleChange = (e) => { | ||||||
|  |     const { name, value } = e.target; | ||||||
|  |     setNewEntity({ ...newEntity, [name]: value }); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleEditChange = (e) => { | ||||||
|  |     const { name, value } = e.target; | ||||||
|  |     setEditEntity({ ...editEntity, [name]: value }); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleEdit = (entity) => { | ||||||
|  |     setEditEntity(entity); | ||||||
|  |     setShowEditModal(true); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleUpdate = async () => { | ||||||
|  |     try { | ||||||
|  |       await axios.put(`${API_URL}/${editEntity.id}`, editEntity, { | ||||||
|  |         headers: { Authorization: `Bearer ${token}` }, | ||||||
|  |       }); | ||||||
|  |       fetchData(); | ||||||
|  |       setShowEditModal(false); | ||||||
|  |       setSnackbarMessage("Successfully updated!"); | ||||||
|  |       setSnackbarSeverity("success"); | ||||||
|  |       setOpenSnackbar(true); | ||||||
|  |     } catch (error) { | ||||||
|  |       console.error("Error updating data:", error); | ||||||
|  |       setSnackbarMessage("Failed to update!"); | ||||||
|  |       setSnackbarSeverity("error"); | ||||||
|  |       setOpenSnackbar(true); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleSearch = () => { | ||||||
|  |     const filtered = data.filter( | ||||||
|  |       (entity) => | ||||||
|  |         entity.name.toLowerCase().includes(searchQuery.toLowerCase()) || | ||||||
|  |         entity.email.toLowerCase().includes(searchQuery.toLowerCase()) || | ||||||
|  |         entity.mobno.toLowerCase().includes(searchQuery.toLowerCase()) || | ||||||
|  |         entity.address.toLowerCase().includes(searchQuery.toLowerCase()) || | ||||||
|  |         entity.pincode.toLowerCase().includes(searchQuery.toLowerCase()) | ||||||
|  |     ); | ||||||
|  |     setFilteredData(filtered); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className="container mt-5"> | ||||||
|  |       <Typography variant="h4" gutterBottom> | ||||||
|  |         Entity Table | ||||||
|  |       </Typography> | ||||||
|  |       <div className={classes.searchContainer}> | ||||||
|  |         <Button | ||||||
|  |           variant="contained" | ||||||
|  |           color="primary" | ||||||
|  |           onClick={() => setShowAddModal(true)} | ||||||
|  |           className={classes.button} | ||||||
|  |         > | ||||||
|  |           Add Entity | ||||||
|  |         </Button> | ||||||
|  |         <TextField | ||||||
|  |           className={classes.searchInput} | ||||||
|  |           label="Search" | ||||||
|  |           variant="outlined" | ||||||
|  |           size="small" | ||||||
|  |           value={searchQuery} | ||||||
|  |           onChange={(e) => setSearchQuery(e.target.value)} | ||||||
|  |           InputProps={{ | ||||||
|  |             endAdornment: ( | ||||||
|  |               <InputAdornment position="end"> | ||||||
|  |                 <IconButton> | ||||||
|  |                   <SearchIcon /> | ||||||
|  |                 </IconButton> | ||||||
|  |               </InputAdornment> | ||||||
|  |             ), | ||||||
|  |           }} | ||||||
|  |         /> | ||||||
|  |       </div> | ||||||
|  |       <TableContainer component={Paper} className={classes.tableContainer}> | ||||||
|  |         <Table> | ||||||
|  |           <TableHead> | ||||||
|  |             <TableRow className={classes.tableHeader}> | ||||||
|  |               <TableCell>ID</TableCell> | ||||||
|  |               <TableCell>Name</TableCell> | ||||||
|  |               <TableCell>Email</TableCell> | ||||||
|  |               <TableCell>Mobile No</TableCell> | ||||||
|  |               <TableCell>Address</TableCell> | ||||||
|  |               <TableCell>Pincode</TableCell> | ||||||
|  |               <TableCell>Actions</TableCell> | ||||||
|  |             </TableRow> | ||||||
|  |           </TableHead> | ||||||
|  |           <TableBody> | ||||||
|  |             {filteredData.slice(currentPage * itemsPerPage, (currentPage + 1) * itemsPerPage).map((entity) => ( | ||||||
|  |               <TableRow key={entity.id}> | ||||||
|  |                 <TableCell>{entity.id}</TableCell> | ||||||
|  |                 <TableCell>{entity.name}</TableCell> | ||||||
|  |                 <TableCell>{entity.email}</TableCell> | ||||||
|  |                 <TableCell>{entity.mobno}</TableCell> | ||||||
|  |                 <TableCell>{entity.address}</TableCell> | ||||||
|  |                 <TableCell>{entity.pincode}</TableCell> | ||||||
|  |                 <TableCell> | ||||||
|  |                   <Button | ||||||
|  |                     variant="contained" | ||||||
|  |                     color="warning" | ||||||
|  |                     size="small" | ||||||
|  |                     className={classes.button} | ||||||
|  |                     onClick={() => handleEdit(entity)} | ||||||
|  |                   > | ||||||
|  |                     Update | ||||||
|  |                   </Button> | ||||||
|  |                   <Button | ||||||
|  |                     variant="contained" | ||||||
|  |                     color="error" | ||||||
|  |                     size="small" | ||||||
|  |                     className={classes.button} | ||||||
|  |                     onClick={() => { | ||||||
|  |                       setDeleteEntityId(entity.id); | ||||||
|  |                       setShowDeleteModal(true); | ||||||
|  |                     }} | ||||||
|  |                   > | ||||||
|  |                     Delete | ||||||
|  |                   </Button> | ||||||
|  |                 </TableCell> | ||||||
|  |               </TableRow> | ||||||
|  |             ))} | ||||||
|  |           </TableBody> | ||||||
|  |         </Table> | ||||||
|  |       </TableContainer> | ||||||
|  |       <TablePagination | ||||||
|  |         rowsPerPageOptions={[5, 10, 25]} | ||||||
|  |         component="div" | ||||||
|  |         count={filteredData.length} | ||||||
|  |         rowsPerPage={itemsPerPage} | ||||||
|  |         page={currentPage} | ||||||
|  |         onPageChange={handlePageChange} | ||||||
|  |       /> | ||||||
|  |       <Dialog open={showEditModal} onClose={() => setShowEditModal(false)}> | ||||||
|  |         <DialogTitle>Edit Entity</DialogTitle> | ||||||
|  |         <DialogContent className={classes.dialogContent}> | ||||||
|  |           <TextField | ||||||
|  |             label="Name" | ||||||
|  |             variant="outlined" | ||||||
|  |             fullWidth | ||||||
|  |             name="name" | ||||||
|  |             value={editEntity?.name || ""} | ||||||
|  |             onChange={handleEditChange} | ||||||
|  |             className={classes.formControl} | ||||||
|  |           /> | ||||||
|  |           <TextField | ||||||
|  |             label="Email" | ||||||
|  |             variant="outlined" | ||||||
|  |             fullWidth | ||||||
|  |             name="email" | ||||||
|  |             value={editEntity?.email || ""} | ||||||
|  |             onChange={handleEditChange} | ||||||
|  |             className={classes.formControl} | ||||||
|  |           /> | ||||||
|  |           <TextField | ||||||
|  |             label="Mobile No" | ||||||
|  |             variant="outlined" | ||||||
|  |             fullWidth | ||||||
|  |             name="mobno" | ||||||
|  |             value={editEntity?.mobno || ""} | ||||||
|  |             onChange={handleEditChange} | ||||||
|  |             className={classes.formControl} | ||||||
|  |           /> | ||||||
|  |           <TextField | ||||||
|  |             label="Address" | ||||||
|  |             variant="outlined" | ||||||
|  |             fullWidth | ||||||
|  |             name="address" | ||||||
|  |             value={editEntity?.address || ""} | ||||||
|  |             onChange={handleEditChange} | ||||||
|  |             className={classes.formControl} | ||||||
|  |           /> | ||||||
|  |           <TextField | ||||||
|  |             label="Pincode" | ||||||
|  |             variant="outlined" | ||||||
|  |             fullWidth | ||||||
|  |             name="pincode" | ||||||
|  |             value={editEntity?.pincode || ""} | ||||||
|  |             onChange={handleEditChange} | ||||||
|  |             className={classes.formControl} | ||||||
|  |           /> | ||||||
|  |         </DialogContent> | ||||||
|  |         <DialogActions> | ||||||
|  |           <Button onClick={() => setShowEditModal(false)} color="primary"> | ||||||
|  |             Cancel | ||||||
|  |           </Button> | ||||||
|  |           <Button onClick={handleUpdate} color="primary"> | ||||||
|  |             Update | ||||||
|  |           </Button> | ||||||
|  |         </DialogActions> | ||||||
|  |       </Dialog> | ||||||
|  |       <Dialog open={showAddModal} onClose={() => setShowAddModal(false)}> | ||||||
|  |         <DialogTitle>Add Entity</DialogTitle> | ||||||
|  |         <DialogContent className={classes.dialogContent}> | ||||||
|  |           <TextField | ||||||
|  |             label="Name" | ||||||
|  |             variant="outlined" | ||||||
|  |             fullWidth | ||||||
|  |             name="name" | ||||||
|  |             value={newEntity.name} | ||||||
|  |             onChange={handleChange} | ||||||
|  |             className={classes.formControl} | ||||||
|  |           /> | ||||||
|  |           <TextField | ||||||
|  |             label="Email" | ||||||
|  |             variant="outlined" | ||||||
|  |             fullWidth | ||||||
|  |             name="email" | ||||||
|  |             value={newEntity.email} | ||||||
|  |             onChange={handleChange} | ||||||
|  |             className={classes.formControl} | ||||||
|  |           /> | ||||||
|  |           <TextField | ||||||
|  |             label="Mobile No" | ||||||
|  |             variant="outlined" | ||||||
|  |             fullWidth | ||||||
|  |             name="mobno" | ||||||
|  |             value={newEntity.mobno} | ||||||
|  |             onChange={handleChange} | ||||||
|  |             className={classes.formControl} | ||||||
|  |           /> | ||||||
|  |           <TextField | ||||||
|  |             label="Address" | ||||||
|  |             variant="outlined" | ||||||
|  |             fullWidth | ||||||
|  |             name="address" | ||||||
|  |             value={newEntity.address} | ||||||
|  |             onChange={handleChange} | ||||||
|  |             className={classes.formControl} | ||||||
|  |           /> | ||||||
|  |           <TextField | ||||||
|  |             label="Pincode" | ||||||
|  |             variant="outlined" | ||||||
|  |             fullWidth | ||||||
|  |             name="pincode" | ||||||
|  |             value={newEntity.pincode} | ||||||
|  |             onChange={handleChange} | ||||||
|  |             className={classes.formControl} | ||||||
|  |           /> | ||||||
|  |         </DialogContent> | ||||||
|  |         <DialogActions> | ||||||
|  |           <Button onClick={() => setShowAddModal(false)} color="primary"> | ||||||
|  |             Cancel | ||||||
|  |           </Button> | ||||||
|  |           <Button onClick={handleAdd} color="primary"> | ||||||
|  |             Add | ||||||
|  |           </Button> | ||||||
|  |         </DialogActions> | ||||||
|  |       </Dialog> | ||||||
|  |       <Dialog open={showDeleteModal} onClose={() => setShowDeleteModal(false)}> | ||||||
|  |         <DialogTitle>Confirm Delete</DialogTitle> | ||||||
|  |         <DialogContent> | ||||||
|  |           <Typography>Are you sure you want to delete this entity?</Typography> | ||||||
|  |         </DialogContent> | ||||||
|  |         <DialogActions> | ||||||
|  |           <Button onClick={() => setShowDeleteModal(false)} color="primary"> | ||||||
|  |             Cancel | ||||||
|  |           </Button> | ||||||
|  |           <Button onClick={handleDelete} color="primary"> | ||||||
|  |             Delete | ||||||
|  |           </Button> | ||||||
|  |         </DialogActions> | ||||||
|  |       </Dialog> | ||||||
|  |       <Snackbar | ||||||
|  |         open={openSnackbar} | ||||||
|  |         autoHideDuration={6000} | ||||||
|  |         onClose={() => setOpenSnackbar(false)} | ||||||
|  |       > | ||||||
|  |         <Alert onClose={() => setOpenSnackbar(false)} severity={snackbarSeverity}> | ||||||
|  |           {snackbarMessage} | ||||||
|  |         </Alert> | ||||||
|  |       </Snackbar> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default EntityTable; | ||||||
							
								
								
									
										146
									
								
								src/components/Dashboard/TokenRegistery/TokenRegistery.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								src/components/Dashboard/TokenRegistery/TokenRegistery.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,146 @@ | |||||||
|  | import React, { useState, useEffect, useRef } from "react"; | ||||||
|  | import { Box, Button } from "@mui/material"; | ||||||
|  | import { DataGrid, GridToolbarContainer } from "@mui/x-data-grid"; | ||||||
|  | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
|  | import { faEllipsisV } from "@fortawesome/free-solid-svg-icons"; | ||||||
|  | 
 | ||||||
|  | const api = process.env.REACT_APP_API_BASE_URL; | ||||||
|  | 
 | ||||||
|  | function CustomToolbar({ apiRef, handleModal }) { | ||||||
|  |   const handleGoToPage1 = () => { | ||||||
|  |     if (apiRef.current) { | ||||||
|  |       apiRef.current.setPage(1); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <GridToolbarContainer className="flex flex-wrap justify-between p-2 bg-gray-100 border-b border-gray-200"> | ||||||
|  |       <Button | ||||||
|  |         onClick={handleGoToPage1} | ||||||
|  |         className="bg-blue-500 text-white px-4 py-2 rounded shadow hover:bg-blue-600 m-1" | ||||||
|  |       > | ||||||
|  |         Go to page 1 | ||||||
|  |       </Button> | ||||||
|  |       <Button | ||||||
|  |         onClick={handleModal} | ||||||
|  |         className="bg-green-500 text-white px-4 py-2 rounded shadow hover:bg-green-600 m-1" | ||||||
|  |       > | ||||||
|  |         + | ||||||
|  |       </Button> | ||||||
|  |     </GridToolbarContainer> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function TokenRegistery() { | ||||||
|  |   const [menuItems, setMenuItems] = useState([]); | ||||||
|  |   const [selectedMenuItem, setSelectedMenuItem] = useState(null); | ||||||
|  |   const [isModalOpen, setIsModalOpen] = useState(false); | ||||||
|  |   const apiRef = useRef(null); | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     const fetchData = async () => { | ||||||
|  |       const token = localStorage.getItem("token"); // Get token from local storage
 | ||||||
|  |       try { | ||||||
|  |         const response = await fetch( | ||||||
|  |           `${api}/apiregistery/getall`, | ||||||
|  |           { | ||||||
|  |             headers: { | ||||||
|  |               Authorization: `Bearer ${token}`, | ||||||
|  |             }, | ||||||
|  |           } | ||||||
|  |         ); | ||||||
|  |         const data = await response.json(); | ||||||
|  |         setMenuItems(data); | ||||||
|  |       } catch (error) { | ||||||
|  |         console.error("Error fetching data:", error); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     fetchData(); | ||||||
|  |   }, []); | ||||||
|  | 
 | ||||||
|  |   const handleThreeDotsClick = (menuItemId) => { | ||||||
|  |     setSelectedMenuItem(menuItemId === selectedMenuItem ? null : menuItemId); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const columns = [ | ||||||
|  |     { | ||||||
|  |       field: "table_id", | ||||||
|  |       headerName: "Table ID", | ||||||
|  |       width: 200, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "token_name", | ||||||
|  |       headerName: "Token Name", | ||||||
|  |       width: 250, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "token", | ||||||
|  |       headerName: "Token", | ||||||
|  |       width: 200, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "actions", | ||||||
|  |       headerName: "Actions", | ||||||
|  |       width: 150, | ||||||
|  |       renderCell: ({ row }) => ( | ||||||
|  |         <div className="relative"> | ||||||
|  |           <div | ||||||
|  |             className="cursor-pointer" | ||||||
|  |             onClick={() => handleThreeDotsClick(row.id)} | ||||||
|  |           > | ||||||
|  |             <FontAwesomeIcon icon={faEllipsisV} /> | ||||||
|  |           </div> | ||||||
|  |           {selectedMenuItem === row.id && ( | ||||||
|  |             <div className="absolute right-0 mt-2 py-2 w-48 bg-white rounded-lg shadow-xl"> | ||||||
|  |               <button className="block px-4 py-2 text-gray-800 hover:bg-gray-200 w-full text-left"> | ||||||
|  |                 Edit | ||||||
|  |               </button> | ||||||
|  |               <button className="block px-4 py-2 text-gray-800 hover:bg-gray-200 w-full text-left"> | ||||||
|  |                 Delete | ||||||
|  |               </button> | ||||||
|  |             </div> | ||||||
|  |           )} | ||||||
|  |         </div> | ||||||
|  |       ), | ||||||
|  |     }, | ||||||
|  |   ]; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className="flex justify-center mt-5 px-2 md:px-0"> | ||||||
|  |       <Box className="w-full max-w-7xl bg-gray-50 p-4 md:p-6 rounded shadow-md"> | ||||||
|  |         <p className="text-2xl md:text-3xl text-center text-white bg-gray-400 mb-4 p-3"> | ||||||
|  |           Token Registry | ||||||
|  |         </p> | ||||||
|  |         <div className="bg-white p-2 md:p-4 rounded shadow-md"> | ||||||
|  |           <DataGrid | ||||||
|  |             rows={menuItems} | ||||||
|  |             columns={columns} | ||||||
|  |             components={{ | ||||||
|  |               Toolbar: () => ( | ||||||
|  |                 <CustomToolbar | ||||||
|  |                   apiRef={apiRef} | ||||||
|  |                   handleModal={() => setIsModalOpen(true)} | ||||||
|  |                 /> | ||||||
|  |               ), | ||||||
|  |             }} | ||||||
|  |             pageSize={10} | ||||||
|  |             onGridReady={(gridApi) => { | ||||||
|  |               apiRef.current = gridApi; | ||||||
|  |             }} | ||||||
|  |             className="data-grid" | ||||||
|  |           /> | ||||||
|  |         </div> | ||||||
|  |       </Box> | ||||||
|  |       {/* Add your modals and other components here */} | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default TokenRegistery; | ||||||
							
								
								
									
										41
									
								
								src/components/Dashboard/UpdateModal.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/components/Dashboard/UpdateModal.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | |||||||
|  | /* UpdateModal.css */ | ||||||
|  | 
 | ||||||
|  | .modalWrapper { | ||||||
|  |     position: fixed; | ||||||
|  |     top: 0; | ||||||
|  |     left: 0; | ||||||
|  |     width: 100%; | ||||||
|  |     height: 100%; | ||||||
|  |     background: rgba(0, 0, 0, 0.5); | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: center; | ||||||
|  |     align-items: center; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   .modal { | ||||||
|  |     background: white; | ||||||
|  |     padding: 20px; | ||||||
|  |     border-radius: 8px; | ||||||
|  |     box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   label { | ||||||
|  |     display: block; | ||||||
|  |     margin-bottom: 5px; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   input { | ||||||
|  |     width: 100%; | ||||||
|  |     padding: 8px; | ||||||
|  |     margin-bottom: 10px; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   button { | ||||||
|  |     background-color: #4caf50; | ||||||
|  |     color: white; | ||||||
|  |     padding: 10px 15px; | ||||||
|  |     border: none; | ||||||
|  |     border-radius: 4px; | ||||||
|  |     cursor: pointer; | ||||||
|  |   } | ||||||
|  |    | ||||||
							
								
								
									
										107
									
								
								src/components/Dashboard/UpdateModal.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/components/Dashboard/UpdateModal.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,107 @@ | |||||||
|  | import React, { useState, useEffect } from 'react'; | ||||||
|  | 
 | ||||||
|  | const UpdateModal = ({ user, onUpdate, onClose }) => { | ||||||
|  |   const [updatedUser, setUpdatedUser] = useState(() => ({ ...user })); | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     console.log('Updated user state:', updatedUser); | ||||||
|  |   }, [updatedUser]); | ||||||
|  | 
 | ||||||
|  |   const handleChange = (field, value) => { | ||||||
|  |     const updatedData = { ...updatedUser, [field]: value }; | ||||||
|  |     setUpdatedUser(updatedData); | ||||||
|  |   }; | ||||||
|  |   const handleSave = () => { | ||||||
|  |     onUpdate(updatedUser); | ||||||
|  |     onClose(); | ||||||
|  |   }; | ||||||
|  |    | ||||||
|  |   const handleUpdate = () => { | ||||||
|  |     console.log('Before update:', updatedUser); | ||||||
|  |     onUpdate(updatedUser); | ||||||
|  | 
 | ||||||
|  |     onClose(); | ||||||
|  |    | ||||||
|  | 
 | ||||||
|  |     // Use a callback function with setUpdatedUser to ensure the state is updated
 | ||||||
|  |     setUpdatedUser((prev) => { | ||||||
|  |       const updatedData = { ...prev }; | ||||||
|  |       console.log('Updated data:', updatedData); | ||||||
|  | 
 | ||||||
|  |       onUpdate(updatedData); // Pass the updatedData to onUpdate
 | ||||||
|  |       onClose(); | ||||||
|  |       return updatedData; // Return the updatedData to setUpdatedUser
 | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     // Set the updatedUser state directly to ensure the UI reflects the changes
 | ||||||
|  |     setUpdatedUser(updatedUser); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className="modalWrapper"> | ||||||
|  |       <div className="modal"> | ||||||
|  |         <button className="closeBtn" onClick={onClose}> | ||||||
|  |           X | ||||||
|  |         </button> | ||||||
|  |         <div>User ID: {user.userId}</div> | ||||||
|  |         <div>Username: {user.username}</div> | ||||||
|  |         <div>Full Name: {user.fullName}</div> | ||||||
|  | 
 | ||||||
|  |         <div>Email: {user.email}</div> | ||||||
|  |          | ||||||
|  |         <div>Mob Number: {user.mobno}</div> | ||||||
|  |         <div>User grp name: {user.usergrpname}</div> | ||||||
|  | 
 | ||||||
|  |         <label htmlFor="updatedUserId">User ID:</label> | ||||||
|  |         <input | ||||||
|  |           id="updatedUserId" | ||||||
|  |           type="text" | ||||||
|  |           value={updatedUser.userId} | ||||||
|  |           onChange={(e) => handleChange('userId', e.target.value)} | ||||||
|  |         /> | ||||||
|  | 
 | ||||||
|  |         <label htmlFor="updatedUsername">Username:</label> | ||||||
|  |         <input | ||||||
|  |           id="updatedUsername" | ||||||
|  |           type="text" | ||||||
|  |           value={updatedUser.username} | ||||||
|  |           onChange={(e) => handleChange('username', e.target.value)} | ||||||
|  |         /> | ||||||
|  | 
 | ||||||
|  |         <label htmlFor="updatedEmail">Email:</label> | ||||||
|  |         <input | ||||||
|  |           id="updatedEmail" | ||||||
|  |           type="text" | ||||||
|  |           value={updatedUser.email} | ||||||
|  |           onChange={(e) => handleChange('email', e.target.value)} | ||||||
|  |         /> | ||||||
|  | 
 | ||||||
|  |         <label htmlFor="updatedFullName">Full Name:</label> | ||||||
|  |         <input | ||||||
|  |           id="updatedFullName" | ||||||
|  |           type="text" | ||||||
|  |           value={updatedUser.fullName} | ||||||
|  |           onChange={(e) => handleChange('fullName', e.target.value)} | ||||||
|  |         /> | ||||||
|  | <label htmlFor="updatedMobno">Mob No:</label> | ||||||
|  |         <input | ||||||
|  |           id="updatedmobno" | ||||||
|  |           type="number" | ||||||
|  |           value={updatedUser.mobno} | ||||||
|  |           onChange={(e) => handleChange('mobno', e.target.value)} | ||||||
|  |         /> | ||||||
|  | <label htmlFor="updatedusergrpname">User grp name:</label> | ||||||
|  |         <input | ||||||
|  |           id="updatedusergrpname" | ||||||
|  |           type="text" | ||||||
|  |           value={updatedUser.usergrpname} | ||||||
|  |           onChange={(e) => handleChange('usergrpname', e.target.value)} | ||||||
|  |         /> | ||||||
|  | 
 | ||||||
|  |         <button onClick={handleSave}>SAVE</button> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default UpdateModal; | ||||||
							
								
								
									
										69
									
								
								src/components/Dashboard/UserGroupMaintance/Modelitem.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/components/Dashboard/UserGroupMaintance/Modelitem.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,69 @@ | |||||||
|  | .modalWrapper { | ||||||
|  |     position: fixed; | ||||||
|  |     top: 0; | ||||||
|  |     left: 0; | ||||||
|  |     width: 100%; | ||||||
|  |     height: 100%; | ||||||
|  |     background: rgba(0, 0, 0, 0.5); | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: center; | ||||||
|  |     align-items: center; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   .modal { | ||||||
|  |     background: #fff; | ||||||
|  |     padding: 20px; | ||||||
|  |     border-radius: 8px; | ||||||
|  |     box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); | ||||||
|  |     width: 300px; | ||||||
|  |     max-width: 100%; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   .closeBtn { | ||||||
|  |     background: none; | ||||||
|  |     border: none; | ||||||
|  |     font-size: 18px; | ||||||
|  |     color: #333; | ||||||
|  |     cursor: pointer; | ||||||
|  |     position: absolute; | ||||||
|  |     top: 10px; | ||||||
|  |     right: 10px; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   label { | ||||||
|  |     display: block; | ||||||
|  |     margin-bottom: 5px; | ||||||
|  |     font-weight: bold; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   input { | ||||||
|  |     width: 100%; | ||||||
|  |     padding: 8px; | ||||||
|  |     margin-bottom: 10px; | ||||||
|  |     border: 1px solid #ccc; | ||||||
|  |     border-radius: 4px; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   button { | ||||||
|  |     background-color: #4caf50; | ||||||
|  |     color: white; | ||||||
|  |     padding: 10px 15px; | ||||||
|  |     border: none; | ||||||
|  |     border-radius: 4px; | ||||||
|  |     cursor: pointer; | ||||||
|  |     margin-right: 10px; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   button:hover { | ||||||
|  |     background-color: #45a049; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   button:last-child { | ||||||
|  |     background-color: #36bbf4; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   button:last-child:hover { | ||||||
|  |     background-color: #2f8cd3; | ||||||
|  |   } | ||||||
|  |    | ||||||
							
								
								
									
										146
									
								
								src/components/Dashboard/UserGroupMaintance/Modelitem.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								src/components/Dashboard/UserGroupMaintance/Modelitem.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,146 @@ | |||||||
|  | // AddUserGroupModal.js
 | ||||||
|  | import React, { useState } from 'react'; | ||||||
|  | import './Modelitem.css'; | ||||||
|  | 
 | ||||||
|  | const AddUserGroupModal = ({ showModal, handleCloseModal, onSave }) => { | ||||||
|  |   const [newUserData, setNewUserData] = useState({ | ||||||
|  |     groupName: '', | ||||||
|  |     groupDesc: '', | ||||||
|  |     createBy: '', | ||||||
|  |     createDate: '', | ||||||
|  |     updateDate: '', | ||||||
|  |     updateBy: '', | ||||||
|  |     status: '', | ||||||
|  |     groupLevel: '', | ||||||
|  |     createDateFormatted: '', | ||||||
|  |     updateDateFormatted: '', | ||||||
|  |     // Add more fields as needed
 | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |    | ||||||
|  |   const handleSave = () => { | ||||||
|  |     // Format date fields before saving
 | ||||||
|  |     const formattedData = { | ||||||
|  |       ...newUserData, | ||||||
|  |       createDate: new Date(newUserData.createDate).toISOString(), | ||||||
|  |       updateDate: new Date(newUserData.updateDate).toISOString(), | ||||||
|  |     }; | ||||||
|  |    | ||||||
|  |     onSave(formattedData); // Pass the new data to the parent component
 | ||||||
|  |     handleCloseModal(); // Close the modal after saving
 | ||||||
|  |   }; | ||||||
|  |    | ||||||
|  |   const handleCancel = () => { | ||||||
|  |     setNewUserData({ | ||||||
|  |       groupName: '', | ||||||
|  |       groupDesc: '', | ||||||
|  |       createBy: '', | ||||||
|  |       createDate: '', | ||||||
|  |       updateDate: '', | ||||||
|  |       updateBy: '', | ||||||
|  |       status: '', | ||||||
|  |       groupLevel: '', | ||||||
|  |       createDateFormatted: '', | ||||||
|  |       updateDateFormatted: '', | ||||||
|  |       // Reset other fields as needed
 | ||||||
|  |     }); | ||||||
|  |     handleCloseModal(); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <> | ||||||
|  |       {showModal && ( | ||||||
|  |         <div className='modalWrapper'> | ||||||
|  |           <div className='modal'> | ||||||
|  |             <button className="closeBtn" onClick={handleCancel}>X</button> | ||||||
|  | 
 | ||||||
|  |             <label htmlFor="groupName">Group Name:</label> | ||||||
|  |             <input | ||||||
|  |               type="text" | ||||||
|  |               id="groupName" | ||||||
|  |               value={newUserData.groupName} | ||||||
|  |               onChange={(e) => setNewUserData((prevData) => ({ ...prevData, groupName: e.target.value }))} | ||||||
|  |             /> | ||||||
|  | 
 | ||||||
|  |             <label htmlFor="groupDesc">Group Description:</label> | ||||||
|  |             <input | ||||||
|  |               type="text" | ||||||
|  |               id="groupDesc" | ||||||
|  |               value={newUserData.groupDesc} | ||||||
|  |               onChange={(e) => setNewUserData((prevData) => ({ ...prevData, groupDesc: e.target.value }))} | ||||||
|  |             /> | ||||||
|  | 
 | ||||||
|  |             <label htmlFor="createBy">Create By:</label> | ||||||
|  |             <input | ||||||
|  |               type="text" | ||||||
|  |               id="createBy" | ||||||
|  |               value={newUserData.createBy} | ||||||
|  |               onChange={(e) => setNewUserData((prevData) => ({ ...prevData, createBy: e.target.value }))} | ||||||
|  |             /> | ||||||
|  | 
 | ||||||
|  |             <label htmlFor="createDate">Create Date:</label> | ||||||
|  |             <input | ||||||
|  |               type="date" | ||||||
|  |               id="createDate" | ||||||
|  |               value={newUserData.createDate} | ||||||
|  |               onChange={(e) => setNewUserData((prevData) => ({ ...prevData, createDate: e.target.value }))} | ||||||
|  |             /> | ||||||
|  | 
 | ||||||
|  |             <label htmlFor="updateDate">Update Date:</label> | ||||||
|  |             <input | ||||||
|  |               type="text" | ||||||
|  |               id="updateDate" | ||||||
|  |               value={newUserData.updateDate} | ||||||
|  |               onChange={(e) => setNewUserData((prevData) => ({ ...prevData, updateDate: e.target.value }))} | ||||||
|  |             /> | ||||||
|  | 
 | ||||||
|  |             <label htmlFor="updateBy">Update By:</label> | ||||||
|  |             <input | ||||||
|  |               type="text" | ||||||
|  |               id="updateBy" | ||||||
|  |               value={newUserData.updateBy} | ||||||
|  |               onChange={(e) => setNewUserData((prevData) => ({ ...prevData, updateBy: e.target.value }))} | ||||||
|  |             /> | ||||||
|  | 
 | ||||||
|  |             <label htmlFor="status">Status:</label> | ||||||
|  |             <input | ||||||
|  |               type="text" | ||||||
|  |               id="status" | ||||||
|  |               value={newUserData.status} | ||||||
|  |               onChange={(e) => setNewUserData((prevData) => ({ ...prevData, status: e.target.value }))} | ||||||
|  |             /> | ||||||
|  | 
 | ||||||
|  |             <label htmlFor="groupLevel">Group Level:</label> | ||||||
|  |             <input | ||||||
|  |               type="text" | ||||||
|  |               id="groupLevel" | ||||||
|  |               value={newUserData.groupLevel} | ||||||
|  |               onChange={(e) => setNewUserData((prevData) => ({ ...prevData, groupLevel: e.target.value }))} | ||||||
|  |             /> | ||||||
|  | 
 | ||||||
|  |             <label htmlFor="createDateFormatted">Create Date Formatted:</label> | ||||||
|  |             <input | ||||||
|  |               type="text" | ||||||
|  |               id="createDateFormatted" | ||||||
|  |               value={newUserData.createDateFormatted} | ||||||
|  |               onChange={(e) => setNewUserData((prevData) => ({ ...prevData, createDateFormatted: e.target.value }))} | ||||||
|  |             /> | ||||||
|  | 
 | ||||||
|  |             <label htmlFor="updateDateFormatted">Update Date Formatted:</label> | ||||||
|  |             <input | ||||||
|  |               type="text" | ||||||
|  |               id="updateDateFormatted" | ||||||
|  |               value={newUserData.updateDateFormatted} | ||||||
|  |               onChange={(e) => setNewUserData((prevData) => ({ ...prevData, updateDateFormatted: e.target.value }))} | ||||||
|  |             /> | ||||||
|  | 
 | ||||||
|  |             <button onClick={handleSave}>Save</button> | ||||||
|  |             <button onClick={handleCancel}>Cancel</button> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       )} | ||||||
|  |     </> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default AddUserGroupModal; | ||||||
| @ -0,0 +1,7 @@ | |||||||
|  | @import url('https://fonts.googleapis.com/css2?family=EB+Garamond:ital,wght@0,400..800;1,400..800&family=PT+Serif:ital,wght@0,400;0,700;1,400;1,700&family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap'); | ||||||
|  | .custom-header, .custom-cell { | ||||||
|  |   font-family: 'PT Serif", serif ';  | ||||||
|  |    | ||||||
|  |   font-style: normal; | ||||||
|  |   font-weight: bold; | ||||||
|  | } | ||||||
| @ -0,0 +1,224 @@ | |||||||
|  | import React, { useState, useEffect, useRef } from "react"; | ||||||
|  | import { Box, Button } from "@mui/material"; | ||||||
|  | import { DataGrid, GridToolbarContainer } from "@mui/x-data-grid"; | ||||||
|  | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
|  | import { faEllipsisV } from "@fortawesome/free-solid-svg-icons"; | ||||||
|  | import "./UserGroupMaintance.css"; | ||||||
|  | import { Token } from "@mui/icons-material"; | ||||||
|  | 
 | ||||||
|  | const api = process.env.REACT_APP_API_BASE_URL; | ||||||
|  | 
 | ||||||
|  | function CustomToolbar({ apiRef, handleThreeDotsClick, handleModal }) { | ||||||
|  |   const handleGoToPage1 = () => { | ||||||
|  |     if (apiRef.current) { | ||||||
|  |       apiRef.current.setPage(1); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <GridToolbarContainer> | ||||||
|  |       <Button onClick={handleGoToPage1}>Go to page 1</Button> | ||||||
|  |       <Button onClick={handleModal}>+</Button> | ||||||
|  |     </GridToolbarContainer> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function UserMaintance() { | ||||||
|  |   const [userGroups, setUserGroups] = useState([]); | ||||||
|  |   const [selectedUserGroup, setSelectedUserGroup] = useState(null); | ||||||
|  |   const [isModalOpen, setIsModalOpen] = useState(false); | ||||||
|  |   const [isUpdateModalOpen, setIsUpdateModalOpen] = useState(false); | ||||||
|  |   const apiRef = useRef(null); | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     const fetchData = async () => { | ||||||
|  |       const token = localStorage.getItem("token"); | ||||||
|  |       try { | ||||||
|  |         const response = await fetch(`${api}/api/getAllUsrGrp`, { | ||||||
|  |           headers: { authorization: `bearer ${token}` }, | ||||||
|  |         }); | ||||||
|  |         const data = await response.json(); | ||||||
|  |         const userGroupsWithIds = data.map((group, index) => ({ | ||||||
|  |           ...group, | ||||||
|  |           id: index + 1, | ||||||
|  |         })); | ||||||
|  |         setUserGroups(userGroupsWithIds); | ||||||
|  |       } catch (error) { | ||||||
|  |         console.error("Error fetching data:", error); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     fetchData(); | ||||||
|  |   }, []); | ||||||
|  | 
 | ||||||
|  |   const handleThreeDotsClick = (usrGrp) => { | ||||||
|  |     setSelectedUserGroup(usrGrp === selectedUserGroup ? null : usrGrp); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleDelete = async (usrGrp) => { | ||||||
|  |     try { | ||||||
|  |       const response = await fetch(`${api}/api/delete_usrgrp/${usrGrp}`, { | ||||||
|  |         method: "DELETE", | ||||||
|  |       }); | ||||||
|  |       if (response.ok) { | ||||||
|  |         setUserGroups(userGroups.filter((group) => group.usrGrp !== usrGrp)); | ||||||
|  |         console.log("User group deleted successfully:", usrGrp); | ||||||
|  |       } else { | ||||||
|  |         console.error("Failed to delete user group:", response.statusText); | ||||||
|  |       } | ||||||
|  |     } catch (error) { | ||||||
|  |       console.error("Error deleting user group:", error); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleModal = () => { | ||||||
|  |     setIsModalOpen(true); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const columns = [ | ||||||
|  |     { | ||||||
|  |       field: "usrGrp", | ||||||
|  |       headerName: "User Group ID", | ||||||
|  |       width: 150, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "groupName", | ||||||
|  |       headerName: "Group Name", | ||||||
|  |       width: 150, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "groupDesc", | ||||||
|  |       headerName: "Group Description", | ||||||
|  |       width: 150, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "createby", | ||||||
|  |       headerName: "Create By", | ||||||
|  |       width: 100, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "createdate", | ||||||
|  |       headerName: "Create Date", | ||||||
|  |       width: 100, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "updatedate", | ||||||
|  |       headerName: "Update Date", | ||||||
|  |       width: 100, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "updateby", | ||||||
|  |       headerName: "Update By", | ||||||
|  |       width: 100, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "status", | ||||||
|  |       headerName: "Status", | ||||||
|  |       width: 100, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "grouplevel", | ||||||
|  |       headerName: "Group Level", | ||||||
|  |       width: 100, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "createdateformated", | ||||||
|  |       headerName: "Create Date Formated", | ||||||
|  |       width: 100, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       field: "updatedateformated", | ||||||
|  |       headerName: "Update Date Formated", | ||||||
|  |       width: 100, | ||||||
|  |       headerClassName: "custom-header", | ||||||
|  |       cellClassName: "custom-cell", | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     // Add other columns as needed
 | ||||||
|  |     { | ||||||
|  |       field: "actions", | ||||||
|  |       headerName: "Actions", | ||||||
|  |       width: 150, | ||||||
|  |       renderCell: ({ row }) => ( | ||||||
|  |         <div> | ||||||
|  |           <div | ||||||
|  |             className="three-dots" | ||||||
|  |             onClick={() => handleThreeDotsClick(row.usrGrp)} | ||||||
|  |           > | ||||||
|  |             <FontAwesomeIcon icon={faEllipsisV} /> | ||||||
|  |           </div> | ||||||
|  |           {selectedUserGroup === row.usrGrp && ( | ||||||
|  |             <div className="popover"> | ||||||
|  |               <button onClick={() => handleDelete(row.usrGrp)}>Delete</button> | ||||||
|  |               {/* You can include other actions here */} | ||||||
|  |             </div> | ||||||
|  |           )} | ||||||
|  |         </div> | ||||||
|  |       ), | ||||||
|  |     }, | ||||||
|  |   ]; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className="flex flex-col items-center justify-center min-h-screen bg-gray-100 p-4"> | ||||||
|  |       <div className="text-center text-3xl text-white bg-gray-400 p-2 rounded-lg"> | ||||||
|  |         User Group Maintenance | ||||||
|  |       </div> | ||||||
|  | 
 | ||||||
|  |       <Box | ||||||
|  |         className="w-full p-4 md:w-3/4 lg:w-2/3 xl:w-1/2 bg-white border border-gray-200 shadow-lg rounded-lg" | ||||||
|  |         sx={{ height: 500, width: "100%" }} | ||||||
|  |       > | ||||||
|  |         <DataGrid | ||||||
|  |           rows={userGroups} | ||||||
|  |           columns={columns} | ||||||
|  |           components={{ | ||||||
|  |             Toolbar: () => ( | ||||||
|  |               <CustomToolbar | ||||||
|  |                 apiRef={apiRef} | ||||||
|  |                 handleThreeDotsClick={handleThreeDotsClick} | ||||||
|  |                 handleModal={handleModal} | ||||||
|  |               /> | ||||||
|  |             ), | ||||||
|  |           }} | ||||||
|  |           pageSize={10} | ||||||
|  |           onGridReady={(gridApi) => { | ||||||
|  |             apiRef.current = gridApi; | ||||||
|  |           }} | ||||||
|  |           className="bg-gray-400" | ||||||
|  |         /> | ||||||
|  |       </Box> | ||||||
|  |       {/* Your modals and other components */} | ||||||
|  |       {isModalOpen && ( | ||||||
|  |         <div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 p-4"> | ||||||
|  |           <div className="bg-white p-8 rounded-lg shadow-lg max-w-lg w-full"> | ||||||
|  |             <h2 className="text-xl font-bold mb-4">Modal Title</h2> | ||||||
|  |             {/* Modal content here */} | ||||||
|  |             <Button onClick={() => setIsModalOpen(false)}>Close</Button> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       )} | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default UserMaintance; | ||||||
							
								
								
									
										132
									
								
								src/components/Dashboard/UserMaintance.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								src/components/Dashboard/UserMaintance.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,132 @@ | |||||||
|  |  /* .container { | ||||||
|  |   font-family: Arial, sans-serif; | ||||||
|  |   max-width: 2000px; | ||||||
|  |   margin: 0 auto; | ||||||
|  |   padding: 20px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | h1 { | ||||||
|  |   text-align: center; | ||||||
|  |   margin-bottom: 20px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | table { | ||||||
|  |   width: 100%; | ||||||
|  |   border-collapse: collapse; | ||||||
|  |   margin: 0 auto;  | ||||||
|  |   max-width: 2000px; | ||||||
|  |    | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | table th, | ||||||
|  | table td { | ||||||
|  |   border: 1px solid #ddd; | ||||||
|  |   padding: 8px; | ||||||
|  |   text-align: left; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | table th { | ||||||
|  |   background-color: #f2f2f2; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | input[type='text'] { | ||||||
|  |   width: 100%; | ||||||
|  |   padding: 5px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | button { | ||||||
|  |   padding: 8px 12px; | ||||||
|  |   background-color: #007bff; | ||||||
|  |   color: #fff; | ||||||
|  |   border: none; | ||||||
|  |   cursor: pointer; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | button:hover { | ||||||
|  |   background-color: #0056b3; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | label { | ||||||
|  |   margin-right: 10px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | select { | ||||||
|  |   padding: 5px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .modal { | ||||||
|  |   position: fixed; | ||||||
|  |   top: 0; | ||||||
|  |   left: 0; | ||||||
|  |   width: 100%; | ||||||
|  |   height: 100%; | ||||||
|  |   background-color: rgba(0, 0, 0, 0.5); | ||||||
|  |   display: flex; | ||||||
|  |   justify-content: center; | ||||||
|  |   align-items: center; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .modal-content { | ||||||
|  |   background-color: #fff; | ||||||
|  |   padding: 20px; | ||||||
|  |   border-radius: 5px; | ||||||
|  |   box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .modal-content input { | ||||||
|  |   margin-bottom: 10px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .modal-content button { | ||||||
|  |   margin-top: 10px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .update-modal { | ||||||
|  |   position: fixed; | ||||||
|  |   top: 0; | ||||||
|  |   left: 0; | ||||||
|  |   width: 100%; | ||||||
|  |   height: 100%; | ||||||
|  |   background-color: rgba(0, 0, 0, 0.5); | ||||||
|  |   display: flex; | ||||||
|  |   justify-content: center; | ||||||
|  |   align-items: center; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .update-modal-content { | ||||||
|  |   background-color: #fff; | ||||||
|  |   padding: 20px; | ||||||
|  |   border-radius: 5px; | ||||||
|  |   box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .update-modal-content input { | ||||||
|  |   margin-bottom: 10px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .update-modal-content button { | ||||||
|  |   margin-top: 10px; | ||||||
|  | } | ||||||
|  | .spinner { | ||||||
|  |   display: inline-block; | ||||||
|  |   width: 40px; | ||||||
|  |   height: 40px; | ||||||
|  |   border: 4px solid rgba(0, 0, 0, 0.1); | ||||||
|  |   border-left-color: #7983ff;  | ||||||
|  |   border-radius: 50%; | ||||||
|  |   animation: spin 1s linear infinite;  | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes spin { | ||||||
|  |   to { | ||||||
|  |     transform: rotate(360deg); | ||||||
|  |   } | ||||||
|  | }  */ | ||||||
|  | 
 | ||||||
|  | @import url('https://fonts.googleapis.com/css2?family=EB+Garamond:ital,wght@0,400..800;1,400..800&family=PT+Serif:ital,wght@0,400;0,700;1,400;1,700&family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap'); | ||||||
|  | .custom-header, .custom-cell { | ||||||
|  |   font-family: 'PT Serif", serif ';  | ||||||
|  |    | ||||||
|  |   font-style: normal; | ||||||
|  |   font-weight: bold; | ||||||
|  | } | ||||||
							
								
								
									
										169
									
								
								src/components/Dashboard/UserMaintance.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								src/components/Dashboard/UserMaintance.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,169 @@ | |||||||
|  | import React, { useState, useEffect, useRef } from "react"; | ||||||
|  | import { Box, Button } from "@mui/material"; | ||||||
|  | import { DataGrid, GridToolbarContainer } from "@mui/x-data-grid"; | ||||||
|  | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
|  | import { faEllipsisV } from "@fortawesome/free-solid-svg-icons"; | ||||||
|  | import Modal from "./Modal"; // Import your Modal component
 | ||||||
|  | import UpdateModal from "./UpdateModal"; // Import your UpdateModal component
 | ||||||
|  | import "./UserMaintance.css"; | ||||||
|  | 
 | ||||||
|  | const api = process.env.REACT_APP_API_BASE_URL; | ||||||
|  | 
 | ||||||
|  | function CustomToolbar({ apiRef, handleThreeDotsClick, handleModal }) { | ||||||
|  |   const handleGoToPage1 = () => { | ||||||
|  |     if (apiRef.current) { | ||||||
|  |       apiRef.current.setPage(1); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <GridToolbarContainer> | ||||||
|  |       <Button onClick={handleGoToPage1}>Go to page 1</Button> | ||||||
|  |       <Button onClick={handleModal}>+</Button> | ||||||
|  |     </GridToolbarContainer> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function UserMaintance() { | ||||||
|  |   const [users, setUsers] = useState([]); | ||||||
|  |   const [selectedUser, setSelectedUser] = useState(null); | ||||||
|  |   const [selectedUserForUpdate, setSelectedUserForUpdate] = useState(null); | ||||||
|  |   const [isModalOpen, setIsModalOpen] = useState(false); | ||||||
|  |   const [isUpdateModalOpen, setIsUpdateModalOpen] = useState(false); | ||||||
|  |   const [newUser, setNewUser] = useState({ | ||||||
|  |     userId: "", | ||||||
|  |     username: "", | ||||||
|  |     fullName: "", | ||||||
|  |     email: "", | ||||||
|  | 
 | ||||||
|  |     usrGrpName: "", | ||||||
|  |   }); | ||||||
|  |   const apiRef = useRef(null); | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     const fetchData = async () => { | ||||||
|  |       const token = localStorage.getItem("token"); | ||||||
|  |       console.log("object", token); | ||||||
|  |       try { | ||||||
|  |         const response = await fetch(`${api}/api/getAllAppUser`, { | ||||||
|  |           headers: { | ||||||
|  |             Authorization: `Bearer ${token}`, | ||||||
|  |           }, | ||||||
|  |         }); | ||||||
|  |         const data = await response.json(); | ||||||
|  |         const usersWithIds = data.map((user, index) => ({ | ||||||
|  |           ...user, | ||||||
|  |           id: index + 1, | ||||||
|  |         })); | ||||||
|  |         setUsers(usersWithIds); | ||||||
|  |       } catch (error) { | ||||||
|  |         console.error("Error fetching data:", error); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     fetchData(); | ||||||
|  |   }, []); | ||||||
|  | 
 | ||||||
|  |   const handleThreeDotsClick = (userId) => { | ||||||
|  |     setSelectedUser(userId === selectedUser ? null : userId); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleDelete = (userId) => { | ||||||
|  |     console.log("Delete user with ID:", userId); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleUpdate = (user) => { | ||||||
|  |     setSelectedUserForUpdate(user); | ||||||
|  |     setIsUpdateModalOpen(true); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleModal = () => { | ||||||
|  |     setIsModalOpen(true); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleModalSave = (data) => { | ||||||
|  |     setUsers((prevUsers) => [ | ||||||
|  |       ...prevUsers, | ||||||
|  |       { ...data, id: prevUsers.length + 1 }, | ||||||
|  |     ]); | ||||||
|  |     setIsModalOpen(false); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleUpdateSave = () => { | ||||||
|  |     setIsUpdateModalOpen(false); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const columns = [ | ||||||
|  |     { field: "userId", headerName: "User ID", width: 200 }, | ||||||
|  |     { field: "username", headerName: "Username", width: 200 }, | ||||||
|  |     { field: "fullName", headerName: "Full Name", width: 200 }, | ||||||
|  |     { field: "email", headerName: "Email", width: 200 }, | ||||||
|  |     { field: "usrGrpName", headerName: "User Group", width: 150 }, | ||||||
|  |     { | ||||||
|  |       field: "actions", | ||||||
|  |       headerName: "Actions", | ||||||
|  |       width: 100, | ||||||
|  |       renderCell: ({ row }) => ( | ||||||
|  |         <div> | ||||||
|  |           <div | ||||||
|  |             className="three-dots" | ||||||
|  |             onClick={() => handleThreeDotsClick(row.userId)} | ||||||
|  |           > | ||||||
|  |             <FontAwesomeIcon icon={faEllipsisV} /> | ||||||
|  |           </div> | ||||||
|  |           {selectedUser === row.userId && ( | ||||||
|  |             <div className="popover"> | ||||||
|  |               <button onClick={() => handleDelete(row.userId)}>Delete</button> | ||||||
|  |               <button onClick={() => handleUpdate(row)}>Update</button> | ||||||
|  |             </div> | ||||||
|  |           )} | ||||||
|  |         </div> | ||||||
|  |       ), | ||||||
|  |     }, | ||||||
|  |   ]; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <Box | ||||||
|  |       sx={{ height: "calc(100vh - 150px)", width: "100%", overflowX: "auto" }} | ||||||
|  |     > | ||||||
|  |       <div className="text-center text-3xl text-white bg-gray-400"> | ||||||
|  |         User Maintenance | ||||||
|  |       </div> | ||||||
|  |       <DataGrid | ||||||
|  |         className="bg-gray-400" | ||||||
|  |         rows={users} | ||||||
|  |         columns={columns} | ||||||
|  |         components={{ | ||||||
|  |           Toolbar: () => ( | ||||||
|  |             <CustomToolbar | ||||||
|  |               apiRef={apiRef} | ||||||
|  |               handleThreeDotsClick={handleThreeDotsClick} | ||||||
|  |               handleModal={handleModal} | ||||||
|  |             /> | ||||||
|  |           ), | ||||||
|  |         }} | ||||||
|  |         pageSize={10} | ||||||
|  |         onGridReady={(gridApi) => { | ||||||
|  |           apiRef.current = gridApi; | ||||||
|  |         }} | ||||||
|  |       /> | ||||||
|  |       {isModalOpen && ( | ||||||
|  |         <Modal | ||||||
|  |           setNewUser={setNewUser} | ||||||
|  |           newUser={newUser} | ||||||
|  |           onSave={handleModalSave} | ||||||
|  |           onClose={() => setIsModalOpen(false)} | ||||||
|  |         /> | ||||||
|  |       )} | ||||||
|  |       {isUpdateModalOpen && ( | ||||||
|  |         <UpdateModal | ||||||
|  |           user={selectedUserForUpdate} | ||||||
|  |           onUpdate={handleUpdateSave} | ||||||
|  |           onClose={() => setIsUpdateModalOpen(false)} | ||||||
|  |         /> | ||||||
|  |       )} | ||||||
|  |     </Box> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default UserMaintance; | ||||||
							
								
								
									
										123
									
								
								src/components/Dashboard/dashboard.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								src/components/Dashboard/dashboard.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,123 @@ | |||||||
|  | /* Global Styles */ | ||||||
|  | body { | ||||||
|  |   font-family: 'Roboto', sans-serif; | ||||||
|  |   background-color: #f4f6f8; | ||||||
|  |   color: #333; | ||||||
|  |   margin: 0; | ||||||
|  |   padding: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .dashboard { | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  |   height: 100vh; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Horizontal Navbar */ | ||||||
|  | .horizontal-navbar { | ||||||
|  |   display: flex; | ||||||
|  |   justify-content: space-between; | ||||||
|  |   align-items: center; | ||||||
|  |   background-color: #2c3e50; | ||||||
|  |   color: #ecf0f1; | ||||||
|  |   padding: 10px 20px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .horizontal-navbar h3 { | ||||||
|  |   margin: 0; | ||||||
|  |   font-size: 24px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .nav { | ||||||
|  |   display: flex; | ||||||
|  |   gap: 20px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .nav-link { | ||||||
|  |   color: #ecf0f1; | ||||||
|  |   text-decoration: none; | ||||||
|  |   font-size: 18px; | ||||||
|  |   transition: color 0.3s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .nav-link:hover { | ||||||
|  |   color: #3498db; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | button { | ||||||
|  |   background-color: #e74c3c; | ||||||
|  |   color: #ecf0f1; | ||||||
|  |   border: none; | ||||||
|  |   padding: 10px 20px; | ||||||
|  |   border-radius: 5px; | ||||||
|  |   cursor: pointer; | ||||||
|  |   transition: background-color 0.3s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | button:hover { | ||||||
|  |   background-color: #c0392b; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Content */ | ||||||
|  | .content { | ||||||
|  |   display: flex; | ||||||
|  |   flex: 1; | ||||||
|  |   overflow: hidden; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .sidebar-content-wrapper { | ||||||
|  |   display: flex; | ||||||
|  |   flex: 1; | ||||||
|  |   overflow: hidden; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Sidebar */ | ||||||
|  | .sidebar { | ||||||
|  |   width: 250px; | ||||||
|  |   background-color: #34495e; | ||||||
|  |   color: #ecf0f1; | ||||||
|  |   transition: width 0.3s; | ||||||
|  |   overflow: auto; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .sidebar.collapsed { | ||||||
|  |   width: 80px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .sidebar-content-wrapper .sidebar ul { | ||||||
|  |   list-style: none; | ||||||
|  |   padding: 0; | ||||||
|  |   margin: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .sidebar-content-wrapper .sidebar ul li { | ||||||
|  |   padding: 15px 20px; | ||||||
|  |   cursor: pointer; | ||||||
|  |   transition: background-color 0.3s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .sidebar-content-wrapper .sidebar ul li:hover { | ||||||
|  |   background-color: #2c3e50; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .sidebar-content-wrapper .sidebar ul li.active { | ||||||
|  |   background-color: #3498db; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .sidebar-content-wrapper .sidebar .toggle-btn { | ||||||
|  |   text-align: center; | ||||||
|  |   padding: 10px; | ||||||
|  |   cursor: pointer; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Main Content */ | ||||||
|  | .main-content { | ||||||
|  |   flex: 1; | ||||||
|  |   padding: 20px; | ||||||
|  |   background-color: #ecf0f1; | ||||||
|  |   overflow-y: auto; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .main-content h3 { | ||||||
|  |   margin-top: 0; | ||||||
|  | } | ||||||
							
								
								
									
										177
									
								
								src/components/Dashboard/dashboard.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								src/components/Dashboard/dashboard.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,177 @@ | |||||||
|  | import React, { useState, useEffect } from "react"; | ||||||
|  | import Sidebar from "./sidebar"; | ||||||
|  | import { useNavigate } from "react-router-dom"; | ||||||
|  | import UserMaintanceComponent from "./UserMaintance"; | ||||||
|  | import UserGroupMaintanceComponent from "./UserGroupMaintance/UserGroupMaintance"; | ||||||
|  | import MenuMaintanceComponent from "./MenuMaintance/MenuMaintance"; | ||||||
|  | import MenuAccessControlComponent from "./MenuAccessControl/MenuAccessControl"; | ||||||
|  | import SystemParametersComponent from "./SystemParameters/SystemParameters"; | ||||||
|  | import AccessTypeComponent from "./AccessType/AccessType"; | ||||||
|  | import ApiRegistery from "./ApiRegistery/ApiRegistery"; | ||||||
|  | import TokenRegistery from "./TokenRegistery/TokenRegistery"; | ||||||
|  | import HomePage from "./HomePage"; | ||||||
|  | import Setup from "./Setup.js"; | ||||||
|  | import Report from "./Report"; | ||||||
|  | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
|  | import { | ||||||
|  |   faCog, | ||||||
|  |   faUsers, | ||||||
|  |   faSignOutAlt, | ||||||
|  |   faHome, | ||||||
|  | } from "@fortawesome/free-solid-svg-icons"; | ||||||
|  | 
 | ||||||
|  | const Dashboard = () => { | ||||||
|  |   const navigate = useNavigate(); | ||||||
|  |   const [menus, setMenus] = useState([]); | ||||||
|  |   const [selectedUserMaintance, setSelectedUserMaintance] = useState(null); | ||||||
|  |   const [sidebarCollapsed, setSidebarCollapsed] = useState(false); | ||||||
|  |   const [content, setContent] = useState(""); | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     const fetchMenusData = async () => { | ||||||
|  |       const token = localStorage.getItem("token"); | ||||||
|  | 
 | ||||||
|  |       const apiUrl = `${process.env.REACT_APP_API_BASE_URL}/fndMenu/menuloadbyuser`; | ||||||
|  |       console.log("Fetching menus from API:", apiUrl); | ||||||
|  | 
 | ||||||
|  |       try { | ||||||
|  |         const response = await fetch(apiUrl, { | ||||||
|  |           headers: { | ||||||
|  |             Authorization: `Bearer ${token}`, | ||||||
|  |           }, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         if (response.ok) { | ||||||
|  |           const menuData = await response.json(); | ||||||
|  |           setMenus(menuData); | ||||||
|  |         } else { | ||||||
|  |           const errorText = await response.text(); | ||||||
|  |           console.error( | ||||||
|  |             "Failed to fetch menus. Status:", | ||||||
|  |             response.status, | ||||||
|  |             "Response:", | ||||||
|  |             errorText | ||||||
|  |           ); | ||||||
|  |         } | ||||||
|  |       } catch (error) { | ||||||
|  |         console.error("Error during menu fetch:", error); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     fetchMenusData(); | ||||||
|  |   }, [navigate]); | ||||||
|  | 
 | ||||||
|  |   const handleMenuItemClick = (menuItem) => { | ||||||
|  |     setSelectedUserMaintance(menuItem); | ||||||
|  |     setContent(menuItem.menuItemDesc); // Update content based on clicked menu item
 | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleHomeClick = () => { | ||||||
|  |     setSelectedUserMaintance(null); | ||||||
|  |     setContent("Home"); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleSetupClick = () => { | ||||||
|  |     setSelectedUserMaintance(null); | ||||||
|  |     setContent("Setup"); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleReportClick = () => { | ||||||
|  |     setSelectedUserMaintance(null); | ||||||
|  |     setContent("Report"); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleSidebarToggle = () => { | ||||||
|  |     setSidebarCollapsed(!sidebarCollapsed); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleLogout = () => { | ||||||
|  |     localStorage.removeItem("authToken"); | ||||||
|  |     localStorage.removeItem("user"); | ||||||
|  |     navigate("/"); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className="flex flex-col h-screen"> | ||||||
|  |       <div className="flex justify-between items-center bg-gray-800 text-white p-4"> | ||||||
|  |         <h3 className="text-2xl">Dashboard</h3> | ||||||
|  |         <nav className="flex space-x-4"> | ||||||
|  |           <a className="text-white" href="#" onClick={handleHomeClick}> | ||||||
|  |             <FontAwesomeIcon icon={faHome} /> | ||||||
|  |           </a> | ||||||
|  |           <a className="text-white" href="#" onClick={handleSetupClick}> | ||||||
|  |             <FontAwesomeIcon icon={faCog} /> | ||||||
|  |           </a> | ||||||
|  |           <a className="text-white" href="#" onClick={handleReportClick}> | ||||||
|  |             <FontAwesomeIcon icon={faUsers} /> | ||||||
|  |           </a> | ||||||
|  |         </nav> | ||||||
|  |         <button | ||||||
|  |           className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded" | ||||||
|  |           onClick={handleLogout} | ||||||
|  |         > | ||||||
|  |           <FontAwesomeIcon icon={faSignOutAlt} /> Logout | ||||||
|  |         </button> | ||||||
|  |       </div> | ||||||
|  | 
 | ||||||
|  |       <div className="flex flex-1 overflow-hidden"> | ||||||
|  |         <div | ||||||
|  |           className={`bg-gray-700 text-white transition-all duration-300 ${ | ||||||
|  |             sidebarCollapsed ? "w-16" : "w-64" | ||||||
|  |           } min-w-16`}
 | ||||||
|  |         > | ||||||
|  |           <div className="flex justify-center p-2"> | ||||||
|  |             <button onClick={handleSidebarToggle} className="text-white"> | ||||||
|  |               {sidebarCollapsed ? ">>" : "<<"} | ||||||
|  |             </button> | ||||||
|  |           </div> | ||||||
|  |           <Sidebar | ||||||
|  |             menus={menus} | ||||||
|  |             handleMenuItemClick={handleMenuItemClick} | ||||||
|  |             collapsed={sidebarCollapsed} | ||||||
|  |             setCollapsed={setSidebarCollapsed} | ||||||
|  |           /> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div className="flex-1 p-6 overflow-auto bg-gray-100"> | ||||||
|  |           {content === "Setup" ? ( | ||||||
|  |             <Setup /> | ||||||
|  |           ) : content === "Home" ? ( | ||||||
|  |             <HomePage /> | ||||||
|  |           ) : content === "Report" ? ( | ||||||
|  |             <Report /> | ||||||
|  |           ) : selectedUserMaintance ? ( | ||||||
|  |             <div> | ||||||
|  |               <h3 className="text-2xl mb-4"> | ||||||
|  |                 {selectedUserMaintance.menuItemDesc} | ||||||
|  |               </h3> | ||||||
|  |               {selectedUserMaintance.menuItemDesc === "User Maintance" ? ( | ||||||
|  |                 <UserMaintanceComponent /> | ||||||
|  |               ) : selectedUserMaintance.menuItemDesc === | ||||||
|  |                 "User Group Maintance" ? ( | ||||||
|  |                 <UserGroupMaintanceComponent /> | ||||||
|  |               ) : selectedUserMaintance.menuItemDesc === "Menu Maintance" ? ( | ||||||
|  |                 <MenuMaintanceComponent /> | ||||||
|  |               ) : selectedUserMaintance.menuItemDesc === | ||||||
|  |                 "Menu Access Control" ? ( | ||||||
|  |                 <MenuAccessControlComponent /> | ||||||
|  |               ) : selectedUserMaintance.menuItemDesc === "System Parameters" ? ( | ||||||
|  |                 <SystemParametersComponent /> | ||||||
|  |               ) : selectedUserMaintance.menuItemDesc === "Access Type" ? ( | ||||||
|  |                 <AccessTypeComponent /> | ||||||
|  |               ) : selectedUserMaintance.menuItemDesc === "Api Registery" ? ( | ||||||
|  |                 <ApiRegistery /> | ||||||
|  |               ) : selectedUserMaintance.menuItemDesc === "Token Registery" ? ( | ||||||
|  |                 <TokenRegistery /> | ||||||
|  |               ) : null} | ||||||
|  |             </div> | ||||||
|  |           ) : ( | ||||||
|  |             <HomePage /> | ||||||
|  |           )} | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default Dashboard; | ||||||
							
								
								
									
										62
									
								
								src/components/Dashboard/onetomany.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/components/Dashboard/onetomany.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,62 @@ | |||||||
|  | import React, { useState } from 'react'; | ||||||
|  | 
 | ||||||
|  | function App() { | ||||||
|  |   const [formData, setFormData] = useState({ | ||||||
|  |     name: '', | ||||||
|  |     test: [ | ||||||
|  |       { t1: '', t2: '' } // Initial test2
 | ||||||
|  |     ] | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   const handleChange = (e, index) => { | ||||||
|  |     const { name, value } = e.target; | ||||||
|  |     if (name === 'name') { | ||||||
|  |       setFormData({ ...formData, [name]: value }); | ||||||
|  |     } else { | ||||||
|  |       const updatedTests = [...formData.test]; | ||||||
|  |       updatedTests[index][name] = value; | ||||||
|  |       setFormData({ ...formData, test: updatedTests }); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleAddTest = () => { | ||||||
|  |     setFormData({ | ||||||
|  |       ...formData, | ||||||
|  |       test: [...formData.test, { t1: '', t2: '' }] | ||||||
|  |     }); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleSubmit = (e) => { | ||||||
|  |     e.preventDefault(); | ||||||
|  |     console.log(formData); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className="container"> | ||||||
|  |       <form onSubmit={handleSubmit}> | ||||||
|  |         <div className="form-group"> | ||||||
|  |           <label htmlFor="name">Name:</label> | ||||||
|  |           <input type="text" id="name" name="name" value={formData.name} onChange={handleChange} required /> | ||||||
|  |         </div> | ||||||
|  |         <hr /> | ||||||
|  |         <h2>Test 2</h2> | ||||||
|  |         {formData.test.map((test, index) => ( | ||||||
|  |           <div key={index}> | ||||||
|  |             <div className="form-group"> | ||||||
|  |               <label htmlFor={`t1-${index}`}>Name:</label> | ||||||
|  |               <input type="text" id={`t1-${index}`} name={`t1-${index}`} value={test.t1} onChange={(e) => handleChange(e, index)} required /> | ||||||
|  |             </div> | ||||||
|  |             <div className="form-group"> | ||||||
|  |               <label htmlFor={`t2-${index}`}>Description:</label> | ||||||
|  |               <input type="text" id={`t2-${index}`} name={`t2-${index}`} value={test.t2} onChange={(e) => handleChange(e, index)} required /> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |         ))} | ||||||
|  |         <button type="button" onClick={handleAddTest}>Add Test</button> | ||||||
|  |         <button type="submit">Submit</button> | ||||||
|  |       </form> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default App; | ||||||
							
								
								
									
										73
									
								
								src/components/Dashboard/onetoone.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								src/components/Dashboard/onetoone.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,73 @@ | |||||||
|  | import React, { useState } from 'react'; | ||||||
|  | 
 | ||||||
|  | function MyForm() { | ||||||
|  |   const [formData, setFormData] = useState({ | ||||||
|  |     name: '', | ||||||
|  |     test2: { name: '', description: '' } | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   const handleChange = (e) => { | ||||||
|  |     const { name, value } = e.target; | ||||||
|  |     setFormData({ | ||||||
|  |       ...formData, | ||||||
|  |       [name]: value | ||||||
|  |     }); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleTest2Change = (e) => { | ||||||
|  |     const { name, value } = e.target; | ||||||
|  |     setFormData({ | ||||||
|  |       ...formData, | ||||||
|  |       test2: { | ||||||
|  |         ...formData.test2, | ||||||
|  |         [name]: value | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleSubmit = (e) => { | ||||||
|  |     e.preventDefault(); | ||||||
|  |     console.log(formData); | ||||||
|  |     // we can send this data to our server
 | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <form onSubmit={handleSubmit}> | ||||||
|  |       <div> | ||||||
|  |         <label htmlFor="name">Name:</label> | ||||||
|  |         <input | ||||||
|  |           type="text" | ||||||
|  |           id="name" | ||||||
|  |           name="name" | ||||||
|  |           value={formData.name} | ||||||
|  |           onChange={handleChange} | ||||||
|  |         /> | ||||||
|  |       </div> | ||||||
|  |       <hr /> | ||||||
|  |       <h2>Test 2</h2> | ||||||
|  |       <div> | ||||||
|  |         <label htmlFor="test2Name">Name:</label> | ||||||
|  |         <input | ||||||
|  |           type="text" | ||||||
|  |           id="test2Name" | ||||||
|  |           name="name" | ||||||
|  |           value={formData.test2.name} | ||||||
|  |           onChange={handleTest2Change} | ||||||
|  |         /> | ||||||
|  |       </div> | ||||||
|  |       <div> | ||||||
|  |         <label htmlFor="test2Description">Description:</label> | ||||||
|  |         <input | ||||||
|  |           type="text" | ||||||
|  |           id="test2Description" | ||||||
|  |           name="description" | ||||||
|  |           value={formData.test2.description} | ||||||
|  |           onChange={handleTest2Change} | ||||||
|  |         /> | ||||||
|  |       </div> | ||||||
|  |       <button type="submit">Submit</button> | ||||||
|  |     </form> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default MyForm; | ||||||
							
								
								
									
										100
									
								
								src/components/Dashboard/sidebar.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								src/components/Dashboard/sidebar.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,100 @@ | |||||||
|  | /* sidebar.css */ | ||||||
|  | 
 | ||||||
|  | /* Common styles */ | ||||||
|  | .sidebar { | ||||||
|  |   width: 250px; /* Initial width */ | ||||||
|  |   height: 100%; | ||||||
|  |   background-color: #778184; | ||||||
|  |   color: #0e0e0e; | ||||||
|  |   overflow-y: auto; | ||||||
|  |   transition: width 0.3s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .sidebar.collapsed { | ||||||
|  |   width: 60px; /* Collapsed width */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .sidebar .navbar { | ||||||
|  |   display: flex; | ||||||
|  |   align-items: center; | ||||||
|  |   justify-content: space-between; | ||||||
|  |   padding: 20px; | ||||||
|  |   background-color: #5f6265; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .sidebar .navbar button { | ||||||
|  |   background: none; | ||||||
|  |   border: none; | ||||||
|  |   font-size: 1.5em; | ||||||
|  |   color: #fff; | ||||||
|  |   cursor: pointer; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .sidebar ul { | ||||||
|  |   list-style: none; | ||||||
|  |   padding: 0; | ||||||
|  |   margin: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .sidebar li { | ||||||
|  |   padding: 10px; | ||||||
|  |   cursor: pointer; | ||||||
|  |   transition: background-color 0.3s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .sidebar li:hover { | ||||||
|  |   background-color: #555; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Responsive styles */ | ||||||
|  | @media (max-width: 768px) { | ||||||
|  |   .sidebar { | ||||||
|  |     width: 60px; /* Collapsed width for smaller screens */ | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .sidebar.collapsed { | ||||||
|  |     width: 60px; /* Ensure sidebar stays collapsed on smaller screens */ | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .sidebar .navbar h2 { | ||||||
|  |     display: none; /* Hide the sidebar title on smaller screens */ | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .sidebar .navbar button { | ||||||
|  |     font-size: 1.2em; /* Reduce button size on smaller screens */ | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .sidebar li { | ||||||
|  |     padding: 8px; /* Reduce padding for menu items on smaller screens */ | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .sidebar ul { | ||||||
|  |     padding-left: 0; /* Remove left padding for nested UL on smaller screens */ | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .sidebar li div { | ||||||
|  |     display: flex; | ||||||
|  |     align-items: center; | ||||||
|  |     justify-content: space-between; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .sidebar li div svg { | ||||||
|  |     display: none; /* Hide submenu toggle icons on smaller screens */ | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .sidebar li div .submenu-icon { | ||||||
|  |     display: inline-block; /* Show submenu toggle icon as inline-block */ | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .sidebar li div .submenu-icon svg { | ||||||
|  |     margin-left: 5px; /* Add margin to submenu toggle icon */ | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .sidebar ul ul { | ||||||
|  |     display: none; /* Hide submenus by default on smaller screens */ | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .sidebar ul ul.active { | ||||||
|  |     display: block; /* Show active submenus on smaller screens */ | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										80
									
								
								src/components/Dashboard/sidebar.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/components/Dashboard/sidebar.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,80 @@ | |||||||
|  | import React, { useState } from 'react'; | ||||||
|  | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; | ||||||
|  | import { | ||||||
|  |   faAngleRight, faAngleDown, faUser, faUsers, faList, faLock, faCog, faFileAlt, faBook, faPen, faExchangeAlt, faUserShield, | ||||||
|  | } from '@fortawesome/free-solid-svg-icons'; | ||||||
|  | import './sidebar.css'; | ||||||
|  | 
 | ||||||
|  | const Sidebar = ({ menus, handleMenuItemClick }) => { | ||||||
|  |   const [collapsed, setCollapsed] = useState(true); | ||||||
|  | 
 | ||||||
|  |   // Initialize collapsedSubmenus state
 | ||||||
|  |   const [collapsedSubmenus, setCollapsedSubmenus] = useState( | ||||||
|  |     menus.reduce((acc, menu) => { | ||||||
|  |       acc[menu.moduleName] = true; | ||||||
|  |       return acc; | ||||||
|  |     }, {}) | ||||||
|  |   ); | ||||||
|  | 
 | ||||||
|  |   const handleSubmenuClick = (menuName) => { | ||||||
|  |     setCollapsedSubmenus((prevCollapsedSubmenus) => ({ | ||||||
|  |       ...prevCollapsedSubmenus, | ||||||
|  |       [menuName]: !prevCollapsedSubmenus[menuName], | ||||||
|  |     })); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className={`flex flex-col h-full ${collapsed ? 'w-16' : 'w-64'} bg-gray-800 text-white transition-all duration-300`}> | ||||||
|  |       <div className="flex items-center justify-between p-4 bg-gray-900"> | ||||||
|  |         <button onClick={() => setCollapsed(!collapsed)}> | ||||||
|  |           <FontAwesomeIcon icon={collapsed ? faAngleRight : faAngleDown} /> | ||||||
|  |         </button> | ||||||
|  |         {!collapsed && <h2 className="ml-2">Cloudnsure</h2>} | ||||||
|  |       </div> | ||||||
|  |       <ul className="flex-1 overflow-y-auto"> | ||||||
|  |         {menus.map((menu) => ( | ||||||
|  |           <li key={menu.moduleName} className="group"> | ||||||
|  |             <div | ||||||
|  |               onClick={() => handleSubmenuClick(menu.moduleName)} | ||||||
|  |               className="flex items-center p-4 cursor-pointer hover:bg-gray-700" | ||||||
|  |             > | ||||||
|  |               {/* Manually adding icons for specific menus */} | ||||||
|  |               {menu.moduleName === 'dashboard' && <FontAwesomeIcon icon={faPen} className="mr-2" />} | ||||||
|  |               {menu.moduleName === 'sec3000' && <FontAwesomeIcon icon={faLock} className="mr-2" />} | ||||||
|  |               {menu.moduleName === 'Super Admin' && <FontAwesomeIcon icon={faUserShield} className="mr-2" />} | ||||||
|  |               {menu.moduleName === 'Transaction' && <FontAwesomeIcon icon={faExchangeAlt} className="mr-2" />} | ||||||
|  |               {/* Display menu name */} | ||||||
|  |               <span className={`flex-1 ${collapsed ? 'hidden' : 'block'}`}>{menu.moduleName}</span> | ||||||
|  |               {/* Submenu toggle icon */} | ||||||
|  |               <FontAwesomeIcon icon={collapsedSubmenus[menu.moduleName] ? faAngleRight : faAngleDown} /> | ||||||
|  |             </div> | ||||||
|  |             {!collapsedSubmenus[menu.moduleName] && ( | ||||||
|  |               <ul className={`pl-8 ${collapsed ? 'hidden' : 'block'}`}> | ||||||
|  |                 {menu.subMenus.map((submenu, index) => ( | ||||||
|  |                   <li | ||||||
|  |                     key={index} | ||||||
|  |                     onClick={() => handleMenuItemClick(submenu)} | ||||||
|  |                     className="flex items-center p-2 cursor-pointer hover:bg-gray-600" | ||||||
|  |                   > | ||||||
|  |                     {/* Manually adding icons for specific submenus */} | ||||||
|  |                     {submenu.menuItemDesc === 'User Maintance' && <FontAwesomeIcon icon={faUser} className="mr-2" />} | ||||||
|  |                     {submenu.menuItemDesc === 'User Group Maintance' && <FontAwesomeIcon icon={faUsers} className="mr-2" />} | ||||||
|  |                     {submenu.menuItemDesc === 'Menu Maintance' && <FontAwesomeIcon icon={faList} className="mr-2" />} | ||||||
|  |                     {submenu.menuItemDesc === 'Menu Access Control' && <FontAwesomeIcon icon={faLock} className="mr-2" />} | ||||||
|  |                     {submenu.menuItemDesc === 'System Parameters' && <FontAwesomeIcon icon={faCog} className="mr-2" />} | ||||||
|  |                     {submenu.menuItemDesc === 'Access Type' && <FontAwesomeIcon icon={faFileAlt} className="mr-2" />} | ||||||
|  |                     {submenu.menuItemDesc === 'Document Sequence' && <FontAwesomeIcon icon={faBook} className="mr-2" />} | ||||||
|  |                     {/* Display submenu name */} | ||||||
|  |                     {submenu.menuItemDesc} | ||||||
|  |                   </li> | ||||||
|  |                 ))} | ||||||
|  |               </ul> | ||||||
|  |             )} | ||||||
|  |           </li> | ||||||
|  |         ))} | ||||||
|  |       </ul> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default Sidebar; | ||||||
							
								
								
									
										111
									
								
								src/components/Login/CreateAccount.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								src/components/Login/CreateAccount.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,111 @@ | |||||||
|  | import React, { useState } from 'react'; | ||||||
|  | import { useNavigate } from 'react-router-dom'; | ||||||
|  | import { AccountCircle, Visibility, VisibilityOff } from '@mui/icons-material'; | ||||||
|  | import './Login.css'; // Import CSS file for custom styling
 | ||||||
|  | 
 | ||||||
|  | const CreateAccountPage = () => { | ||||||
|  |   const [email, setEmail] = useState(''); | ||||||
|  |   const [password, setPassword] = useState(''); | ||||||
|  |   const [reEnterPassword, setReEnterPassword] = useState(''); | ||||||
|  |   const [avatarImage, setAvatarImage] = useState(null); | ||||||
|  |   const navigate = useNavigate(); | ||||||
|  | 
 | ||||||
|  |   const handleCreateAccount = (e) => { | ||||||
|  |     e.preventDefault(); | ||||||
|  |     // Your create account logic here
 | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleAvatarChange = (e) => { | ||||||
|  |     const file = e.target.files[0]; | ||||||
|  |     if (file) { | ||||||
|  |       const reader = new FileReader(); | ||||||
|  |       reader.onload = () => { | ||||||
|  |         setAvatarImage(reader.result); | ||||||
|  |       }; | ||||||
|  |       reader.readAsDataURL(file); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className="relative min-h-screen flex items-center justify-center bg-gray-800"> | ||||||
|  |       <div className="absolute inset-0 flex items-center justify-center"> | ||||||
|  |         <div className="text-center text-gray-200 text-9xl font-bold opacity-10"> | ||||||
|  |           CLOUDNSURE | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <div className="relative w-full max-w-md bg-white shadow-md rounded-lg p-6 z-10"> | ||||||
|  |         <div className="flex items-center justify-center mb-6"> | ||||||
|  |           <AccountCircle className="text-7xl text-gray-700" /> | ||||||
|  |         </div> | ||||||
|  |         <h2 className="text-2xl font-semibold text-center text-gray-800 mb-4">Create Account</h2> | ||||||
|  |         <form onSubmit={handleCreateAccount} className="space-y-4"> | ||||||
|  |           <div className="flex items-center justify-center"> | ||||||
|  |             <input | ||||||
|  |               accept="image/*" | ||||||
|  |               id="avatar-input" | ||||||
|  |               type="file" | ||||||
|  |               className="hidden" | ||||||
|  |               onChange={handleAvatarChange} | ||||||
|  |             /> | ||||||
|  |             <label htmlFor="avatar-input" className="cursor-pointer"> | ||||||
|  |               <img | ||||||
|  |                 alt="Avatar" | ||||||
|  |                 src={avatarImage || 'https://via.placeholder.com/120'} | ||||||
|  |                 className="w-28 h-28 rounded-full mb-4" | ||||||
|  |               /> | ||||||
|  |             </label> | ||||||
|  |           </div> | ||||||
|  |           <div> | ||||||
|  |             <label className="block text-gray-600">Email</label> | ||||||
|  |             <input | ||||||
|  |               type="email" | ||||||
|  |               value={email} | ||||||
|  |               onChange={(e) => setEmail(e.target.value)} | ||||||
|  |               className="w-full px-4 py-2 mt-2 border rounded-md focus:outline-none focus:ring focus:ring-opacity-50" | ||||||
|  |             /> | ||||||
|  |           </div> | ||||||
|  |           <div> | ||||||
|  |             <label className="block text-gray-600">Password</label> | ||||||
|  |             <input | ||||||
|  |               type="password" | ||||||
|  |               value={password} | ||||||
|  |               onChange={(e) => setPassword(e.target.value)} | ||||||
|  |               className="w-full px-4 py-2 mt-2 border rounded-md focus:outline-none focus:ring focus:ring-opacity-50" | ||||||
|  |             /> | ||||||
|  |           </div> | ||||||
|  |           <div> | ||||||
|  |             <label className="block text-gray-600">Re-enter Password</label> | ||||||
|  |             <input | ||||||
|  |               type="password" | ||||||
|  |               value={reEnterPassword} | ||||||
|  |               onChange={(e) => setReEnterPassword(e.target.value)} | ||||||
|  |               className="w-full px-4 py-2 mt-2 border rounded-md focus:outline-none focus:ring focus:ring-opacity-50" | ||||||
|  |             /> | ||||||
|  |           </div> | ||||||
|  |           <div className="text-center"> | ||||||
|  |             <button | ||||||
|  |               type="submit" | ||||||
|  |               className="w-full py-2 px-4 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring focus:ring-blue-300 transition duration-300 ease-in-out" | ||||||
|  |             > | ||||||
|  |               Create Account | ||||||
|  |             </button> | ||||||
|  |           </div> | ||||||
|  |         </form> | ||||||
|  |         <div className="mt-4 text-center"> | ||||||
|  |           <p className="text-gray-600"> | ||||||
|  |             Already have an account?{' '} | ||||||
|  |             <button | ||||||
|  |               type="button" | ||||||
|  |               onClick={() => navigate('/login')} | ||||||
|  |               className="text-blue-600 hover:underline focus:outline-none" | ||||||
|  |             > | ||||||
|  |               Log in | ||||||
|  |             </button> | ||||||
|  |           </p> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default CreateAccountPage; | ||||||
							
								
								
									
										99
									
								
								src/components/Login/ForgotPassword.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								src/components/Login/ForgotPassword.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,99 @@ | |||||||
|  | import React, { useState } from 'react'; | ||||||
|  | import { useNavigate } from 'react-router-dom'; | ||||||
|  | import { AccountCircle } from '@mui/icons-material'; | ||||||
|  | import './Login.css'; // Import CSS file for custom styling
 | ||||||
|  | 
 | ||||||
|  | const API_BASE_URL = process.env.REACT_APP_API_BASE_URL; | ||||||
|  | const API_FORGOT_PASSWORD = `${API_BASE_URL}/backend/api/resources/forgotpassword`; | ||||||
|  | 
 | ||||||
|  | const ForgotPasswordPage = () => { | ||||||
|  |   const [email, setEmail] = useState(''); | ||||||
|  |   const [message, setMessage] = useState(''); | ||||||
|  |   const [messageType, setMessageType] = useState(''); // State to manage message type for styling
 | ||||||
|  |   const navigate = useNavigate(); | ||||||
|  | 
 | ||||||
|  |   const handleSubmit = async (e) => { | ||||||
|  |     e.preventDefault(); | ||||||
|  | 
 | ||||||
|  |     try { | ||||||
|  |       const response = await fetch(API_FORGOT_PASSWORD, { | ||||||
|  |         method: 'POST', | ||||||
|  |         headers: { | ||||||
|  |           'Content-Type': 'application/json', | ||||||
|  |         }, | ||||||
|  |         body: JSON.stringify({ email }), | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       if (!response.ok) { | ||||||
|  |         const errorText = await response.text(); | ||||||
|  |         setMessage(`Reset password failed: ${errorText}`); | ||||||
|  |         setMessageType('error'); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       setMessage('Reset password email sent successfully. Please check your email.'); | ||||||
|  |       setMessageType('success'); | ||||||
|  |     } catch (error) { | ||||||
|  |       setMessage(`Error during reset password: ${error.message}`); | ||||||
|  |       setMessageType('error'); | ||||||
|  |       console.error('Error during reset password:', error); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className="relative min-h-screen flex items-center justify-center bg-gray-800"> | ||||||
|  |       <div className="absolute inset-0 flex items-center justify-center"> | ||||||
|  |         <div className="text-center text-gray-200 text-9xl font-bold opacity-10"> | ||||||
|  |           CLOUDNSURE | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <div className="relative w-full max-w-md bg-white shadow-md rounded-lg p-6 z-10"> | ||||||
|  |         <div className="flex items-center justify-center mb-6"> | ||||||
|  |           <AccountCircle className="text-7xl text-gray-700" /> | ||||||
|  |         </div> | ||||||
|  |         <h2 className="text-2xl font-semibold text-center text-gray-800 mb-4">Forgot Password</h2> | ||||||
|  |         <p className="text-center text-gray-600 mb-4"> | ||||||
|  |           Enter your email address and we'll send you a link to reset your password. | ||||||
|  |         </p> | ||||||
|  |         <form onSubmit={handleSubmit} className="space-y-4"> | ||||||
|  |           <div> | ||||||
|  |             <label className="block text-gray-600">Email</label> | ||||||
|  |             <input | ||||||
|  |               type="email" | ||||||
|  |               value={email} | ||||||
|  |               onChange={(e) => setEmail(e.target.value)} | ||||||
|  |               className="w-full px-4 py-2 mt-2 border rounded-md focus:outline-none focus:ring focus:ring-opacity-50" | ||||||
|  |               required | ||||||
|  |               autoFocus | ||||||
|  |             /> | ||||||
|  |           </div> | ||||||
|  |           <div className="text-center"> | ||||||
|  |             <button | ||||||
|  |               type="submit" | ||||||
|  |               className="w-full py-2 px-4 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring focus:ring-blue-300 transition duration-300 ease-in-out" | ||||||
|  |             > | ||||||
|  |               Reset Password | ||||||
|  |             </button> | ||||||
|  |           </div> | ||||||
|  |         </form> | ||||||
|  |         {message && ( | ||||||
|  |           <div className={`mt-4 text-center ${messageType === 'error' ? 'text-red-500' : 'text-green-500'}`}> | ||||||
|  |             {message} | ||||||
|  |           </div> | ||||||
|  |         )} | ||||||
|  |         <p className="mt-4 text-center text-gray-600"> | ||||||
|  |           Remember your password?{' '} | ||||||
|  |           <button | ||||||
|  |             type="button" | ||||||
|  |             onClick={() => navigate('/login')} | ||||||
|  |             className="text-blue-600 hover:underline focus:outline-none" | ||||||
|  |           > | ||||||
|  |             Log in | ||||||
|  |           </button> | ||||||
|  |         </p> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default ForgotPasswordPage; | ||||||
							
								
								
									
										64
									
								
								src/components/Login/Login.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/components/Login/Login.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | |||||||
|  | /* LoginPage.css */ | ||||||
|  | 
 | ||||||
|  | .login-container { | ||||||
|  |   background: linear-gradient(to bottom, #417cd5, white); /* Linear gradient from blue to white */ | ||||||
|  |   height: 100vh; /* Full viewport height */ | ||||||
|  |   display: flex; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  |    | ||||||
|  |   .login-box { | ||||||
|  |     display: flex; | ||||||
|  |     background-color: white; | ||||||
|  |     box-shadow: 0 4px 8px rgba(0,0,0,0.1); | ||||||
|  |     border-radius: 8px; | ||||||
|  |     overflow: hidden; | ||||||
|  |     height: 500px; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   .login-left { | ||||||
|  |     background-color: #31c2db; | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: column; | ||||||
|  |     justify-content: center; | ||||||
|  |     align-items: center; | ||||||
|  |     flex: 1; | ||||||
|  |     padding: 4rem; /* Padding for better spacing */ | ||||||
|  | } | ||||||
|  |    | ||||||
|  |   .login-left img { | ||||||
|  |     width: 80px; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   .login-right { | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: center; | ||||||
|  |     align-items: center; | ||||||
|  |     flex: 1; | ||||||
|  |     padding: 4rem; /* Padding for better spacing */ | ||||||
|  | } | ||||||
|  |    | ||||||
|  | .login-form { | ||||||
|  |   width: 100%; | ||||||
|  |   max-width: 400px; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  | } | ||||||
|  | .forgot-password, .create-account { | ||||||
|  |   margin-top: 1rem; /* Spacing between links and other elements */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .login-form .MuiButton-root { | ||||||
|  |   background-color: #1fcf90; | ||||||
|  |   color: white; | ||||||
|  |   margin-top: 1rem; /* Spacing at the top of the button */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .MuiAlert-root { | ||||||
|  |   margin-bottom: 1rem; /* Spacing below the alert */ | ||||||
|  | } | ||||||
|  |   .forgot-password { | ||||||
|  |     text-align: right; | ||||||
|  |     margin-top: -10px; | ||||||
|  |   } | ||||||
|  |    | ||||||
							
								
								
									
										156
									
								
								src/components/Login/Login.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								src/components/Login/Login.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,156 @@ | |||||||
|  | import React, { useState } from 'react'; | ||||||
|  | import { useNavigate } from 'react-router-dom'; | ||||||
|  | import { AccountCircle, Visibility, VisibilityOff } from '@mui/icons-material'; | ||||||
|  | import './Login.css'; // Import CSS file for custom styling
 | ||||||
|  | 
 | ||||||
|  | const API_BASE_URL = process.env.REACT_APP_API_BASE_URL; | ||||||
|  | const API_TOKEN_SESSION = `${API_BASE_URL}/token/session`; | ||||||
|  | 
 | ||||||
|  | const LoginPage = () => { | ||||||
|  |   const [email, setEmail] = useState(''); | ||||||
|  |   const [password, setPassword] = useState(''); | ||||||
|  |   const [showPassword, setShowPassword] = useState(false); | ||||||
|  |   const [rememberMe, setRememberMe] = useState(false); | ||||||
|  |   const [errorMessage, setErrorMessage] = useState(''); | ||||||
|  |   const navigate = useNavigate(); | ||||||
|  | 
 | ||||||
|  |   const handleLogin = async (e) => { | ||||||
|  |     e.preventDefault(); | ||||||
|  |     setErrorMessage(''); | ||||||
|  | 
 | ||||||
|  |     if (!email || !password) { | ||||||
|  |       setErrorMessage('Email and password are required.'); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     try { | ||||||
|  |       const response = await fetch(API_TOKEN_SESSION, { | ||||||
|  |         method: 'POST', | ||||||
|  |         headers: { | ||||||
|  |           'Content-Type': 'application/json', | ||||||
|  |         }, | ||||||
|  |         body: JSON.stringify({ email, password }), | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       if (!response.ok) { | ||||||
|  |         const errorText = await response.text(); | ||||||
|  |         console.error('Login failed:', errorText); | ||||||
|  |         setErrorMessage('Login failed. Please check your credentials.'); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       const data = await response.json(); | ||||||
|  |       console.log('Login response:', data); | ||||||
|  | 
 | ||||||
|  |       if (data.operationStatus !== 'SUCCESS') { | ||||||
|  |         console.error('Login failed:', data.operationMessage); | ||||||
|  |         setErrorMessage(data.operationMessage || 'Login failed. Please try again.'); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       localStorage.setItem('authToken', data.item.token); | ||||||
|  |       localStorage.setItem('user', JSON.stringify(data.item)); | ||||||
|  |       console.log('Token stored in local storage:', data.item.token); | ||||||
|  |       navigate('/dashboard'); | ||||||
|  |     } catch (error) { | ||||||
|  |       console.error('Error during login:', error); | ||||||
|  |       setErrorMessage('An error occurred during login. Please try again later.'); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleForgotPassword = () => { | ||||||
|  |     navigate('/ForgotPassword'); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleCreateAccount = () => { | ||||||
|  |     navigate('/CreateAccount'); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className="relative min-h-screen flex items-center justify-center bg-gray-700"> | ||||||
|  |       <div className="absolute inset-0 flex items-center justify-center"> | ||||||
|  |         <div className="text-center text-gray-100 text-9xl font-bold opacity-75"> | ||||||
|  |           CLOUDNSURE | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <div className="relative w-full max-w-md bg-white shadow-md rounded-lg p-6 z-10 "> | ||||||
|  |         <div className="flex items-center justify-center mb-6"> | ||||||
|  |           <AccountCircle className="text-7xl text-gray-700" /> | ||||||
|  |         </div> | ||||||
|  |         <h2 className="text-2xl font-semibold text-center text-gray-800 mb-4 ">Log in</h2> | ||||||
|  |         {errorMessage && <div className="mb-4 text-red-600">{errorMessage}</div>} | ||||||
|  |         <form onSubmit={handleLogin} className="space-y-4"> | ||||||
|  |           <div> | ||||||
|  |             <label className="block text-gray-600">Email</label> | ||||||
|  |             <input | ||||||
|  |               type="text" | ||||||
|  |               value={email} | ||||||
|  |               onChange={(e) => setEmail(e.target.value)} | ||||||
|  |               className="w-full px-4 py-2 mt-2 border rounded-md focus:outline-none focus:ring focus:ring-opacity-50" | ||||||
|  |             /> | ||||||
|  |           </div> | ||||||
|  |           <div> | ||||||
|  |             <label className="block text-gray-600">Password</label> | ||||||
|  |             <div className="relative"> | ||||||
|  |               <input | ||||||
|  |                 type={showPassword ? 'text' : 'password'} | ||||||
|  |                 value={password} | ||||||
|  |                 onChange={(e) => setPassword(e.target.value)} | ||||||
|  |                 className="w-full px-4 py-2 mt-2 border rounded-md focus:outline-none focus:ring focus:ring-opacity-50" | ||||||
|  |               /> | ||||||
|  |               <div className="absolute inset-y-0 right-0 pr-3 flex items-center"> | ||||||
|  |                 <button | ||||||
|  |                   type="button" | ||||||
|  |                   onClick={() => setShowPassword(!showPassword)} | ||||||
|  |                   className="" | ||||||
|  |                 > | ||||||
|  |                   {showPassword ? <VisibilityOff /> : <Visibility />} | ||||||
|  |                 </button> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |           <div className="flex items-center justify-between"> | ||||||
|  |             <label className="flex items-center"> | ||||||
|  |               <input | ||||||
|  |                 type="checkbox" | ||||||
|  |                 checked={rememberMe} | ||||||
|  |                 onChange={(e) => setRememberMe(e.target.checked)} | ||||||
|  |                 className="form-checkbox" | ||||||
|  |               /> | ||||||
|  |               <span className="ml-2 text-gray-600">Remember Me</span> | ||||||
|  |             </label> | ||||||
|  |             <button | ||||||
|  |               type="button" | ||||||
|  |               onClick={handleForgotPassword} | ||||||
|  |               className="text-sm text-blue-600 hover:underline focus:outline-none" | ||||||
|  |             > | ||||||
|  |               Forgot password? | ||||||
|  |             </button> | ||||||
|  |           </div> | ||||||
|  |           <div className="text-center"> | ||||||
|  |             <button | ||||||
|  |               type="submit" | ||||||
|  |               className="w-full py-2 px-4 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring focus:ring-blue-300" | ||||||
|  |             > | ||||||
|  |               Login | ||||||
|  |             </button> | ||||||
|  |           </div> | ||||||
|  |         </form> | ||||||
|  |         <div className="mt-4 text-center"> | ||||||
|  |           <p className="text-gray-600"> | ||||||
|  |             Don't have an account?{' '} | ||||||
|  |             <button | ||||||
|  |               type="button" | ||||||
|  |               onClick={handleCreateAccount} | ||||||
|  |               className="text-blue-600 hover:underline focus:outline-none" | ||||||
|  |             > | ||||||
|  |               Create Account | ||||||
|  |             </button> | ||||||
|  |           </p> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default LoginPage; | ||||||
							
								
								
									
										19
									
								
								src/index.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/index.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | /* src/index.css */ | ||||||
|  | @tailwind base; | ||||||
|  | @tailwind components; | ||||||
|  | @tailwind utilities; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 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; | ||||||
|  | } | ||||||
							
								
								
									
										23
									
								
								src/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/index.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | |||||||
|  | // index.js
 | ||||||
|  | import React from 'react'; | ||||||
|  | import ReactDOM from 'react-dom'; | ||||||
|  | import { BrowserRouter as Router } from 'react-router-dom'; | ||||||
|  | import { ThemeProvider, createTheme } from '@mui/material/styles'; | ||||||
|  | import App from './App'; | ||||||
|  | import './index.css'; | ||||||
|  | import ErrorBoundary from './ErrorBoundary'; | ||||||
|  | 
 | ||||||
|  | const theme = createTheme({ | ||||||
|  |   // your theme configuration
 | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | ReactDOM.render( | ||||||
|  |   <ErrorBoundary> | ||||||
|  |     <ThemeProvider theme={theme}> | ||||||
|  |       <Router> | ||||||
|  |         <App /> | ||||||
|  |       </Router> | ||||||
|  |     </ThemeProvider> | ||||||
|  |   </ErrorBoundary>, | ||||||
|  |   document.getElementById('root') | ||||||
|  | ); | ||||||
							
								
								
									
										1
									
								
								src/logo.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/logo.svg
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | <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> | ||||||
| After Width: | Height: | Size: 2.6 KiB | 
							
								
								
									
										13
									
								
								src/reportWebVitals.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/reportWebVitals.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | 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; | ||||||
							
								
								
									
										5
									
								
								src/setupTests.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/setupTests.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | // 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'; | ||||||
							
								
								
									
										11
									
								
								tailwind.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								tailwind.config.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | // tailwind.config.js
 | ||||||
|  | module.exports = { | ||||||
|  |   content: [ | ||||||
|  |     "./src/**/*.{js,jsx,ts,tsx}", // Adjust this to match your project structure
 | ||||||
|  |   ], | ||||||
|  |   theme: { | ||||||
|  |     extend: {}, | ||||||
|  |   }, | ||||||
|  |   plugins: [], | ||||||
|  | }; | ||||||
|  | 
 | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user