react
This commit is contained in:
		
							parent
							
								
									18231c4f44
								
							
						
					
					
						commit
						55c68917fc
					
				| @ -17,6 +17,7 @@ | ||||
| 
 | ||||
| */ | ||||
| --> | ||||
| 
 | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|   <head> | ||||
| @ -136,7 +137,7 @@ | ||||
|       </nav> | ||||
|       <!-- Header --> | ||||
|       <div | ||||
|         class="header bg-gradient-primary pb-8 pt-5 pt-lg-8 d-flex align-items-center" | ||||
|         class="header  pb-8 pt-5 pt-lg-8 d-flex align-items-center" | ||||
|       > | ||||
|         <!-- Header container --> | ||||
|         <div class="container-fluid"> | ||||
| @ -157,7 +158,7 @@ | ||||
|       <div class="container-fluid mt--7"> | ||||
|         <div class="row justify-content-center"> | ||||
|           <div class="col-lg-4"> | ||||
|             <div class="card bg-gradient-default text-center p-5"> | ||||
|             <div class="card  text-center p-5"> | ||||
|               <a | ||||
|                 href="https://demos.creative-tim.com/argon-dashboard-react/#/documentation/overview" | ||||
|                 class="btn btn-white btn-icon mb-3 mb-sm-0" | ||||
|  | ||||
							
								
								
									
										15
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								package.json
									
									
									
									
									
								
							| @ -1,9 +1,6 @@ | ||||
| { | ||||
|   "name": "authsec-dashboard-react", | ||||
| <<<<<<< HEAD | ||||
| ======= | ||||
|   "proxy": "http://157.66.191.31:33266", | ||||
| >>>>>>> 1c0592d (commit new code) | ||||
|   "version": "1.2.4", | ||||
|   "description": "React version of Argon Dashboard by Creative Tim", | ||||
|   "main": "index.js", | ||||
| @ -47,31 +44,32 @@ | ||||
|     "not op_mini all" | ||||
|   ], | ||||
|   "dependencies": { | ||||
|     "@ant-design/icons": "^6.0.0", | ||||
|     "@cds/core": "^6.15.1", | ||||
|     "@cds/react": "^6.15.1", | ||||
|     "@dnd-kit/core": "^6.3.1", | ||||
|     "@dnd-kit/sortable": "^10.0.0", | ||||
|     "@dnd-kit/utilities": "^3.2.2", | ||||
|     "@emotion/react": "^11.14.0", | ||||
|     "@emotion/styled": "^11.14.0", | ||||
|     "@fortawesome/fontawesome-free": "6.5.1", | ||||
|     "@fortawesome/fontawesome-svg-core": "^6.6.0", | ||||
|     "@fortawesome/free-solid-svg-icons": "^6.6.0", | ||||
|     "@fortawesome/react-fontawesome": "^0.2.2", | ||||
|     "@mui/material": "^6.4.8", | ||||
|     "@mui/icons-material": "^7.1.0", | ||||
|     "@mui/material": "^7.1.0", | ||||
|     "@mui/styled-engine": "^6.4.8", | ||||
|     "@mui/styles": "^6.4.8", | ||||
|     "ajv": "^8.16.0", | ||||
|     "antd": "^5.25.4", | ||||
|     "authsec-dashboard-react": "file:", | ||||
|     "axios": "^1.7.7", | ||||
|     "axios": "^1.9.0", | ||||
|     "bootstrap": "^4.6.0", | ||||
|     "bootstrap-icons": "^1.11.3", | ||||
|     "bootstrap-switch-button-react": "^1.2.0", | ||||
|     "chart.js": "^4.4.8", | ||||
|     "classnames": "2.3.2", | ||||
| <<<<<<< HEAD | ||||
| ======= | ||||
|     "cors-anywhere": "^0.4.4", | ||||
| >>>>>>> 1c0592d (commit new code) | ||||
|     "file-saver": "^2.0.5", | ||||
|     "moment": "2.29.4", | ||||
|     "multiselect-react-dropdown": "^2.0.25", | ||||
| @ -92,6 +90,7 @@ | ||||
|     "react-hot-toast": "^2.4.1", | ||||
|     "react-i18next": "^15.4.1", | ||||
|     "react-icons": "^5.3.0", | ||||
|     "react-image-crop": "^11.0.10", | ||||
|     "react-pro-sidebar": "^1.1.0", | ||||
|     "react-qr-reader": "^3.0.0-beta-1", | ||||
|     "react-router-dom": "6.21.1", | ||||
|  | ||||
| @ -20,7 +20,7 @@ apiClient.interceptors.request.use( | ||||
|   (config) => { | ||||
|     const token = getToken(); | ||||
|     if (token) { | ||||
|       // console.log("token: ",token);
 | ||||
|       console.log("token: ",token); | ||||
|       config.headers['Authorization'] = `Bearer ${token}`; | ||||
|     } | ||||
|     return config; | ||||
| @ -106,6 +106,18 @@ const apiService = { | ||||
|       .delete(url, options) // Pass options such as headers
 | ||||
|       .catch(handleError), // Attach error handler
 | ||||
| }; | ||||
| // Add at the bottom of APIService.js
 | ||||
| 
 | ||||
| export const getSubmenuItems = async (id) => { | ||||
|   const response = await apiService.get(`/api1/submenu1/${id}`); | ||||
|   return response.data;  | ||||
| }; | ||||
| export const addSubmenuItem = async (menuId, submenuData) => { | ||||
|   const response = await apiService.post(`/api1/menu/${menuId}/submenu`, submenuData); | ||||
|   return response.data; | ||||
| }; | ||||
| export const updateMenuItem = (id, formData) => apiService.put(`/api1/submenu1/${id}`, formData); | ||||
| export const deleteMenuItem = (id) => apiService.delete(`/api1/menu/${id}`); | ||||
| 
 | ||||
| 
 | ||||
| export default apiService; | ||||
|  | ||||
| @ -24,27 +24,71 @@ export const fetchMenuItems = async () => { | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| // export const addMenuItem = async (formData) => {
 | ||||
| //   try {
 | ||||
| //     const response = await apiService.post('/api1/Sec_menuDet', formData);
 | ||||
| //     console.log("add response: ",response.data);
 | ||||
| //     return response.data; // Return only the data part of the response
 | ||||
| //   } catch (error) {
 | ||||
| //     throw error; // Let the error be handled by the calling component
 | ||||
|      | ||||
| //   }   
 | ||||
| // }
 | ||||
| 
 | ||||
| export const addMenuItem = async (formData) => { | ||||
|   try { | ||||
|     const response = await apiService.post('/api1/Sec_menuDet', formData); | ||||
|     console.log("add response: ",response.data); | ||||
|     return response.data; // Return only the data part of the response
 | ||||
|   } catch (error) { | ||||
|     throw error; // Let the error be handled by the calling component
 | ||||
|     const payload = { | ||||
|       menuItemDesc: formData.menuItemDesc, | ||||
|       menuId: 0, | ||||
|       itemSeq: formData.itemSeq || 0, | ||||
|       moduleName: formData.moduleName || "", | ||||
|       main_menu_action_name: formData.main_menu_action_name || "#", | ||||
|       main_menu_icon_name: formData.main_menu_icon_name || "fa-circle", | ||||
|       status: formData.status === "true" | ||||
|     }; | ||||
|      | ||||
|   }    | ||||
| } | ||||
|     console.log("Final payload:", payload); | ||||
|      | ||||
|     // Remove the duplicate '/back' from the endpoint
 | ||||
|     const response = await apiService.post('/api1/Sec_menuDet/', payload); | ||||
|     return response.data; | ||||
|   } catch (error) { | ||||
|     console.error('Error adding menu item:', error); | ||||
|     throw error; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| export const updateMenuItem = async (id, formData) => { | ||||
|   try { | ||||
|     const response = await apiService.put(`/api1/submenu1/${id}`, formData); | ||||
|     console.log("update response: ",response.data); | ||||
|     // Payload with ALL required fields (never change menuItemId)
 | ||||
|     const payload = { | ||||
|       menuItemId: Number(id),  // Keep original ID
 | ||||
|       menuItemDesc: formData.menuItemDesc, | ||||
|       menuId: formData.menuId || 0, // Keep original parent ID
 | ||||
|       itemSeq: formData.itemSeq || 0, | ||||
|       moduleName: formData.moduleName || "", | ||||
|       main_menu_action_name: formData.main_menu_action_name || "#", | ||||
|       main_menu_icon_name: formData.main_menu_icon_name || "fa-circle", | ||||
|       status: formData.status === "Enable" || formData.status === true | ||||
|     }; | ||||
| 
 | ||||
|     console.log("Updating menu item #"+id, payload); | ||||
|      | ||||
|     // POST request with full payload (confirmed working)
 | ||||
|     const response = await apiService.post('/api1/Sec_menuDet/', payload); | ||||
|      | ||||
|     console.log("Update successful:", response.data); | ||||
|     return response.data; | ||||
|    | ||||
|      | ||||
|   } catch (error) { | ||||
|     console.error('Update failed:', { | ||||
|       id: id, | ||||
|       error: error.response?.data || error.message | ||||
|     }); | ||||
|     throw error; | ||||
|   } | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| export const deleteMenuItem = async (id) => { | ||||
| @ -59,7 +103,9 @@ export const deleteMenuItem = async (id) => { | ||||
| 
 | ||||
| export const getSubmenuItems = async (id) => { | ||||
|   try { | ||||
|      | ||||
|     const response = await apiService.get(`/api1/submenu1/${id}`); | ||||
|     console.log("get submenu response: ", response.data); | ||||
|     return response.data; // Return only the data part of the response
 | ||||
|   } catch (error) { | ||||
|     throw error; // Let the error be handled by the calling component
 | ||||
| @ -77,28 +123,135 @@ export const getSubmenuItems = async (id) => { | ||||
| // }
 | ||||
| 
 | ||||
| 
 | ||||
| export const addSubmenuItem = async (menuId, formData) => { | ||||
| // export const addSubmenuItem = async (menuId, formData) => {
 | ||||
| //   try {
 | ||||
| //     console.log("adding submenu item");
 | ||||
| //     console.log("menuid", menuId);
 | ||||
| 
 | ||||
| //     const response = await apiService.post(`/api1/submenu1/${menuId}`, formData);
 | ||||
| //     console.log("menuid", menuId);
 | ||||
| //     console.log("add subMenu response: ", response.data);
 | ||||
| //     return response.data; // Return only the data part of the response
 | ||||
| //   } catch (error) {
 | ||||
| //     throw error; // Let the error be handled by the calling component
 | ||||
| //   }
 | ||||
| // }
 | ||||
| 
 | ||||
| 
 | ||||
| // Update the MenuMaintenanceAPI.js to handle single object
 | ||||
| // export const addSubmenuItem = async (menuId, formData) => {
 | ||||
| //   try {
 | ||||
| //     // Convert string numbers to proper numbers
 | ||||
| //     const payload = {
 | ||||
| //       ...formData,
 | ||||
| //       menuItemId: Number(formData.menuItemId), // Convert to number
 | ||||
| //       itemSeq: Number(formData.itemSeq),       // Convert to number
 | ||||
| //       menuId: Number(menuId)                  // Ensure parent ID is number
 | ||||
| //     };
 | ||||
| 
 | ||||
| //     console.log("Final payload with converted numbers:", payload);
 | ||||
| 
 | ||||
| //     const response = await apiService.put(`/api1/submenu1`, payload, { // Changed to POST
 | ||||
| //       headers: {
 | ||||
| //         'Content-Type': 'application/json'
 | ||||
| //       }
 | ||||
| //     });
 | ||||
| 
 | ||||
| //     // Verify the response contains all required fields
 | ||||
| //     if (!response.data?.menuItemId) {
 | ||||
| //       throw new Error("Incomplete response from server");
 | ||||
| //     }
 | ||||
| 
 | ||||
| //     return response.data;
 | ||||
| //   } catch (error) {
 | ||||
| //     console.error("API Error Details:", {
 | ||||
| //       request: error.config?.data,
 | ||||
| //       response: error.response?.data
 | ||||
| //     });
 | ||||
| //     throw error;
 | ||||
| //   }
 | ||||
| // };
 | ||||
|    | ||||
| export const addSubmenuItem = async (parentMenuId, formData) => { | ||||
|   try { | ||||
|     console.log("adding submenu item"); | ||||
|     console.log("menuid", menuId); | ||||
|     // Prepare payload - same structure as main menu but with parent ID relationship
 | ||||
|     const payload = { | ||||
|       menuItemDesc: formData.menuItemDesc, | ||||
|       menuId: Number(parentMenuId), // This establishes the parent-child relationship
 | ||||
|       itemSeq: formData.itemSeq || 0, | ||||
|       moduleName: formData.moduleName || "", | ||||
|       main_menu_action_name: formData.main_menu_action_name || "#", | ||||
|       main_menu_icon_name: formData.main_menu_icon_name || "fa-circle", | ||||
|       status: formData.status === "Enable" // Convert to boolean
 | ||||
|     }; | ||||
| 
 | ||||
|     const response = await apiService.post(`/api1/submenu1/${menuId}`, formData); | ||||
|     console.log("menuid", menuId); | ||||
|     console.log("add subMenu response: ", response.data); | ||||
|     return response.data; // Return only the data part of the response
 | ||||
|     console.log("Adding submenu with payload:", payload); | ||||
|      | ||||
|     // Use the same endpoint as main menu
 | ||||
|     const response = await apiService.post('/api1/Sec_menuDet/', payload); | ||||
|      | ||||
|     return response.data; | ||||
|   } catch (error) { | ||||
|     throw error; // Let the error be handled by the calling component
 | ||||
|     console.error('Error adding submenu:', error); | ||||
|     throw error; | ||||
|   } | ||||
| } | ||||
| }; | ||||
| 
 | ||||
|          | ||||
| export const updateSubmenuItem = async (submenuId, formData) => { | ||||
|    const payload = { | ||||
|       menuItemId: Number(submenuId), // ID in the body
 | ||||
|       menuItemDesc: formData.menuItemDesc, | ||||
|       menuId: Number(formData.menuId), // Parent menu ID
 | ||||
|       itemSeq: formData.itemSeq || 0, | ||||
|       moduleName: formData.moduleName || "", | ||||
|       main_menu_action_name: formData.main_menu_action_name || "#", | ||||
|       main_menu_icon_name: formData.main_menu_icon_name || "fa-circle", | ||||
|       status: formData.status === "Enable" || formData.status === true | ||||
|     }; | ||||
|   try { | ||||
|     const payload = { | ||||
|       menuItemId: Number(submenuId), // ID in the body
 | ||||
|       menuItemDesc: formData.menuItemDesc, | ||||
|       menuId: Number(formData.menuId), // Parent menu ID
 | ||||
|       itemSeq: formData.itemSeq || 0, | ||||
|       moduleName: formData.moduleName || "", | ||||
|       main_menu_action_name: formData.main_menu_action_name || "#", | ||||
|       main_menu_icon_name: formData.main_menu_icon_name || "fa-circle", | ||||
|       status: formData.status === "Enable" || formData.status === true | ||||
|     }; | ||||
| 
 | ||||
|     console.log("Updating submenu with payload:", payload); | ||||
|      | ||||
|          | ||||
|     // Using POST with ID in body (confirmed working)
 | ||||
|     const response = await apiService.post('/api1/Sec_menuDet/', payload); | ||||
|     return response.data; | ||||
|      | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|   } catch (error) { | ||||
|     console.error('Error updating submenu:', { | ||||
|       error: error.response?.data || error.message, | ||||
|       payload: payload | ||||
|     }); | ||||
|     throw error; | ||||
|   } | ||||
| }; | ||||
| export const deleteSubmenuItem = async (submenuId) => { | ||||
|   try { | ||||
|     console.log("Deleting submenu with ID:", submenuId); | ||||
|      | ||||
|     // Using the working POST method with just menuItemId
 | ||||
|     const response = await apiService.post('/api1/Sec_menuDet/', { | ||||
|       menuItemId: Number(submenuId)  // Only sending the ID as confirmed to work
 | ||||
|     }); | ||||
|      | ||||
|     console.log("Delete successful:", response.data); | ||||
|     return response.data; | ||||
|      | ||||
|   } catch (error) { | ||||
|     console.error('Error deleting submenu:', { | ||||
|       status: error.response?.status, | ||||
|       error: error.response?.data || error.message, | ||||
|       submenuId: submenuId | ||||
|     }); | ||||
|     throw error; | ||||
|   } | ||||
| }; | ||||
							
								
								
									
										22
									
								
								src/App.js
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								src/App.js
									
									
									
									
									
								
							| @ -14,7 +14,7 @@ import "@fortawesome/fontawesome-free/css/all.min.css"; | ||||
| import "bootstrap-icons/font/bootstrap-icons.css"; | ||||
| 
 | ||||
| import "assets/scss/argon-dashboard-react.scss"; | ||||
| 
 | ||||
| import About from "views/examples/about"; | ||||
| import AdminLayout from "layouts/Admin.js"; | ||||
| import AuthLayout from "layouts/Auth.js"; | ||||
| import Profile from "views/examples/Profile"; | ||||
| @ -30,7 +30,7 @@ import AccessTypeManagement from "components/Dashboard/AccessType"; | ||||
| import APIRegistry from "components/Dashboard/APIRegistry"; | ||||
| import TOKENRegistry from "components/Dashboard/TOKENRegistry"; | ||||
| 
 | ||||
| 
 | ||||
| import Error404 from "views/examples/Error404"; | ||||
| import { ToastContainer } from "react-toastify"; | ||||
| import "react-toastify/dist/ReactToastify.css"; | ||||
| import Register from "views/examples/Register"; | ||||
| @ -60,6 +60,9 @@ import DashboardNewEdit from "./components/Dashboard/dashboardnew/DashboardnewEd | ||||
| import EditNewDash from "components/Dashboard/dashboardnew/EditNewDash/EditNewDash"; | ||||
| import ProtectedRoute from "ProtectedRoute"; | ||||
| import DashboardRunner from "components/Dashboard/dashboardRunner/dashboardRunner"; | ||||
| import Regform from "views/examples/regform"; | ||||
| import SequenceGenerator from "components/Dashboard/sequencegenerator"; | ||||
| // Inside <Routes>
 | ||||
| 
 | ||||
| const App = () => { | ||||
|   return ( | ||||
| @ -90,22 +93,28 @@ const App = () => { | ||||
|             <AdminLayout /> | ||||
|             </ProtectedRoute> | ||||
|             }> | ||||
|             <Route path="regform" element={<Regform />} /> | ||||
|             <Route path="error404" element={<Error404 />} /> | ||||
|             <Route path="resetpassword" element={<ResetPassword />} /> | ||||
|           | ||||
|             <Route path="index" element={<Index/>}/> | ||||
|             <Route path="profile" element={<Profile />} /> | ||||
|             <Route path="user-report" element={<UserDetailsView />} /> | ||||
|             <Route path="setting" element={<SetupView />} /> | ||||
|             <Route path="resetpassword" element={<ResetPassword />} /> | ||||
|            | ||||
|             {/* Dynamic Routes */} | ||||
|             <Route path="datamanagement" element={<DataManagement />} /> | ||||
|             <Route path="validationrule" element={<ValidationRule />} /> | ||||
|             <Route path="mappingrule" element={<MappingRule />} /> | ||||
|             <Route path="multidynmicbugs" element={<MultiDynamicBugs />} /> | ||||
| 
 | ||||
|             <Route path="about" element={<About />} /> | ||||
|             {/* Static Routes */} | ||||
|             <Route path="user-maintenance" element={<UserMaintenanceView />} /> | ||||
|             <Route path="menu-access-control" element={<MenuAccessControl />} /> | ||||
|              | ||||
|             <Route path="submenu/:menuItemId" element={<SubMenuMaintenance />} /> | ||||
|             <Route path="sequence-generator" element={<SequenceGenerator />} /> | ||||
|             <Route path="menu-access-control2" element={<MenuAccessControl2/>} /> | ||||
|              | ||||
|             <Route path="user-group-maintenance" element={<UserGroupMaintenance />} /> | ||||
|             <Route path="system-parameter" element={<SystemParameterForm />} /> | ||||
|             <Route path="menu-maintenance" element={<MenuMaintenance />} /> | ||||
| @ -128,7 +137,7 @@ const App = () => { | ||||
|             <Route path="dashboard-new-edit/:id" element={<DashboardNewEdit/>}/> | ||||
|             <Route path="edit-new-dash/:id" element={<EditNewDash/>}/> | ||||
|             <Route path="dashrunner/:id" element={<DashboardRunner/>}/> | ||||
| 
 | ||||
|                | ||||
|              {/* buildercomponents */} | ||||
|             | ||||
|                | ||||
| @ -137,7 +146,6 @@ const App = () => { | ||||
|           <Route path="/auth/*" element={<AuthLayout />}> | ||||
|             <Route path="login" element={<Login />} /> | ||||
|             <Route path="register" element={<Register />} /> | ||||
|             <Route path="resetpassword" element={<ResetPassword />} /> | ||||
|           </Route> | ||||
|         </Routes> | ||||
|       </BrowserRouter> | ||||
|  | ||||
| @ -931,6 +931,12 @@ pre code { | ||||
| } | ||||
| 
 | ||||
| @media (min-width: 576px) { | ||||
|   table input[type="checkbox"] { | ||||
|     position: static !important; | ||||
|     display: inline-block; | ||||
|     margin: auto; | ||||
|   } | ||||
|    | ||||
|   .col-sm { | ||||
|     flex-basis: 0; | ||||
|     flex-grow: 1; | ||||
| @ -1593,7 +1599,9 @@ pre code { | ||||
|     margin-left: 91.66667%; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .table-responsive { | ||||
|   overflow-x: auto; | ||||
| } | ||||
| .table { | ||||
|   width: 100%; | ||||
|   margin-bottom: 1rem; | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/brand/micrologo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/assets/img/brand/micrologo.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 3.5 KiB | 
							
								
								
									
										99
									
								
								src/components/ChartConfigModal.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								src/components/ChartConfigModal.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,99 @@ | ||||
| // components/ChartConfigModal.js
 | ||||
| import React, { useState, useEffect } from 'react'; | ||||
| import { | ||||
|   Dialog, DialogTitle, DialogContent, DialogActions, | ||||
|   TextField, Checkbox, FormControlLabel, Button, MenuItem | ||||
| } from '@mui/material'; | ||||
| 
 | ||||
| const ChartConfigModal = ({  | ||||
|   open,  | ||||
|   onClose,  | ||||
|   config,  | ||||
|   onSave,  | ||||
|   columns = []  | ||||
| }) => { | ||||
|   const [localConfig, setLocalConfig] = useState(config); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     setLocalConfig(config); // Reset on open
 | ||||
|   }, [config]); | ||||
| 
 | ||||
|   const handleChange = (field, value) => { | ||||
|     setLocalConfig(prev => ({ ...prev, [field]: value })); | ||||
|   }; | ||||
| 
 | ||||
|   const handleSubmit = () => { | ||||
|     onSave(localConfig); | ||||
|     onClose(); | ||||
|   }; | ||||
| 
 | ||||
|   return ( | ||||
|     <Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth> | ||||
|       <DialogTitle>Configure Chart</DialogTitle> | ||||
|       <DialogContent> | ||||
|         <TextField | ||||
|           label="Chart Title" | ||||
|           fullWidth | ||||
|           value={localConfig.title} | ||||
|           onChange={e => handleChange('title', e.target.value)} | ||||
|           margin="dense" | ||||
|         /> | ||||
|         <FormControlLabel | ||||
|           control={ | ||||
|             <Checkbox | ||||
|               checked={localConfig.showLegend} | ||||
|               onChange={e => handleChange('showLegend', e.target.checked)} | ||||
|             /> | ||||
|           } | ||||
|           label="Show Chart Legend" | ||||
|         /> | ||||
|         <FormControlLabel | ||||
|           control={ | ||||
|             <Checkbox | ||||
|               checked={localConfig.showLabel} | ||||
|               onChange={e => handleChange('showLabel', e.target.checked)} | ||||
|             /> | ||||
|           } | ||||
|           label="Show Chart Label" | ||||
|         /> | ||||
|         <TextField | ||||
|           label="Table Name" | ||||
|           fullWidth | ||||
|           value={localConfig.tableName} | ||||
|           onChange={e => handleChange('tableName', e.target.value)} | ||||
|           margin="dense" | ||||
|         /> | ||||
|         <TextField | ||||
|           select | ||||
|           label="X-Axis" | ||||
|           fullWidth | ||||
|           value={localConfig.xAxis} | ||||
|           onChange={e => handleChange('xAxis', e.target.value)} | ||||
|           margin="dense" | ||||
|         > | ||||
|           {columns.map(col => ( | ||||
|             <MenuItem key={col} value={col}>{col}</MenuItem> | ||||
|           ))} | ||||
|         </TextField> | ||||
|         <TextField | ||||
|           select | ||||
|           label="Y-Axis" | ||||
|           fullWidth | ||||
|           value={localConfig.yAxis} | ||||
|           onChange={e => handleChange('yAxis', e.target.value)} | ||||
|           margin="dense" | ||||
|         > | ||||
|           {columns.map(col => ( | ||||
|             <MenuItem key={col} value={col}>{col}</MenuItem> | ||||
|           ))} | ||||
|         </TextField> | ||||
|       </DialogContent> | ||||
|       <DialogActions> | ||||
|         <Button onClick={onClose}>Cancel</Button> | ||||
|         <Button onClick={handleSubmit} variant="contained">Save</Button> | ||||
|       </DialogActions> | ||||
|     </Dialog> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export default ChartConfigModal; | ||||
| @ -168,7 +168,7 @@ function AccessTypeManagement() { | ||||
|   }; | ||||
| 
 | ||||
|   return ( | ||||
|     <div style={{marginTop:"11rem"}}> | ||||
|     <div style={{marginTop:"1rem"}}> | ||||
|       {loading ? ( | ||||
|         <Spinner/> | ||||
|       ):( | ||||
|  | ||||
| @ -3,6 +3,13 @@ | ||||
|     border-radius: 0.8rem; | ||||
| 
 | ||||
| } | ||||
| /* Ensures checkboxes behave like regular table content */ | ||||
| .table-responsive input[type="checkbox"] { | ||||
|   position: static !important; | ||||
|   margin: 0 auto; | ||||
|   display: block; | ||||
|   vertical-align: middle; | ||||
| } | ||||
| 
 | ||||
| .thead-light{ | ||||
|      font-size: 1.1rem; | ||||
| @ -80,6 +87,7 @@ | ||||
|     padding-top: 11rem; | ||||
|     padding-bottom: 5rem;/* Adjust as needed for the space between the navbar and component */ | ||||
|     margin-top: -10rem; | ||||
|     margin-right: 2rem; | ||||
|   } | ||||
|    | ||||
| 
 | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
|   display: grid; | ||||
|   grid-template-columns: repeat(4, 1fr); /* 4 columns */ | ||||
|   gap: 15px; | ||||
|   margin-top:9rem; | ||||
|   margin-top:4rem; | ||||
|   margin-right: 2rem; | ||||
|   margin-left:2rem; | ||||
|   margin-bottom:2rem; | ||||
| @ -19,7 +19,7 @@ | ||||
| } | ||||
| 
 | ||||
| .usercard i { | ||||
|   color:#0E6591; | ||||
|   color:rgba(255, 0, 0, 0.688); | ||||
| } | ||||
| 
 | ||||
| .usercard:hover{ | ||||
| @ -28,7 +28,7 @@ | ||||
| } | ||||
| 
 | ||||
| .usercard h3{ | ||||
|   color: #0E6591; /* Change the card title color to red */ | ||||
|   color: rgba(255, 0, 0, 0.739); /* Change the card title color to red */ | ||||
|     font-family: 'GoogleFontName', sans-serif; | ||||
|     font-size: large; /* Apply the Google font */ | ||||
| } | ||||
|  | ||||
| @ -184,7 +184,7 @@ const DynamicForm2 = () => { | ||||
|   ); | ||||
| 
 | ||||
|   return ( | ||||
|     <div style={{ marginTop: "11rem" }}> | ||||
|     <div style={{ marginTop: "7rem" }}> | ||||
|       {loading ? ( | ||||
|         <Spinner /> | ||||
|       ) : ( | ||||
|  | ||||
| @ -296,7 +296,7 @@ function DynamicFormAdd() { | ||||
|    | ||||
| 
 | ||||
|   return ( | ||||
|     <div style={{ marginTop: "11rem" }}> | ||||
|     <div style={{ marginTop: "7rem" }}> | ||||
|       {loading ? ( | ||||
|        <Spinner/> | ||||
|       ) : ( | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1240,10 +1240,12 @@ const MenuAccessControl = () => { | ||||
|       if (!response.ok) { | ||||
|         throw new Error(`HTTP error! status: ${response.status}`); | ||||
|       } | ||||
|       const data = await response.json(); | ||||
|       console.log("data:", data); // Log the fetched data
 | ||||
|       setAlldata(data.items); | ||||
|       setPagination({ ...pagination, totalItems: data.totalItems }); | ||||
|       setLoading(false); // Stop loading
 | ||||
|       const data = await response.json(); | ||||
| 
 | ||||
|     } catch (error) { | ||||
|       console.error("Error fetching data:", error); | ||||
|       setLoading(false); // Stop loading in case of error
 | ||||
|  | ||||
| @ -18,7 +18,7 @@ | ||||
| //     main_menu_action_name: true,
 | ||||
| //     status: true
 | ||||
| //   });
 | ||||
| //   const [isSubMenu, setIsSubMenu] = useState(false);
 | ||||
| //   const [dd, setIsSubMenu] = useState(false);
 | ||||
| //   const [parentMenuItemId, setParentMenuItemId] = useState(null);
 | ||||
| 
 | ||||
| //   useEffect(() => {
 | ||||
| @ -70,7 +70,7 @@ | ||||
| //   const handleSubmit = (event) => {
 | ||||
| //     event.preventDefault();
 | ||||
| //     if (isEditing) {
 | ||||
| //       if (isSubMenu) {
 | ||||
| //       if (dd) {
 | ||||
| //         setSubMenuItems(subMenuItems.map(item =>
 | ||||
| //           item.menuItemId === currentMenuItem.menuItemId ? currentMenuItem : item
 | ||||
| //         ));
 | ||||
| @ -80,7 +80,7 @@ | ||||
| //         ));
 | ||||
| //       }
 | ||||
| //     } else {
 | ||||
| //       if (isSubMenu) {
 | ||||
| //       if (dd) {
 | ||||
| //         setSubMenuItems([...subMenuItems, { ...currentMenuItem, menuItemId: `ID-${subMenuItems.length + 1}` }]);
 | ||||
| //       } else {
 | ||||
| //         setMenuItems([...menuItems, { ...currentMenuItem, menuItemId: `ID-${menuItems.length + 1}` }]);
 | ||||
| @ -301,18 +301,19 @@ import { | ||||
| 
 | ||||
| 
 | ||||
| function MenuMaintenance() { | ||||
|    | ||||
|   const [menuItems, setMenuItems] = useState([]); | ||||
|   const [subMenuItems, setSubMenuItems] = useState([]); | ||||
|   const [showAddEditPopup, setShowAddEditPopup] = useState(false); | ||||
|   const [currentMenuItem, setCurrentMenuItem] = useState({ | ||||
|     menuItemDesc: "", | ||||
|     menu_id: "", | ||||
|     itemSeq: "", | ||||
|     moduleName: "", | ||||
|     main_menu_action_name: "", | ||||
|     main_menu_icon_name: "", | ||||
|     status: true, | ||||
|   }); | ||||
|   menuItemDesc: "", | ||||
|   menuId: 0, // Important: Use menuId instead of menu_id
 | ||||
|   itemSeq: "", | ||||
|   moduleName: "", | ||||
|   main_menu_action_name: "", | ||||
|   main_menu_icon_name: "", | ||||
|   status: "true" // As string to match select input
 | ||||
| }); | ||||
|   const [isEditing, setIsEditing] = useState(false); | ||||
|   const [recordsPerPage, setRecordsPerPage] = useState(10); | ||||
|   const [selectedMainMenuId, setSelectedMainMenuId] = useState(""); | ||||
| @ -390,6 +391,7 @@ function MenuMaintenance() { | ||||
|       console.log("Selected file:", file.name); // For debugging or processing
 | ||||
|     } | ||||
|   }; | ||||
| const dd = isSubMenu; // or set based on your logic
 | ||||
| 
 | ||||
|   const exportToExcel = () => { | ||||
|     const worksheet = XLSX.utils.json_to_sheet([]); | ||||
| @ -421,68 +423,93 @@ function MenuMaintenance() { | ||||
|     setSearchQuery(query); | ||||
|   }; | ||||
| 
 | ||||
|   const handleSubmit = async (event) => { | ||||
|     event.preventDefault(); | ||||
|     try { | ||||
|       if (isEditing) { | ||||
|         if (isSubMenu) { | ||||
|           setSubMenuItems( | ||||
|             subMenuItems.map((item) => | ||||
|               item.menuItemId === currentMenuItem.menuItemId | ||||
|                 ? currentMenuItem | ||||
|                 : item | ||||
|             ) | ||||
|           ); | ||||
|         } else { | ||||
|           const formData = { | ||||
|             ...currentMenuItem, // Include required fields for API payload
 | ||||
|           }; | ||||
|   // const handleSubmit = async (event) => {
 | ||||
|   //   event.preventDefault();
 | ||||
|   //   try {
 | ||||
|   //     if (isEditing) {
 | ||||
|   //       if (isSubMenu) {
 | ||||
|   //         setSubMenuItems(
 | ||||
|   //           subMenuItems.map((item) =>
 | ||||
|   //             item.menuItemId === currentMenuItem.menuItemId
 | ||||
|   //               ? currentMenuItem
 | ||||
|   //               : item
 | ||||
|   //           )
 | ||||
|   //         );
 | ||||
|   //       } else {
 | ||||
|   //         const formData = {
 | ||||
|   //           ...currentMenuItem, // Include required fields for API payload
 | ||||
|   //         };
 | ||||
| 
 | ||||
|           // Call the API to update the menu item
 | ||||
|           await updateMenuItem(currentMenuItem.menuItemId, formData); | ||||
|           setMenuItems( | ||||
|             menuItems.map((item) => | ||||
|               item.menuItemId === currentMenuItem.menuItemId | ||||
|                 ? currentMenuItem | ||||
|                 : item | ||||
|             ) | ||||
|           ); | ||||
|           toast.success("Menu item updated successfully!"); | ||||
|         } | ||||
|       } else { | ||||
|         if (isSubMenu) { | ||||
|           // const formData = {
 | ||||
|           //   ...currentMenuItem, // Include fields required for submenu creation
 | ||||
|           // };
 | ||||
|           // const addedSubMenuItem = await addSubmenuItem(parentMenuItemId, formData);
 | ||||
|           // setSubMenuItems([...subMenuItems, addedSubMenuItem]);
 | ||||
|           // toast.success("Submenu item added successfully!");
 | ||||
|           // // Local addition for submenus
 | ||||
|           // setSubMenuItems([
 | ||||
|           //   ...subMenuItems,
 | ||||
|           //   { ...currentMenuItem, menuItemId: `ID-${subMenuItems.length + 1}` },
 | ||||
|           // ]);
 | ||||
|         } else { | ||||
|           // Prepare form data for API
 | ||||
|           const formData = { | ||||
|             ...currentMenuItem, // Include required fields for API payload
 | ||||
|           }; | ||||
|   //         // Call the API to update the menu item
 | ||||
|   //         await updateMenuItem(currentMenuItem.menuItemId, formData);
 | ||||
|   //         setMenuItems(
 | ||||
|   //           menuItems.map((item) =>
 | ||||
|   //             item.menuItemId === currentMenuItem.menuItemId
 | ||||
|   //               ? currentMenuItem
 | ||||
|   //               : item
 | ||||
|   //           )
 | ||||
|   //         );
 | ||||
|   //         toast.success("Menu item updated successfully!");
 | ||||
|   //       }
 | ||||
|   //     } else {
 | ||||
|   //       if (isSubMenu) {
 | ||||
|   //         // const formData = {
 | ||||
|   //         //   ...currentMenuItem, // Include fields required for submenu creation
 | ||||
|   //         // };
 | ||||
|   //         // const addedSubMenuItem = await addSubmenuItem(parentMenuItemId, formData);
 | ||||
|   //         // setSubMenuItems([...subMenuItems, addedSubMenuItem]);
 | ||||
|   //         // toast.success("Submenu item added successfully!");
 | ||||
|   //         // // Local addition for submenus
 | ||||
|   //         // setSubMenuItems([
 | ||||
|   //         //   ...subMenuItems,
 | ||||
|   //         //   { ...currentMenuItem, menuItemId: `ID-${subMenuItems.length + 1}` },
 | ||||
|   //         // ]);
 | ||||
|   //       } else {
 | ||||
|   //         // Prepare form data for API
 | ||||
|   //         const formData = {
 | ||||
|   //           ...currentMenuItem, // Include required fields for API payload
 | ||||
|   //         };
 | ||||
| 
 | ||||
|           // Call the API to add a new menu item
 | ||||
|           const addedMenuItem = await addMenuItem(formData); | ||||
|   //         // Call the API to add a new menu item
 | ||||
|   //         const addedMenuItem = await addMenuItem(formData);
 | ||||
| 
 | ||||
|           // Update menu items with the newly added item from the API response
 | ||||
|           setMenuItems([...menuItems, addedMenuItem]); | ||||
|   //         // Update menu items with the newly added item from the API response
 | ||||
|   //         setMenuItems([...menuItems, addedMenuItem]);
 | ||||
| 
 | ||||
|           toast.success("Menu item added successfully!"); | ||||
|         } | ||||
|       } | ||||
|       setShowAddEditPopup(false); | ||||
|     } catch (error) { | ||||
|       toast.error("There was an error while submitting the API."); | ||||
|       console.error("Error in handleSubmit:", error); // Log the error for debugging
 | ||||
|   //         toast.success("Menu item added successfully!");
 | ||||
|   //       }
 | ||||
|   //     }
 | ||||
|   //     setShowAddEditPopup(false);
 | ||||
|   //   } catch (error) {
 | ||||
|   //     toast.error("There was an error while submitting the API.");
 | ||||
|   //     console.error("Error in handleSubmit:", error); // Log the error for debugging
 | ||||
|   //   }
 | ||||
|   // };
 | ||||
| 
 | ||||
| 
 | ||||
|  const handleSubmit = async (event) => { | ||||
|   event.preventDefault(); | ||||
|   try { | ||||
|     if (isEditing) { | ||||
|       // Update existing item
 | ||||
|       const updatedItem = await updateMenuItem(currentMenuItem.menuItemId, currentMenuItem); | ||||
|       setMenuItems(menuItems.map(item =>  | ||||
|         item.menuItemId === currentMenuItem.menuItemId ? updatedItem : item | ||||
|       )); | ||||
|       toast.success("Menu item updated successfully!"); | ||||
|     } else { | ||||
|       // Add new item
 | ||||
|       const addedItem = await addMenuItem(currentMenuItem); | ||||
|       setMenuItems([...menuItems, addedItem]); | ||||
|       toast.success("Menu item added successfully!"); | ||||
|     } | ||||
|   }; | ||||
|     setShowAddEditPopup(false); | ||||
|   } catch (error) { | ||||
|     toast.error(`Operation failed: ${error.message}`); | ||||
|     console.error("Submit error:", error); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
|   const handleDelete = async (menuItemId) => { | ||||
|     if (isSubMenu) { | ||||
| @ -502,7 +529,7 @@ function MenuMaintenance() { | ||||
| 
 | ||||
|   const handleSubMenuClick = (menuItemId) => { | ||||
|     // Pehle navigate karke page open karein
 | ||||
|     navigate(`/admin/sub-menu-maintenance/:menuItemId`); | ||||
|     navigate(`/admin/sub-menu-maintenance/${menuItemId}`); | ||||
| 
 | ||||
|     // Phir API logic handle karein
 | ||||
|     fetchSubMenuItems(menuItemId); | ||||
| @ -559,6 +586,8 @@ function MenuMaintenance() { | ||||
|   console.log("sliced menu", slicedMenus); // Verify the data in slicedMenus
 | ||||
| 
 | ||||
|   return ( | ||||
|      | ||||
|      | ||||
|     <div style={{ marginTop: "-20px" }}> | ||||
|       {loading ? ( | ||||
|         <Spinner /> | ||||
| @ -597,6 +626,7 @@ function MenuMaintenance() { | ||||
|                     padding: "10px 15px", | ||||
|                   }} | ||||
|                 > | ||||
|                    | ||||
|                   <FaSearch /> | ||||
|                 </InputGroup.Text> | ||||
|                 <FormControl | ||||
| @ -693,7 +723,7 @@ function MenuMaintenance() { | ||||
|                   /> | ||||
|                 </OverlayTrigger> | ||||
| 
 | ||||
|                 <OverlayTrigger | ||||
|                 {/* <OverlayTrigger | ||||
|                   placement="bottom" | ||||
|                   overlay={<Tooltip>Menu Items</Tooltip>} | ||||
|                 > | ||||
| @ -705,7 +735,7 @@ function MenuMaintenance() { | ||||
|                       color: "#747264", | ||||
|                     }} | ||||
|                   /> | ||||
|                 </OverlayTrigger> | ||||
|                 </OverlayTrigger> */} | ||||
|               </> | ||||
|             </Col> | ||||
|           </Row> | ||||
| @ -757,7 +787,7 @@ function MenuMaintenance() { | ||||
|                       ) | ||||
|                   )} | ||||
|                   <th>Actions</th> | ||||
|                   {!isSubMenu && <th>Sub-Menu</th>} | ||||
|                   {!dd && <th>Sub-Menu</th>} | ||||
|                 </tr> | ||||
|               </thead> | ||||
| 
 | ||||
| @ -770,7 +800,7 @@ function MenuMaintenance() { | ||||
|                         Object.keys(visibleColumns).filter( | ||||
|                           (key) => visibleColumns[key] | ||||
|                         ).length + | ||||
|                         (isSubMenu ? 1 : 2) | ||||
|                         (dd ? 1 : 2) | ||||
|                       } | ||||
|                       className="text-center" | ||||
|                     > | ||||
| @ -830,7 +860,7 @@ function MenuMaintenance() { | ||||
|                           }} | ||||
|                         /> | ||||
|                       </td> | ||||
|                       {!isSubMenu && ( | ||||
|                       {!dd && ( | ||||
|                         <td className="text-center"> | ||||
|                           <FontAwesomeIcon | ||||
|                             icon={faBars} | ||||
| @ -947,99 +977,151 @@ function MenuMaintenance() { | ||||
| 
 | ||||
|           {/* Add/Edit Modal */} | ||||
|           {showAddEditPopup && ( | ||||
|             <Modal | ||||
|               show={showAddEditPopup} | ||||
|               onHide={() => setShowAddEditPopup(false)} | ||||
|               centered | ||||
|             > | ||||
|               <Modal.Header> | ||||
|                 <Modal.Title> | ||||
|                   {isEditing ? "Edit Menu Item" : "Add New Menu Item"} | ||||
|                 </Modal.Title> | ||||
|                 <FontAwesomeIcon | ||||
|                   icon={faTimes} | ||||
|                   size="lg" | ||||
|                   onClick={handleClose} | ||||
|                   style={{ | ||||
|                     position: "absolute", | ||||
|                     top: "25px", | ||||
|                     right: "25px", | ||||
|                     cursor: "pointer", | ||||
|                   }} | ||||
|                 /> | ||||
|               </Modal.Header> | ||||
|               <Modal.Body> | ||||
|                 <Form onSubmit={handleSubmit}> | ||||
|                   <Form.Group controlId="menuId" className="mb-3"> | ||||
|                     <Form.Label>menuId</Form.Label> | ||||
|                     <Form.Control | ||||
|                       type="number" | ||||
|                       name="menu_id" // Updated to match the state
 | ||||
|                       value={currentMenuItem.menu_id || ""} | ||||
|                       onChange={handleInputChange} | ||||
|                       required | ||||
|                       className="custom-hover-border" | ||||
|                     /> | ||||
|                   </Form.Group> | ||||
|                   <Form.Group controlId="menuItemDesc" className="mb-3"> | ||||
|                     <Form.Label>Title</Form.Label> | ||||
|                     <Form.Control | ||||
|                       type="text" | ||||
|                       name="menuItemDesc" | ||||
|                       value={currentMenuItem.menuItemDesc || ""} | ||||
|                       onChange={handleInputChange} | ||||
|                       required | ||||
|                       className="custom-hover-border" | ||||
|                     /> | ||||
|                   </Form.Group> | ||||
|                   <Form.Group | ||||
|                     controlId="main_menu_action_name" | ||||
|                     className="mb-3" | ||||
|                   > | ||||
|                     <Form.Label>Link</Form.Label> | ||||
|                     <Form.Control | ||||
|                       type="text" | ||||
|                       name="main_menu_action_name" | ||||
|                       value={currentMenuItem.main_menu_action_name || ""} | ||||
|                       onChange={handleInputChange} | ||||
|                       required | ||||
|                       className="custom-hover-border" | ||||
|                     /> | ||||
|                   </Form.Group> | ||||
|                   <Form.Group controlId="status" className="mb-3"> | ||||
|                     <Form.Label>Status</Form.Label> | ||||
|                     <Form.Select | ||||
|                       name="status" | ||||
|                       value={currentMenuItem.status ? "true" : "false"} | ||||
|                       onChange={handleInputChange} | ||||
|                       required | ||||
|                       className="custom-checkbox:checked" | ||||
|                     > | ||||
|                       <option value="">Select Status</option> | ||||
|                       <option value="true">Enable</option> | ||||
|                       <option value="false">Disable</option> | ||||
|                     </Form.Select> | ||||
|                   </Form.Group> | ||||
|                   <Modal.Footer> | ||||
|                     <Button | ||||
|                       variant="primary" | ||||
|                       onClick={() => setShowAddEditPopup(false)} | ||||
|                       className="custom_button" | ||||
|                     > | ||||
|                       Close | ||||
|                     </Button> | ||||
|                     <Button | ||||
|                       type="submit" | ||||
|                       variant="primary" | ||||
|                       className="custom_button" | ||||
|                     > | ||||
|                       {isEditing ? "Update Item" : "Add Item"} | ||||
|                     </Button> | ||||
|                   </Modal.Footer> | ||||
|                 </Form> | ||||
|               </Modal.Body> | ||||
|             </Modal> | ||||
|           )} | ||||
|   <Modal | ||||
|     show={showAddEditPopup} | ||||
|     onHide={() => setShowAddEditPopup(false)} | ||||
|     centered | ||||
|     size="lg" | ||||
|   > | ||||
|     <Modal.Header> | ||||
|       <Modal.Title> | ||||
|         {isEditing ? "Edit Menu Item" : "Add New Menu Item"} | ||||
|       </Modal.Title> | ||||
|       <FontAwesomeIcon | ||||
|         icon={faTimes} | ||||
|         size="lg" | ||||
|         onClick={handleClose} | ||||
|         style={{ | ||||
|           position: "absolute", | ||||
|           top: "25px", | ||||
|           right: "25px", | ||||
|           cursor: "pointer", | ||||
|         }} | ||||
|       /> | ||||
|     </Modal.Header> | ||||
|     <Modal.Body> | ||||
|       <Form onSubmit={handleSubmit}> | ||||
|         <Row> | ||||
|           {/* Menu ID (Fixed at 0) */} | ||||
|           <Col md={6}> | ||||
|             <Form.Group controlId="menuId" className="mb-3"> | ||||
|               <Form.Label>Menu ID*</Form.Label> | ||||
|               <Form.Control | ||||
|                 type="number" | ||||
|                 name="menuId" | ||||
|                 value={0} | ||||
|                 readOnly | ||||
|                 plaintext | ||||
|                 className="form-control-plaintext" | ||||
|               /> | ||||
|             </Form.Group> | ||||
|           </Col> | ||||
|            | ||||
|           {/* Menu Item Name */} | ||||
|           <Col md={6}> | ||||
|             <Form.Group controlId="menuItemDesc" className="mb-3"> | ||||
|               <Form.Label>Menu Item Name*</Form.Label> | ||||
|               <Form.Control | ||||
|                 type="text" | ||||
|                 name="menuItemDesc" | ||||
|                 value={currentMenuItem.menuItemDesc || ""} | ||||
|                 onChange={handleInputChange} | ||||
|                 required | ||||
|               /> | ||||
|             </Form.Group> | ||||
|           </Col> | ||||
|         </Row> | ||||
| 
 | ||||
|         <Row> | ||||
|           {/* Sequence */} | ||||
|           <Col md={6}> | ||||
|             <Form.Group controlId="itemSeq" className="mb-3"> | ||||
|               <Form.Label>Sequence</Form.Label> | ||||
|               <Form.Control | ||||
|                 type="number" | ||||
|                 name="itemSeq" | ||||
|                 value={currentMenuItem.itemSeq || ""} | ||||
|                 onChange={handleInputChange} | ||||
|               /> | ||||
|             </Form.Group> | ||||
|           </Col> | ||||
|            | ||||
|           {/* Module Name */} | ||||
|           <Col md={6}> | ||||
|             <Form.Group controlId="moduleName" className="mb-3"> | ||||
|               <Form.Label>Module Name</Form.Label> | ||||
|               <Form.Control | ||||
|                 type="text" | ||||
|                 name="moduleName" | ||||
|                 value={currentMenuItem.moduleName || ""} | ||||
|                 onChange={handleInputChange} | ||||
|               /> | ||||
|             </Form.Group> | ||||
|           </Col> | ||||
|         </Row> | ||||
| 
 | ||||
|         <Row> | ||||
|           {/* Menu Action Link */} | ||||
|           <Col md={6}> | ||||
|             <Form.Group controlId="main_menu_action_name" className="mb-3"> | ||||
|               <Form.Label>Menu Action Link</Form.Label> | ||||
|               <Form.Control | ||||
|                 type="text" | ||||
|                 name="main_menu_action_name" | ||||
|                 value={currentMenuItem.main_menu_action_name || ""} | ||||
|                 onChange={handleInputChange} | ||||
|               /> | ||||
|             </Form.Group> | ||||
|           </Col> | ||||
|            | ||||
|           {/* Menu Icon Name */} | ||||
|           <Col md={6}> | ||||
|             <Form.Group controlId="main_menu_icon_name" className="mb-3"> | ||||
|               <Form.Label>Menu Icon Name</Form.Label> | ||||
|               <Form.Control | ||||
|                 type="text" | ||||
|                 name="main_menu_icon_name" | ||||
|                 value={currentMenuItem.main_menu_icon_name || ""} | ||||
|                 onChange={handleInputChange} | ||||
|                 placeholder="e.g., fa-home" | ||||
|               /> | ||||
|             </Form.Group> | ||||
|           </Col> | ||||
|         </Row> | ||||
| 
 | ||||
|         {/* Status */} | ||||
|         <Form.Group controlId="status" className="mb-3"> | ||||
|           <Form.Label>Status</Form.Label> | ||||
|           <Form.Select | ||||
|             name="status" | ||||
|             value={currentMenuItem.status ? "true" : "false"} | ||||
|             onChange={handleInputChange} | ||||
|           > | ||||
|             <option value="true">Enable</option> | ||||
|             <option value="false">Disable</option> | ||||
|           </Form.Select> | ||||
|         </Form.Group> | ||||
| 
 | ||||
|         <Modal.Footer> | ||||
|           <Button | ||||
|             variant="secondary" | ||||
|             onClick={() => setShowAddEditPopup(false)} | ||||
|             className="me-2" | ||||
|           > | ||||
|             CANCEL | ||||
|           </Button> | ||||
|           <Button | ||||
|             type="submit" | ||||
|             variant="primary" | ||||
|           > | ||||
|             {isEditing ? "UPDATE" : "ADD"} | ||||
|           </Button> | ||||
|         </Modal.Footer> | ||||
|       </Form> | ||||
|     </Modal.Body> | ||||
|   </Modal> | ||||
| )} | ||||
|            | ||||
|         </div> | ||||
|       )} | ||||
|     </div> | ||||
|  | ||||
| @ -322,78 +322,74 @@ const ReportBuild2All = () => { | ||||
|                     {visibleColumns.action && <th className="text-center">Action</th>} | ||||
|                   </tr> | ||||
|                 </thead> | ||||
| 
 | ||||
|                 <tbody className="tbody"> | ||||
|                   {filteredData.length === 0 ? ( | ||||
|                     <tr> | ||||
|                       <td | ||||
|                         colSpan={ | ||||
|                           Object.values(visibleColumns).filter(Boolean).length | ||||
|                         } | ||||
|                         className="text-center" | ||||
|                       > | ||||
|                         No data available | ||||
|                       </td> | ||||
|                     </tr> | ||||
|                   ) : ( | ||||
|                     filteredData.filter((user) => user.isSql === false).map((user) => ( | ||||
|                       <tr key={user.id}> | ||||
|                         {visibleColumns.goTo && ( | ||||
|                           <td> | ||||
|                             <Badge | ||||
|                               color="primary" | ||||
|                               pill | ||||
|                               style={{ | ||||
|                                 cursor: "pointer", | ||||
|                                 padding: "0.5em 1em", | ||||
|                                 fontSize: "0.9rem", | ||||
|                                 textTransform: "uppercase", | ||||
|                               }} | ||||
|                               onClick={() => goToLines(user)} | ||||
|                             > | ||||
|                               Set Up | ||||
|                             </Badge> | ||||
|                           </td> | ||||
|                         )} | ||||
|                         {visibleColumns.reportName && <td>{user.reportName}</td>} | ||||
|                         {visibleColumns.description && <td>{user.description}</td>} | ||||
|                         {visibleColumns.active && ( | ||||
|                           <td | ||||
|                             style={{ | ||||
|                               fontWeight: user.active ? "bold" : "normal", | ||||
|                               color: user.active ? "green" : "red", | ||||
|                               backgroundColor: user.active | ||||
|                                 ? "rgba(0, 128, 0, 0.1)" | ||||
|                                 : "rgba(255, 0, 0, 0.1)", | ||||
|                               padding: "2px 4px", | ||||
|                               display: "inline-block", | ||||
|                               borderRadius: "4px", | ||||
|                               textAlign: "center", | ||||
|                               marginTop: "10px", | ||||
|                               alignItems: "center", | ||||
|                               justifyContent: "center", | ||||
|                             }} | ||||
|                           > | ||||
|                             {user.active ? "Yes" : "No"} | ||||
|                           </td> | ||||
|                         )} | ||||
|                         {visibleColumns.action && ( | ||||
|                           <td> | ||||
|                             <FontAwesomeIcon | ||||
|                               icon={faTrash} | ||||
|                               onClick={(e) => confirmDelete(e, user)} | ||||
|                               style={{ | ||||
|                                 cursor: "pointer", | ||||
|                                 fontSize: "1rem", | ||||
|                                 color: "red", | ||||
|                                 marginRight: "15px", | ||||
|                               }} | ||||
|                             /> | ||||
|                           </td> | ||||
|                         )} | ||||
|                     {filteredData.length === 0 ? ( | ||||
|                       <tr> | ||||
|                         <td | ||||
|                           colSpan={Object.values(visibleColumns).filter(Boolean).length} | ||||
|                           className="text-center" | ||||
|                         > | ||||
|                           No data available | ||||
|                         </td> | ||||
|                       </tr> | ||||
|                     )) | ||||
|                   )} | ||||
|                 </tbody> | ||||
|                     ) : ( | ||||
|                       filteredData.filter(user => user.isSql === false).map(user => ( | ||||
|                         <tr key={user.id}> | ||||
|                           {visibleColumns.goTo && ( | ||||
|                             <td> | ||||
|                               <Badge | ||||
|                                 color="primary" | ||||
|                                 pill | ||||
|                                 style={{ | ||||
|                                   cursor: "pointer", | ||||
|                                   padding: "0.5em 1em", | ||||
|                                   fontSize: "0.9rem", | ||||
|                                   textTransform: "uppercase", | ||||
|                                 }} | ||||
|                                 onClick={() => goToLines(user)} | ||||
|                               > | ||||
|                                 Set Up | ||||
|                               </Badge> | ||||
|                             </td> | ||||
|                           )} | ||||
|                           {visibleColumns.reportName && <td>{user.reportName}</td>} | ||||
|                           {visibleColumns.description && <td>{user.description}</td>} | ||||
|                           {visibleColumns.active && ( | ||||
|                             <td | ||||
|                               style={{ | ||||
|                                 fontWeight: user.active ? "bold" : "normal", | ||||
|                                 color: user.active ? "green" : "red", | ||||
|                                 backgroundColor: user.active ? "rgba(0, 128, 0, 0.1)" : "rgba(255, 0, 0, 0.1)", | ||||
|                                 padding: "2px 4px", | ||||
|                                 display: "inline-block", | ||||
|                                 borderRadius: "4px", | ||||
|                                 textAlign: "center", | ||||
|                                 marginTop: "10px", | ||||
|                               }} | ||||
|                             > | ||||
|                               {user.active ? "Yes" : "No"} | ||||
|                             </td> | ||||
|                           )} | ||||
|                           {visibleColumns.action && ( | ||||
|                             <td> | ||||
|                               <FontAwesomeIcon | ||||
|                                 icon={faTrash} | ||||
|                                 onClick={(e) => confirmDelete(e, user)} | ||||
|                                 style={{ | ||||
|                                   cursor: "pointer", | ||||
|                                   fontSize: "1rem", | ||||
|                                   color: "red", | ||||
|                                   marginRight: "15px", | ||||
|                                 }} | ||||
|                               /> | ||||
|                             </td> | ||||
|                           )} | ||||
|                         </tr> | ||||
|                       )) | ||||
|                     )} | ||||
|                   </tbody> | ||||
| 
 | ||||
|               </Table> | ||||
|             )} | ||||
| 
 | ||||
|  | ||||
| @ -464,14 +464,16 @@ function UserDetailsView() { | ||||
|         responsive | ||||
|         hover | ||||
|         className=" align-middle table-flush shadow-sm" | ||||
|          | ||||
|       > | ||||
|         <thead className="custom_header "> | ||||
|           <tr> | ||||
|             <th className="text-center">Go To</th> | ||||
|             <th className="text-center">Report Name</th> | ||||
|             <th className="text-center">Description</th> | ||||
|             <th className="text-center">Status</th> | ||||
|             <th className="text-center">Actions</th> | ||||
|             <th className="text-center">Go To</th> | ||||
|              | ||||
|           </tr> | ||||
|         </thead> | ||||
|         <tbody className="tbody"> | ||||
| @ -489,6 +491,20 @@ function UserDetailsView() { | ||||
|                 style={{ cursor: "pointer" }} | ||||
|                 onClick={() => handleRowClick(detail)} | ||||
|               > | ||||
|                 <td className="text-center"> | ||||
|                   <FontAwesomeIcon | ||||
|                     icon={faCogs} | ||||
|                     onClick={(e) => { | ||||
|                       e.stopPropagation(); // Prevent row click event
 | ||||
|                       handleGoTo(detail); | ||||
|                     }} | ||||
|                     style={{ | ||||
|                       cursor: "pointer", | ||||
|                       fontSize: "1.2rem", | ||||
|                       color: "#0E6591", | ||||
|                     }} | ||||
|                   /> | ||||
|                 </td> | ||||
|                 <td>{detail.reportName}</td> | ||||
|                 <td>{detail.description || "No description available"}</td> | ||||
|                 <td | ||||
| @ -532,20 +548,7 @@ function UserDetailsView() { | ||||
|                     }} | ||||
|                   /> | ||||
|                 </td> | ||||
|                 <td className="text-center"> | ||||
|                   <FontAwesomeIcon | ||||
|                     icon={faCogs} | ||||
|                     onClick={(e) => { | ||||
|                       e.stopPropagation(); // Prevent row click event
 | ||||
|                       handleGoTo(detail); | ||||
|                     }} | ||||
|                     style={{ | ||||
|                       cursor: "pointer", | ||||
|                       fontSize: "1.2rem", | ||||
|                       color: "#0E6591", | ||||
|                     }} | ||||
|                   /> | ||||
|                 </td> | ||||
|                  | ||||
|               </tr> | ||||
|             )) | ||||
|           )} | ||||
|  | ||||
| @ -38,161 +38,60 @@ function SetupView({ | ||||
|         <Spinner /> // Display the spinner while loading
 | ||||
|       ) : ( | ||||
|         <div className="usercards-container"> | ||||
|           <div className="usercards"> | ||||
|             <div | ||||
|               className="usercard" | ||||
|               onClick={() => { | ||||
|                 console.log("User Maintenance card clicked"); | ||||
|                 console.log("Navigating to:", "/admin/user-maintenance"); | ||||
| 
 | ||||
|                 navigate("/admin/user-maintenance"); | ||||
|               }} | ||||
|             // onClick={onUserMaintenanceClick}
 | ||||
|             > | ||||
|               <i className="fa fa-user-cog card-icon"></i> | ||||
|               <h3>User Maintenance</h3> | ||||
|               <p>Content for Card 1</p> | ||||
|             </div> | ||||
|             <div | ||||
|               className="usercard" | ||||
|               onClick={() => { | ||||
|                 navigate("/admin/menu-access-control"); | ||||
|                 // navigate("/admin/menu-access-control2")
 | ||||
|               }} | ||||
|             > | ||||
|               <i className="fa-solid fa-lock"></i> | ||||
|               <h3>Menu Access Control</h3> | ||||
|               <p>Content for Card 2</p> | ||||
|             </div> | ||||
|             <div className="usercard" onClick={() => { | ||||
|               navigate("/admin/user-Group-Maintenance"); | ||||
|             }}> | ||||
|               <i className="fa-solid fa-users"></i> | ||||
|               <h3>User Group Maintenance</h3> | ||||
|               <p>Content for Card 3</p> | ||||
|             </div> | ||||
|             <div className="usercard" onClick={() => { | ||||
|               navigate("/admin/system-parameter"); | ||||
|             }}> | ||||
|               <i className="fa-solid fa-gears"></i> | ||||
|               <h3>System Parameter</h3> | ||||
|               <p>Content for Card 4</p> | ||||
|             </div> | ||||
|             <div className="usercard" onClick={() => { | ||||
|               navigate("/admin/menu-maintenance"); | ||||
|             }}> | ||||
|               <i className="fa-solid fa-utensils"></i> | ||||
|               <h3>Menu Maintenance</h3> | ||||
|               <p>Content for Card 5</p> | ||||
|             </div> | ||||
|             <div className="usercard" onClick={() => { | ||||
|               navigate("/admin/access-type"); | ||||
|             }}> | ||||
|               <i className="fa-solid fa-key"></i> | ||||
|               <h3>Access Type</h3> | ||||
|               <p>Content for Card 6</p> | ||||
|             </div> | ||||
|             <div className="usercard" onClick={() => { | ||||
|               navigate("/admin/api-registry") | ||||
|             }}> | ||||
|               <i className="fas fa-database"></i> | ||||
|               <h3>API Registry</h3> | ||||
|               <p>Content for Card 7</p> | ||||
|             </div> | ||||
|             <div className="usercard" onClick={() => { | ||||
|               navigate("/admin/token-registry") | ||||
|             }}> | ||||
|               <i className="fas fa-key"></i> | ||||
|               <h3>Token Registry</h3> | ||||
|               <p>Content for Card 8</p> | ||||
|             </div> | ||||
|             {/* <div className="usercard" onClick={()=>{ | ||||
|           navigate("/admin/datatype-1") | ||||
|         }}> | ||||
|           <i className="fa fa-file"></i> | ||||
|           <h3>DATATYPE1</h3> | ||||
|           <p>Content for Card 9</p> | ||||
|         </div> | ||||
|         <div className="usercard" onClick={()=>{ | ||||
|           navigate("/admin/datatype-2") | ||||
|         }}> | ||||
|           <i className="fa fa-file"></i> | ||||
|           <h3>DATATYPE2</h3> | ||||
|           <p>Content for Card 10</p> | ||||
|         </div> | ||||
|         <div className="usercard" onClick={()=>{ | ||||
|           navigate("/admin/datatype-3") | ||||
|         }}> | ||||
|           <i className="fa fa-file"></i> | ||||
|           <h3>DATATYPE3</h3> | ||||
|           <p>Content for Card 11</p> | ||||
|         </div> | ||||
|         <div className="usercard" onClick={()=>{ | ||||
|           navigate("/admin/datatype-4") | ||||
|         }}> | ||||
|           <i className="fa fa-file"></i> | ||||
|           <h3>DATATYPE4</h3> | ||||
|           <p>Content for Card 12</p> | ||||
|         </div> | ||||
|         <div className="usercard"onClick={()=>{ | ||||
|           navigate("/admin/datatype-5") | ||||
|         }}> | ||||
|           <i className="fa fa-file"></i> | ||||
|           <h3>DATATYPE5</h3> | ||||
|           <p>Content for Card 13</p> | ||||
|         </div> | ||||
|         <div className="usercard" onClick={()=>{ | ||||
|           navigate("/admin/datatype-6") | ||||
|         }}> | ||||
|           <i className="fa fa-file"></i> | ||||
|           <h3>DATATYPE6</h3> | ||||
|           <p>Content for Card 14</p> | ||||
|         </div> | ||||
|         <div className="usercard" onClick={()=>{ | ||||
|           navigate("/admin/basics-datatypes") | ||||
|         }}> | ||||
|           <i className="fa fa-file"></i> | ||||
|           <h3>Basics Datatypes</h3> | ||||
|           <p>Content for Card 15</p> | ||||
|         </div> | ||||
|         <div className="usercard" onClick={()=>{ | ||||
|           navigate("/admin/advance-datatypes") | ||||
|         }}> | ||||
|           <i className="fa fa-file"></i> | ||||
|           <h3>Advanced Datatypes</h3> | ||||
|           <p>Content for Card 16</p> | ||||
|         </div> | ||||
|         <div className="usercard" onClick={()=>{ | ||||
|           navigate("/admin/advance-datatypes2") | ||||
|         }}> | ||||
|           <i className="fa fa-file"></i> | ||||
|           <h3>Advanced Datatypes 2</h3> | ||||
|           <p>Content for Card 17</p> | ||||
|         </div> | ||||
|         <div className="usercard" onClick={()=>{ | ||||
|           navigate("/admin/premium-datatypes") | ||||
|         }}> | ||||
|           <i className="fa fa-file"></i> | ||||
|           <h3>Premium Datatypes</h3> | ||||
|           <p>Content for Card 18</p> | ||||
|         </div> */} | ||||
|             <div className="usercard" onClick={() => { | ||||
|               navigate("/admin/user-report") | ||||
|             }}> | ||||
|               <i className="fa fa-file"></i> | ||||
|               <h3>Reports</h3> | ||||
|               <p>Report Description</p> | ||||
|             </div> | ||||
|             <div className="usercard" onClick={() => { | ||||
|               navigate("/admin/dynamic-form") | ||||
|             }}> | ||||
|               <i className="fa fa-file"></i> | ||||
|               <h3>DynamicForm</h3> | ||||
|               <p>Content for Card 16</p> | ||||
|             </div> | ||||
| 
 | ||||
|           </div> | ||||
|         </div> | ||||
|          <div className="usercards"> | ||||
|   <div className="usercard" onClick={() => navigate("/admin/user-maintenance")}> | ||||
|     <i className="fa fa-user-cog card-icon"></i> | ||||
|     <h3>User Maintenance</h3> | ||||
|     <p>User Maintainance</p> | ||||
|   </div> | ||||
|   <div className="usercard" onClick={() => navigate("/admin/user-Group-Maintenance")}> | ||||
|     <i className="fa-solid fa-users"></i> | ||||
|     <h3>User Group Maintenance</h3> | ||||
|     <p>User Group Maintenance</p> | ||||
|   </div> | ||||
|   <div className="usercard" onClick={() => navigate("/admin/menu-maintenance")}> | ||||
|     <i className="fa-solid fa-utensils"></i> | ||||
|     <h3>Menu Maintenance</h3> | ||||
|     <p>Menu Maintenance</p> | ||||
|   </div> | ||||
|   <div className="usercard" onClick={() => navigate("/admin/menu-access-control")}> | ||||
|     <i className="fa-solid fa-lock"></i> | ||||
|     <h3>Menu Access Control</h3> | ||||
|     <p>Menu Access Control</p> | ||||
|   </div> | ||||
|   <div className="usercard" onClick={() => navigate("/admin/system-parameter")}> | ||||
|     <i className="fa-solid fa-gears"></i> | ||||
|     <h3>System Parameter</h3> | ||||
|     <p>System Parameter</p> | ||||
|   </div> | ||||
|   <div className="usercard" onClick={() => navigate("/admin/access-type")}> | ||||
|     <i className="fa-solid fa-key"></i> | ||||
|     <h3>Access Type</h3> | ||||
|     <p>Access Type</p> | ||||
|   </div> | ||||
|   <div className="usercard" onClick={() => navigate("/admin/sequence-generator")}> | ||||
|   <i className="fa-solid fa-list-ol"></i> | ||||
|   <h3>Document Sequence</h3> | ||||
|   <p>Manage document sequences</p> | ||||
| </div> | ||||
| <div className="usercard" onClick={() => navigate("/admin/user-report")}> | ||||
|     <i className="fa fa-file"></i> | ||||
|     <h3>Reports</h3> | ||||
|     <p>Reports Description</p> | ||||
|   </div> | ||||
|   <div className="usercard" onClick={() => navigate("/admin/api-registry")}> | ||||
|     <i className="fas fa-database"></i> | ||||
|     <h3>API Registry</h3> | ||||
|     <p>API Registry</p> | ||||
|   </div> | ||||
|   <div className="usercard" onClick={() => navigate("/admin/token-registry")}> | ||||
|     <i className="fas fa-database"></i> | ||||
|     <h3>Token Registry</h3> | ||||
|     <p>Token Registry</p> | ||||
|   </div> | ||||
|    | ||||
| </div> | ||||
| </div> | ||||
|       )} | ||||
|     </div> | ||||
| 
 | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -144,15 +144,230 @@ | ||||
| 
 | ||||
| // export default SystemParameterForm;
 | ||||
| 
 | ||||
| // import React, { useState, useEffect } from "react";
 | ||||
| // import { Button, Form, Container, Row, Col } from "react-bootstrap";
 | ||||
| // import "bootstrap/dist/css/bootstrap.min.css";
 | ||||
| // import "../Dashboard/CSS/CSS/CommonStyle.css";
 | ||||
| // import { toast } from "react-toastify";
 | ||||
| // import Spinner from "../../UIComponants/Spinner";
 | ||||
| // import {getSysParameter,addSysParameter} from "../../APIServices/SystemparameterApi";
 | ||||
| // import { useSystemParameters } from "../../context/SystemParameterContext"; // update the path if needed
 | ||||
| 
 | ||||
| //   const [loading, setLoading] = useState(true);
 | ||||
| 
 | ||||
| // const [formData, setFormData] = useState({
 | ||||
| //   schedulerTime: "",
 | ||||
| //   leaseTaxCode: "",
 | ||||
| //   vesselConfProcessLimit: "",
 | ||||
| //   rowToDisplay: "",
 | ||||
| //   linkToDisplay: "",
 | ||||
| //   rowToAdd: "",
 | ||||
| //   lovRowToDisplay: "",
 | ||||
| //   lovLinkToDisplay: "",
 | ||||
| //   oidserverName: "",
 | ||||
| //   oidBase: "",
 | ||||
| //   oidAdminUser: "",
 | ||||
| //   oidServerPort: "",
 | ||||
| //   userDefaultGroup: "",
 | ||||
| //   defaultDepartment: "",
 | ||||
| //   defaultPosition: "",
 | ||||
| //   singleCharge: "",
 | ||||
| //   firstDayOftheWeek: "",
 | ||||
| //   hourPerShift: "",
 | ||||
| //   cnBillingFrequency: "",
 | ||||
| //   billingDepartmentCode: "",
 | ||||
| //   basePriceList: "",
 | ||||
| //   nonContainerServiceOrder: "",
 | ||||
| //   ediMaeSchedulerONOFF: "",
 | ||||
| //   ediSchedulerONOFF: "",
 | ||||
| //   upload_Logo: null,
 | ||||
| //   company_Display_Name: "",
 | ||||
| // });
 | ||||
| // useEffect(() => {
 | ||||
| //   if (systemParameters) {
 | ||||
| //     setFormData((prevForm) => ({
 | ||||
| //       ...prevForm,
 | ||||
| //       ...systemParameters
 | ||||
| //     }));
 | ||||
| //   }
 | ||||
| // }, [systemParameters]);
 | ||||
| 
 | ||||
| //   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();
 | ||||
| 
 | ||||
| //   //   toast.success("Form submitted successfully!");
 | ||||
| //   //   // alert("Form submitted successfully!");
 | ||||
| //   //   console.log("Form Data:", formData);
 | ||||
| //   // };
 | ||||
| 
 | ||||
| //   const handleSubmit = async (event) => {
 | ||||
| //     event.preventDefault();
 | ||||
| 
 | ||||
| //     try {
 | ||||
| //         console.log("Form Data:", formData);
 | ||||
| //         const sysParamData = await addSysParameter(formData);
 | ||||
| //         console.log("API Response:", sysParamData);
 | ||||
| 
 | ||||
| //         toast.success("Form submitted successfully!");
 | ||||
| //     } catch (error) {
 | ||||
| //         console.error("Error:", error.response ? error.response.data : error.message);
 | ||||
| //         toast.error("Failed to submit the form. Please try again.");
 | ||||
| //     }
 | ||||
| // };
 | ||||
| 
 | ||||
| //   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: "",
 | ||||
| //       logo: null,
 | ||||
| //       companyDisplayName: "",
 | ||||
| //     });
 | ||||
| //   };
 | ||||
| 
 | ||||
| //   return (
 | ||||
| //     <div
 | ||||
| //       style={{
 | ||||
| //         marginTop: "10rem",
 | ||||
| //         marginBottom: "2rem",
 | ||||
| //         boxSizing: "border-box",
 | ||||
| //       }}
 | ||||
| //     >
 | ||||
| //       {loading ? (
 | ||||
| //         <Spinner />
 | ||||
| //       ) : (
 | ||||
| //         <Container
 | ||||
| //           className="system_parameter mt-5 p-4 bg-light shadow-sm rounded"
 | ||||
|            | ||||
| //         >
 | ||||
| //           <h2
 | ||||
| //             className="title_main text-center mb-4"
 | ||||
| //             style={{ color: "#0E6591", fontWeight: "bold" }}
 | ||||
| //           >
 | ||||
| //             System Parameter Settings
 | ||||
| //           </h2>
 | ||||
| //           <Form onSubmit={handleSubmit}>
 | ||||
| //             <Row className="  mb-3">
 | ||||
| //               <Col xs={6}>
 | ||||
| //                 <h6 className="heading_main text-secondary">Setup Code</h6>
 | ||||
| //               </Col>
 | ||||
| //               <Col xs={6}>
 | ||||
| //                 <h6 className="heading_main text-secondary">Value</h6>
 | ||||
| //               </Col>
 | ||||
| //             </Row>
 | ||||
| 
 | ||||
| //             {Object.keys(formData).map((key, index) =>
 | ||||
| //               key !== "upload_Logo" ? (
 | ||||
| //                 <Row className="mb-3" key={index}>
 | ||||
| //                   <Col xs={6} className="d-flex align-items-center">
 | ||||
| //                     <Form.Label className="mb-0">
 | ||||
| //                       {key
 | ||||
| //                         .split(/(?=[A-Z])/)
 | ||||
| //                         .join(" ")
 | ||||
| //                         .replace(/\b\w/g, (l) => l.toUpperCase())}
 | ||||
| //                     </Form.Label>
 | ||||
| //                   </Col>
 | ||||
| //                   <Col xs={6}>
 | ||||
| //                     <Form.Control
 | ||||
| //                       className="p-2  custom-hover-border"
 | ||||
| //                       style={{ borderColor: "#ced4da" }}
 | ||||
| //                       type="text"
 | ||||
| //                       name={key}
 | ||||
| //                       value={formData[key]}
 | ||||
| //                       onChange={handleInputChange}
 | ||||
| //                     />
 | ||||
| //                   </Col>
 | ||||
| //                 </Row>
 | ||||
| //               ) : (
 | ||||
| //                 <Row className="mb-3" key={index}>
 | ||||
| //                   <Col xs={6} className="d-flex align-items-center">
 | ||||
| //                     <Form.Label className="mb-0">Upload Logo</Form.Label>
 | ||||
| //                   </Col>
 | ||||
| //                   <Col xs={6}>
 | ||||
| //                     <Form.Control
 | ||||
| //                       className="p-2 "
 | ||||
| //                       style={{ borderColor: "#ced4da" }}
 | ||||
| //                       type="file"
 | ||||
| //                       onChange={handleFileChange}
 | ||||
| //                     />
 | ||||
| //                   </Col>
 | ||||
| //                 </Row>
 | ||||
| //               )
 | ||||
| //             )}
 | ||||
| 
 | ||||
| //             <div className="d-flex justify-content-end mt-4">
 | ||||
| //               <Button
 | ||||
| //                 variant="primary"
 | ||||
| //                 type="submit"
 | ||||
| //                 className="me-2 px-4 py-2 custom_button"
 | ||||
| //               >
 | ||||
| //                 Save
 | ||||
| //               </Button>
 | ||||
| //               <Button
 | ||||
| //                 variant="outline"
 | ||||
| //                 onClick={handleClear}
 | ||||
| //                 className="px-4 py-2 custom_button"
 | ||||
| //               >
 | ||||
| //                 Clear
 | ||||
| //               </Button>
 | ||||
| //             </div>
 | ||||
| //           </Form>
 | ||||
| //         </Container>
 | ||||
| //       )}
 | ||||
| //     </div>
 | ||||
| //   );
 | ||||
| // };
 | ||||
| 
 | ||||
| // export default SystemParameterForm;
 | ||||
| import React, { useState, useEffect } from "react"; | ||||
| import { Button, Form, Container, Row, Col } from "react-bootstrap"; | ||||
| import "bootstrap/dist/css/bootstrap.min.css"; | ||||
| import "../Dashboard/CSS/CSS/CommonStyle.css"; | ||||
| import { toast } from "react-toastify"; | ||||
| import Spinner from "../../UIComponants/Spinner"; | ||||
| import {getSysParameter,addSysParameter} from "../../APIServices/SystemparameterApi"; | ||||
| import { getSysParameter, addSysParameter } from "../../APIServices/SystemparameterApi"; | ||||
| import { useSystemParameters } from "../../context/SystemParameterContext"; | ||||
| 
 | ||||
| const SystemParameterForm = () => { | ||||
|   const { systemParameters, loading: contextLoading } = useSystemParameters(); | ||||
| 
 | ||||
|   const [formData, setFormData] = useState({ | ||||
|     schedulerTime: "", | ||||
|     leaseTaxCode: "", | ||||
| @ -181,14 +396,16 @@ const SystemParameterForm = () => { | ||||
|     upload_Logo: null, | ||||
|     company_Display_Name: "", | ||||
|   }); | ||||
|   const [loading, setLoading] = useState(true); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     // Simulate loading data
 | ||||
|     setTimeout(() => { | ||||
|       setLoading(false); | ||||
|     }, 3000); // Simulated 3 seconds loading
 | ||||
|   }, []); | ||||
|     if (systemParameters) { | ||||
|       setFormData((prevForm) => ({ | ||||
|         ...prevForm, | ||||
|         ...systemParameters, | ||||
|       })); | ||||
|     } | ||||
|   }, [systemParameters]); | ||||
| 
 | ||||
|   const handleInputChange = (event) => { | ||||
|     const { name, value } = event.target; | ||||
|     setFormData((prevState) => ({ | ||||
| @ -200,62 +417,52 @@ const SystemParameterForm = () => { | ||||
|   const handleFileChange = (event) => { | ||||
|     setFormData((prevState) => ({ | ||||
|       ...prevState, | ||||
|       logo: event.target.files[0], | ||||
|       upload_Logo: event.target.files[0], | ||||
|     })); | ||||
|   }; | ||||
| 
 | ||||
|   // const handleSubmit = (event) => {
 | ||||
|   //   event.preventDefault();
 | ||||
| 
 | ||||
|   //   toast.success("Form submitted successfully!");
 | ||||
|   //   // alert("Form submitted successfully!");
 | ||||
|   //   console.log("Form Data:", formData);
 | ||||
|   // };
 | ||||
| 
 | ||||
|   const handleSubmit = async (event) => { | ||||
|     event.preventDefault(); | ||||
| 
 | ||||
|     try { | ||||
|         console.log("Form Data:", formData); | ||||
|         const sysParamData = await addSysParameter(formData); | ||||
|         console.log("API Response:", sysParamData); | ||||
| 
 | ||||
|         toast.success("Form submitted successfully!"); | ||||
|       console.log("Form Data:", formData); | ||||
|       const sysParamData = await addSysParameter(formData); | ||||
|       console.log("API Response:", sysParamData); | ||||
|       toast.success("Form submitted successfully!"); | ||||
|     } catch (error) { | ||||
|         console.error("Error:", error.response ? error.response.data : error.message); | ||||
|         toast.error("Failed to submit the form. Please try again."); | ||||
|       console.error("Error:", error.response ? error.response.data : error.message); | ||||
|       toast.error("Failed to submit the form. Please try again."); | ||||
|     } | ||||
| }; | ||||
|   }; | ||||
| 
 | ||||
|   const handleClear = () => { | ||||
|     setFormData({ | ||||
|       schedulerTimer: "", | ||||
|       schedulerTime: "", | ||||
|       leaseTaxCode: "", | ||||
|       vesselConfirmationProcessLimit: "", | ||||
| 
 | ||||
|       vesselConfProcessLimit: "", | ||||
|       rowToDisplay: "", | ||||
|       linkToDisplay: "", | ||||
|       rowToAdd: "", | ||||
|       lovRowToDisplay: "", | ||||
|       lovLinkToDisplay: "", | ||||
|       oldServerName: "", | ||||
|       oldBase: "", | ||||
|       oldAdminUser: "", | ||||
|       oldServerPort: "", | ||||
|       oidserverName: "", | ||||
|       oidBase: "", | ||||
|       oidAdminUser: "", | ||||
|       oidServerPort: "", | ||||
|       userDefaultGroup: "", | ||||
|       defaultDepartment: "", | ||||
|       defaultPosition: "", | ||||
|       singleCharge: "", | ||||
|       firstDayOfWeek: "", | ||||
|       firstDayOftheWeek: "", | ||||
|       hourPerShift: "", | ||||
|       cnBillingFrequency: "", | ||||
|       billingDepartmentCode: "", | ||||
|       basePriceList: "", | ||||
|       nonContainerServiceOrderAutoApprovalDeptCode: "", | ||||
|       ediMAESchedulerOnOff: "", | ||||
|       ediSchedulerOnOff: "", | ||||
|       logo: null, | ||||
|       companyDisplayName: "", | ||||
|       nonContainerServiceOrder: "", | ||||
|       ediMaeSchedulerONOFF: "", | ||||
|       ediSchedulerONOFF: "", | ||||
|       upload_Logo: null, | ||||
|       company_Display_Name: "", | ||||
|     }); | ||||
|   }; | ||||
| 
 | ||||
| @ -267,13 +474,10 @@ const SystemParameterForm = () => { | ||||
|         boxSizing: "border-box", | ||||
|       }} | ||||
|     > | ||||
|       {loading ? ( | ||||
|       {contextLoading ? ( | ||||
|         <Spinner /> | ||||
|       ) : ( | ||||
|         <Container | ||||
|           className="system_parameter mt-5 p-4 bg-light shadow-sm rounded" | ||||
|            | ||||
|         > | ||||
|         <Container className="system_parameter mt-5 p-4 bg-light shadow-sm rounded"> | ||||
|           <h2 | ||||
|             className="title_main text-center mb-4" | ||||
|             style={{ color: "#0E6591", fontWeight: "bold" }} | ||||
| @ -281,7 +485,7 @@ const SystemParameterForm = () => { | ||||
|             System Parameter Settings | ||||
|           </h2> | ||||
|           <Form onSubmit={handleSubmit}> | ||||
|             <Row className="  mb-3"> | ||||
|             <Row className="mb-3"> | ||||
|               <Col xs={6}> | ||||
|                 <h6 className="heading_main text-secondary">Setup Code</h6> | ||||
|               </Col> | ||||
| @ -303,7 +507,7 @@ const SystemParameterForm = () => { | ||||
|                   </Col> | ||||
|                   <Col xs={6}> | ||||
|                     <Form.Control | ||||
|                       className="p-2  custom-hover-border" | ||||
|                       className="p-2 custom-hover-border" | ||||
|                       style={{ borderColor: "#ced4da" }} | ||||
|                       type="text" | ||||
|                       name={key} | ||||
| @ -319,7 +523,7 @@ const SystemParameterForm = () => { | ||||
|                   </Col> | ||||
|                   <Col xs={6}> | ||||
|                     <Form.Control | ||||
|                       className="p-2 " | ||||
|                       className="p-2" | ||||
|                       style={{ borderColor: "#ced4da" }} | ||||
|                       type="file" | ||||
|                       onChange={handleFileChange} | ||||
|  | ||||
| @ -1,22 +1,23 @@ | ||||
| import React, { useState, useEffect } from "react"; | ||||
| import { Button, Dropdown,Modal, Form ,Row,Col,InputGroup,FormControl} from "react-bootstrap"; | ||||
| import { Button, Dropdown, Modal, Form, Row, Col, InputGroup, FormControl, Card } from "react-bootstrap"; | ||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||
| import { faEdit, faTrashAlt, faPlus,faBars,faTimes } from "@fortawesome/free-solid-svg-icons"; | ||||
| import { faEdit, faTrashAlt, faPlus, faBars, faTimes } from "@fortawesome/free-solid-svg-icons"; | ||||
| import "bootstrap/dist/css/bootstrap.min.css"; | ||||
| import "../Dashboard/CSS/CSS/CommonStyle.css"; | ||||
| import { Table, Pagination, PaginationItem, PaginationLink } from "reactstrap"; | ||||
| import { FaSearch, FaTimes } from "react-icons/fa"; | ||||
| import { FaSearch } from "react-icons/fa"; | ||||
| import { BsJournals } from "react-icons/bs"; | ||||
| import { toast } from "react-toastify"; | ||||
| import Spinner from '../../UIComponants/Spinner'; | ||||
| 
 | ||||
| import * as tokenRegistryAPI from './tokenregistryapi'; | ||||
| 
 | ||||
| function TOKENRegistry() { | ||||
|   const initialTokens = JSON.parse(localStorage.getItem("tokens")) || []; | ||||
|   const [tokens, setTokens] = useState(initialTokens); | ||||
|   const [tokens, setTokens] = useState([]); | ||||
|   const [showAddEditModal, setShowAddEditModal] = useState(false); | ||||
|   const [showGenerateTokenModal, setShowGenerateTokenModal] = useState(false); | ||||
|   const [newTokenName, setNewTokenName] = useState(""); | ||||
|   const [generatedToken, setGeneratedToken] = useState(""); | ||||
|   const [currentToken, setCurrentToken] = useState({ | ||||
|     tokenId: "", | ||||
|     id: "", | ||||
|     tokenName: "", | ||||
|     tokenValue: "", | ||||
|     isActive: true | ||||
| @ -25,50 +26,49 @@ function TOKENRegistry() { | ||||
|   const [searchQuery, setSearchQuery] = useState(""); | ||||
|   const [isEditing, setIsEditing] = useState(false); | ||||
|   const [recordsPerPage, setRecordsPerPage] = useState(10); | ||||
|   const [visibleColumns, setVisibleColumns] = useState({ | ||||
|     tokenId: true, | ||||
|     tokenName: true, | ||||
|     tokenValue: true, | ||||
|     isActive: true, | ||||
|     actions: true | ||||
|   }); | ||||
|   // Add to your state:
 | ||||
| const [visibleColumns, setVisibleColumns] = useState({ | ||||
|   id: true, | ||||
|   tokenName: true, | ||||
|   tokenValue: true, | ||||
|   scopes: true, | ||||
|   isActive: true, | ||||
|   actions: true | ||||
| }); | ||||
| 
 | ||||
| 
 | ||||
|   const [loading, setLoading] = useState(true); | ||||
| 
 | ||||
|   const [selectedScopes, setSelectedScopes] = useState([]); | ||||
|     const [availableScopes] = useState([ | ||||
|   { value: 'read', label: 'Read Access' }, | ||||
|   { value: 'write', label: 'Write Access' }, | ||||
|   { value: 'delete', label: 'Delete Access' }, | ||||
|   { value: 'admin', label: 'Admin Access' }, | ||||
|   ]); | ||||
|   useEffect(() => { | ||||
|     const apiUrl = `${process.env.REACT_APP_API_URL}apiregistery/getall`; | ||||
|     const token = localStorage.getItem("authToken"); | ||||
| 
 | ||||
|     const fetchTokens = 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(); | ||||
|             setTokens(data); | ||||
|             localStorage.setItem("tokens", JSON.stringify(data)); // Store tokens in local storage
 | ||||
|         } catch (error) { | ||||
|             console.error("Error fetching tokens:", error); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     fetchTokens(); | ||||
| }, []); | ||||
|   }, []); | ||||
| 
 | ||||
| useEffect(() => { | ||||
|   // Simulate loading data
 | ||||
|   setTimeout(() => { | ||||
|     setLoading(false); | ||||
|   }, 3000); // Simulated 3 seconds loading
 | ||||
| }, []); | ||||
|   const fetchTokens = async () => { | ||||
|     setLoading(true); | ||||
|     try { | ||||
|       const data = await tokenRegistryAPI.fetchAllTokens(); | ||||
|       setTokens(data); | ||||
|     } catch (error) { | ||||
|       handleApiError(error, "fetch tokens"); | ||||
|     } finally { | ||||
|       setLoading(false); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   const handleApiError = (error, action) => { | ||||
|     if (error.message === 'Unauthorized') { | ||||
|       toast.error("Your session has expired. Please log in again."); | ||||
|     } else { | ||||
|       toast.error(`Failed to ${action}`); | ||||
|       console.error(`Error ${action}:`, error); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   const toggleColumn = (column) => { | ||||
|     setVisibleColumns(prev => ({ | ||||
| @ -87,10 +87,14 @@ useEffect(() => { | ||||
| 
 | ||||
|   const handleSearch = (query) => { | ||||
|     setSearchQuery(query); | ||||
|     setCurrentPage(1); | ||||
|   }; | ||||
| 
 | ||||
|   const handleClose = () => { | ||||
|     setShowAddEditModal(false); // Close the modal by setting the state to false
 | ||||
|     setShowAddEditModal(false); | ||||
|     setShowGenerateTokenModal(false); | ||||
|     setGeneratedToken(""); | ||||
|     setNewTokenName(""); | ||||
|   }; | ||||
| 
 | ||||
|   const handleRecordsPerPageChange = (number) => { | ||||
| @ -98,365 +102,378 @@ useEffect(() => { | ||||
|     setCurrentPage(1); | ||||
|   }; | ||||
| 
 | ||||
|   const totalPages = Math.ceil(tokens.length / recordsPerPage); | ||||
|   const filteredTokens = tokens.filter( | ||||
|     (item) => | ||||
|       item.tokenName && | ||||
|       item.tokenName.toLowerCase().includes(searchQuery.toLowerCase()) | ||||
|   ); | ||||
| 
 | ||||
|   const totalPages = Math.ceil(filteredTokens.length / recordsPerPage); | ||||
|   const handlePageChange = (pageNumber) => { | ||||
|     setCurrentPage(pageNumber); | ||||
|   }; | ||||
| 
 | ||||
|   const slicedTokens = tokens | ||||
|     .filter( | ||||
|       (item) => | ||||
|         item.tokenName && | ||||
|         item.tokenName.toLowerCase().includes(searchQuery.toLowerCase()) | ||||
|     ) | ||||
|     .slice((currentPage - 1) * recordsPerPage, currentPage * recordsPerPage); | ||||
|   const slicedTokens = filteredTokens.slice( | ||||
|     (currentPage - 1) * recordsPerPage, | ||||
|     currentPage * recordsPerPage | ||||
|   ); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|   const handleSubmit = (event) => { | ||||
|   const handleSubmit = async (event) => { | ||||
|     event.preventDefault(); | ||||
|     try { | ||||
|       if (isEditing) { | ||||
|         setTokens(tokens.map(token => | ||||
|           token.tokenId === currentToken.tokenId ? currentToken : token | ||||
|         )); | ||||
|         await tokenRegistryAPI.updateToken(currentToken.id, currentToken); | ||||
|         toast.success("Token updated successfully!"); | ||||
|       } else { | ||||
|         const newTokenId = `ID${tokens.length + 1}`; | ||||
|         setTokens([...tokens, { ...currentToken, tokenId: newTokenId }]); | ||||
|         await tokenRegistryAPI.createToken(currentToken); | ||||
|         toast.success("Token added successfully!"); | ||||
|       } | ||||
|       setShowAddEditModal(false); | ||||
| 
 | ||||
|       localStorage.setItem("tokens", JSON.stringify(tokens)); // Update local storage with new tokens
 | ||||
|       fetchTokens(); | ||||
|     } catch (error) { | ||||
|       toast.error("There was an error while submitting the token."); | ||||
|       console.error("Error in handleSubmit:", error); // Log the error for debugging
 | ||||
|       handleApiError(error, isEditing ? "update token" : "add token"); | ||||
|     } | ||||
|      | ||||
|   }; | ||||
| 
 | ||||
|   const openModal = (token = { tokenId: "", tokenName: "", tokenValue: "", isActive: false }) => { | ||||
|     setIsEditing(!!token.tokenId); | ||||
|   const openModal = (token = { id: "", tokenName: "", tokenValue: "", isActive: false }) => { | ||||
|     setIsEditing(!!token.id); | ||||
|     setCurrentToken(token); | ||||
|     setShowAddEditModal(true); | ||||
|   }; | ||||
| 
 | ||||
|   const handleDelete = (tokenId) => { | ||||
|     setTokens(tokens.filter(token => token.tokenId !== tokenId)); | ||||
|     localStorage.setItem("tokens", JSON.stringify(tokens.filter(token => token.tokenId !== tokenId))); // Update local storage after deletion
 | ||||
|     toast.success('Token deleted ...'); | ||||
|   const handleDelete = async (id) => { | ||||
|     if (window.confirm("Are you sure you want to delete this token?")) { | ||||
|       try { | ||||
|         await tokenRegistryAPI.deleteToken(id); | ||||
|         toast.success('Token deleted successfully'); | ||||
|         fetchTokens(); | ||||
|       } catch (error) { | ||||
|         handleApiError(error, "delete token"); | ||||
|       } | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   const generateNewToken = async () => { | ||||
|   if (!newTokenName.trim()) { | ||||
|     toast.error("Please enter a token name"); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   try { | ||||
|     const data = await tokenRegistryAPI.generateToken({ | ||||
|       name: newTokenName, | ||||
|       scopes: selectedScopes | ||||
|     }); | ||||
|     setGeneratedToken(data.tokenValue); | ||||
|     toast.success("Token generated successfully!"); | ||||
|     fetchTokens(); | ||||
|   } catch (error) { | ||||
|     handleApiError(error, "generate token"); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
|   return ( | ||||
|     <div style={{marginTop:"11rem"}}> | ||||
|     <div style={{ marginTop: "1rem" }}> | ||||
|       {loading ? ( | ||||
|         <Spinner/> | ||||
|       ):( | ||||
|         <Spinner /> | ||||
|       ) : ( | ||||
|         <div className="container-fluid mt-5"> | ||||
|        | ||||
|       <div className="d-flex justify-content-between align-items-center mb-4"> | ||||
|         <h1 className="title_main">Token Registry</h1> | ||||
|       </div> | ||||
|           {/* Token Generation Card */} | ||||
|           <Card className="mb-4 shadow-sm"> | ||||
|             <Card.Header className="d-flex justify-content-between align-items-center"> | ||||
|               <Card.Title>Token Management</Card.Title> | ||||
|               <Button  | ||||
|                 variant="primary"  | ||||
|                 onClick={() => setShowGenerateTokenModal(true)} | ||||
|                 className="custom_button" | ||||
|               > | ||||
|                 Generate New Token | ||||
|               </Button> | ||||
|             </Card.Header> | ||||
|             <Card.Body> | ||||
|               <p>Manage your API tokens here. Generate new tokens or delete existing ones.</p> | ||||
|             </Card.Body> | ||||
|           </Card> | ||||
| 
 | ||||
|       <Row className="align-items-center my-3"> | ||||
|         {/* Left: Search Bar */} | ||||
|         <Col | ||||
|           xs={12} | ||||
|           md={8} | ||||
|           lg={6} | ||||
|           className="d-flex justify-content-center my-3" | ||||
|         > | ||||
|           <InputGroup | ||||
|             className="search-bar" | ||||
|             style={{ | ||||
|               borderRadius: "10px", | ||||
|               overflow: "hidden", | ||||
|               boxShadow: "0px 4px 12px rgba(0, 0, 0, 0.1)", | ||||
|               width: "100%", | ||||
|               maxWidth: "528px", // Set max-width to limit overall width
 | ||||
|               paddingRight: "-15px", // Increase padding on the right side
 | ||||
|             }} | ||||
|           > | ||||
|             <InputGroup.Text | ||||
|               style={{ | ||||
|                 backgroundColor: "#0E6591", | ||||
|                 color: "#fff", | ||||
|                 padding: "10px 15px", | ||||
|               }} | ||||
|             > | ||||
|               <FaSearch /> | ||||
|             </InputGroup.Text> | ||||
|             <FormControl | ||||
|               placeholder="Search" | ||||
|               value={searchQuery} | ||||
|               onChange={(e) => handleSearch(e.target.value)} | ||||
|               style={{ | ||||
|                 padding: "10px", | ||||
|                 border: "none", | ||||
|                 paddingRight: "5px", // More space on the right side of input field
 | ||||
|               }} | ||||
|             /> | ||||
|           </InputGroup> | ||||
|         </Col> | ||||
|           <div className="d-flex justify-content-between align-items-center mb-4"> | ||||
|             <h1 className="title_main">Token Registry</h1> | ||||
|           </div> | ||||
| 
 | ||||
|         {/*Add Icons */} | ||||
|         <Col xs={12} md={4} lg={6} className="d-flex justify-content-end"> | ||||
|           <> | ||||
|             {/* Add Icon */} | ||||
|             <FontAwesomeIcon | ||||
|               icon={faPlus} | ||||
|               onClick={() => openModal(true)} | ||||
|               style={{ | ||||
|                 cursor: "pointer", | ||||
|                 fontSize: "1.5rem", | ||||
|                 color: "#747264", | ||||
|                 marginRight: "20px", | ||||
|               }} | ||||
|             /> | ||||
|             <FontAwesomeIcon | ||||
|               icon={faBars} | ||||
|               style={{ | ||||
|                 cursor: "pointer", | ||||
|                 fontSize: "1.5rem", | ||||
|                 color: "#747264", | ||||
|               }} | ||||
|             /> | ||||
|           </> | ||||
|         </Col> | ||||
|       </Row> | ||||
| 
 | ||||
|        | ||||
|       <div className="table-responsive"> | ||||
|       <Table striped responsive hover align="middle" className=" table-flush shadow-sm"> | ||||
|         <thead className="custom_header"> | ||||
|           <tr> | ||||
|             {Object.keys(visibleColumns).filter(key => visibleColumns[key]).map(key => ( | ||||
|               <th key={key}>{key.charAt(0).toUpperCase() + key.slice(1)}</th> | ||||
|             ))} | ||||
|           </tr> | ||||
|         </thead> | ||||
|         <tbody className="tbody"> | ||||
|   {slicedTokens.length === 0 ? ( | ||||
|     <tr> | ||||
|       <td | ||||
|         colSpan={ | ||||
|           Object.keys(visibleColumns).filter( | ||||
|             (key) => visibleColumns[key] | ||||
|           ).length | ||||
|         } | ||||
|         className="text-center" | ||||
|       > | ||||
|         No Data Available | ||||
|       </td> | ||||
|     </tr> | ||||
|   ) : ( | ||||
|     slicedTokens.map((token, index) => ( | ||||
|       <tr key={index}> | ||||
|         {Object.keys(visibleColumns).filter(key => visibleColumns[key]).map(key => ( | ||||
|           <td key={key}> | ||||
|             {key === "actions" ? ( | ||||
|               <> | ||||
|                 <FontAwesomeIcon | ||||
|                   icon={faEdit} | ||||
|                   onClick={() => openModal(token)} | ||||
|                   className="me-2" | ||||
|                   style={{ | ||||
|                     cursor: "pointer", | ||||
|                     fontSize: "1rem", | ||||
|                     color: "green", | ||||
|                     marginRight: "15px", | ||||
|                   }} | ||||
|                 /> | ||||
|                 <FontAwesomeIcon | ||||
|                   icon={faTrashAlt} | ||||
|                   onClick={() => handleDelete(token.tokenId)} | ||||
|                   style={{ | ||||
|                     cursor: "pointer", | ||||
|                     fontSize: "1rem", | ||||
|                     color: "#dc3545", | ||||
|                   }} | ||||
|                 /> | ||||
|               </> | ||||
|             ) : key === "isActive" ? ( | ||||
|               <span | ||||
|                 className="status" | ||||
|           <Row className="align-items-center my-3"> | ||||
|             <Col xs={12} md={8} lg={6} className="d-flex justify-content-center my-3"> | ||||
|               <InputGroup | ||||
|                 className="search-bar" | ||||
|                 style={{ | ||||
|                   color: token.isActive ? "green" : "red", | ||||
|                   backgroundColor: token.isActive | ||||
|                     ? "#d4f7d4" | ||||
|                     : "#f7d4d4", | ||||
|                   padding: "4px 8px", | ||||
|                   borderRadius: "4px", | ||||
|                   display: "inline-block", | ||||
|                   borderRadius: "10px", | ||||
|                   overflow: "hidden", | ||||
|                   boxShadow: "0px 4px 12px rgba(0, 0, 0, 0.1)", | ||||
|                   width: "100%", | ||||
|                   maxWidth: "528px", | ||||
|                 }} | ||||
|               > | ||||
|                 {token.isActive ? "Active" : "Inactive"} | ||||
|               </span> | ||||
|             ) : ( | ||||
|               token[key] | ||||
|             )} | ||||
|           </td> | ||||
|         ))} | ||||
|       </tr> | ||||
|     )) | ||||
|   )} | ||||
| </tbody> | ||||
|                 <InputGroup.Text style={{ backgroundColor: "#0E6591", color: "#fff", padding: "10px 15px" }}> | ||||
|                   <FaSearch /> | ||||
|                 </InputGroup.Text> | ||||
|                 <FormControl | ||||
|                   placeholder="Search" | ||||
|                   value={searchQuery} | ||||
|                   onChange={(e) => handleSearch(e.target.value)} | ||||
|                   style={{ padding: "10px", border: "none" }} | ||||
|                 /> | ||||
|               </InputGroup> | ||||
|             </Col> | ||||
| 
 | ||||
|       </Table> | ||||
|       </div> | ||||
|             <Col xs={12} md={4} lg={6} className="d-flex justify-content-end"> | ||||
|               <FontAwesomeIcon | ||||
|                 icon={faPlus} | ||||
|                 onClick={() => openModal()} | ||||
|                 style={{ | ||||
|                   cursor: "pointer", | ||||
|                   fontSize: "1.5rem", | ||||
|                   color: "#747264", | ||||
|                   marginRight: "20px", | ||||
|                 }} | ||||
|               /> | ||||
|               <FontAwesomeIcon | ||||
|                 icon={faBars} | ||||
|                 style={{ | ||||
|                   cursor: "pointer", | ||||
|                   fontSize: "1.5rem", | ||||
|                   color: "#747264", | ||||
|                 }} | ||||
|               /> | ||||
|             </Col> | ||||
|           </Row> | ||||
| 
 | ||||
|       {/* Manage Columns & Records Per Page */} | ||||
|       <Row className="mt-4"> | ||||
|         <Col md={6} className="d-flex justify-content-start"> | ||||
|           <Dropdown> | ||||
|             <Dropdown.Toggle | ||||
|               variant="outline-primary" | ||||
|               className="custom_manage_column_button" | ||||
|             > | ||||
|               Manage Columns | ||||
|             </Dropdown.Toggle> | ||||
|             <Dropdown.Menu> | ||||
|               {Object.keys(visibleColumns).map((column) => ( | ||||
|                 <Dropdown.Item | ||||
|                   key={column} | ||||
|                   onClick={() => toggleColumn(column)} | ||||
|           <div className="table-responsive"> | ||||
|             <Table striped responsive hover align="middle" className="table-flush shadow-sm"> | ||||
|               <thead className="custom_header"> | ||||
|                 <tr> | ||||
|                   {Object.keys(visibleColumns).filter(key => visibleColumns[key]).map(key => ( | ||||
|                     <th key={key}>{key.charAt(0).toUpperCase() + key.slice(1)}</th> | ||||
|                   ))} | ||||
|                 </tr> | ||||
|               </thead> | ||||
|               <tbody className="tbody"> | ||||
|                 {slicedTokens.length === 0 ? ( | ||||
|                   <tr> | ||||
|                     <td | ||||
|                       colSpan={Object.keys(visibleColumns).filter(key => visibleColumns[key]).length} | ||||
|                       className="text-center" | ||||
|                     > | ||||
|                       No Data Available | ||||
|                     </td> | ||||
|                   </tr> | ||||
|                 ) : ( | ||||
|                   slicedTokens.map((token, index) => ( | ||||
|                     <tr key={index}> | ||||
|                       {Object.keys(visibleColumns).filter(key => visibleColumns[key]).map(key => ( | ||||
|                         <td key={key}> | ||||
|                           {key === "actions" ? ( | ||||
|                             <> | ||||
|                               <FontAwesomeIcon | ||||
|                                 icon={faEdit} | ||||
|                                 onClick={() => openModal(token)} | ||||
|                                 className="me-2" | ||||
|                                 style={{ | ||||
|                                   cursor: "pointer", | ||||
|                                   fontSize: "1rem", | ||||
|                                   color: "green", | ||||
|                                   marginRight: "15px", | ||||
|                                 }} | ||||
|                               /> | ||||
|                               <FontAwesomeIcon | ||||
|                                 icon={faTrashAlt} | ||||
|                                 onClick={() => handleDelete(token.id)} | ||||
|                                 style={{ | ||||
|                                   cursor: "pointer", | ||||
|                                   fontSize: "1rem", | ||||
|                                   color: "#dc3545", | ||||
|                                 }} | ||||
|                               /> | ||||
|                             </> | ||||
|                           ) : key === "isActive" ? ( | ||||
|                             <span | ||||
|                               className="status" | ||||
|                               style={{ | ||||
|                                 color: token.isActive ? "green" : "red", | ||||
|                                 backgroundColor: token.isActive ? "#d4f7d4" : "#f7d4d4", | ||||
|                                 padding: "4px 8px", | ||||
|                                 borderRadius: "4px", | ||||
|                                 display: "inline-block", | ||||
|                               }} | ||||
|                             > | ||||
|                               {token.isActive ? "Active" : "Inactive"} | ||||
|                             </span> | ||||
|                           ) : ( | ||||
|                             token[key] | ||||
|                           )} | ||||
|                         </td> | ||||
|                       ))} | ||||
|                     </tr> | ||||
|                   )) | ||||
|                 )} | ||||
|               </tbody> | ||||
|             </Table> | ||||
|           </div> | ||||
| 
 | ||||
|           {/* Manage Columns & Records Per Page */} | ||||
|           <Row className="mt-4"> | ||||
|             <Col md={6} className="d-flex justify-content-start"> | ||||
|               <Dropdown> | ||||
|                 <Dropdown.Toggle variant="outline-primary" className="custom_manage_column_button"> | ||||
|                   Manage Columns | ||||
|                 </Dropdown.Toggle> | ||||
|                 <Dropdown.Menu> | ||||
|                   {Object.keys(visibleColumns).map((column) => ( | ||||
|                     <Dropdown.Item key={column} onClick={() => toggleColumn(column)}> | ||||
|                       <Form.Check | ||||
|                         type="checkbox" | ||||
|                         label={column.charAt(0).toUpperCase() + column.slice(1).toLowerCase()} | ||||
|                         checked={visibleColumns[column]} | ||||
|                         readOnly | ||||
|                         className="custom-checkbox" | ||||
|                       /> | ||||
|                     </Dropdown.Item> | ||||
|                   ))} | ||||
|                 </Dropdown.Menu> | ||||
|               </Dropdown> | ||||
|             </Col> | ||||
| 
 | ||||
|             <Col md={6} className="d-flex justify-content-end"> | ||||
|               <Dropdown> | ||||
|                 <Dropdown.Toggle | ||||
|                   variant="outline-primary" | ||||
|                   className="custom_manage_column_button px-4 py-2 border-2 rounded-3 shadow-sm" | ||||
|                 > | ||||
|                   <Form.Check | ||||
|                     type="checkbox" | ||||
|                     label={ | ||||
|                       column.charAt(0).toUpperCase() + | ||||
|                       column.slice(1).toLowerCase() | ||||
|                     } | ||||
|                     checked={visibleColumns[column]} | ||||
|                     readOnly | ||||
|                     className="custom-checkbox" | ||||
|                   /> | ||||
|                 </Dropdown.Item> | ||||
|               ))} | ||||
|             </Dropdown.Menu> | ||||
|           </Dropdown> | ||||
|         </Col> | ||||
|                   <BsJournals /> | ||||
|                 </Dropdown.Toggle> | ||||
|                 <Dropdown.Menu className="border-0 rounded-3 shadow-lg" align="end"> | ||||
|                   {[1, 5, 10, 20, 50].map((number) => ( | ||||
|                     <Dropdown.Item | ||||
|                       key={number} | ||||
|                       onClick={() => handleRecordsPerPageChange(number)} | ||||
|                       className="text-dark d-flex justify-content-between align-items-center" | ||||
|                     > | ||||
|                       <span>{number}</span> | ||||
|                       <i | ||||
|                         className="fa fa-check-circle" | ||||
|                         style={{ display: recordsPerPage === number ? "inline" : "none" }} | ||||
|                       /> | ||||
|                     </Dropdown.Item> | ||||
|                   ))} | ||||
|                 </Dropdown.Menu> | ||||
|               </Dropdown> | ||||
|             </Col> | ||||
|           </Row> | ||||
| 
 | ||||
|         <Col md={6} className="d-flex justify-content-end"> | ||||
|           <Dropdown> | ||||
|             <Dropdown.Toggle | ||||
|               variant="outline-primary" | ||||
|               className="custom_manage_column_button px-4 py-2 border-2 rounded-3 shadow-sm" | ||||
|               id="dropdown-custom-components" | ||||
|             > | ||||
|               <BsJournals /> | ||||
|             </Dropdown.Toggle> | ||||
|             <Dropdown.Menu className="border-0 rounded-3 shadow-lg" align="end"> | ||||
|               {[1, 5, 10, 20, 50].map((number) => ( | ||||
|                 <Dropdown.Item | ||||
|                   key={number} | ||||
|                   onClick={() => handleRecordsPerPageChange(number)} | ||||
|                   className="text-dark d-flex justify-content-between align-items-center" | ||||
|                 > | ||||
|                   <span>{number}</span> | ||||
|                   <i | ||||
|                     className="fa fa-check-circle" | ||||
|                     style={{ | ||||
|                       display: recordsPerPage === number ? "inline" : "none", | ||||
|                     }} | ||||
|                   /> | ||||
|                 </Dropdown.Item> | ||||
|               ))} | ||||
|             </Dropdown.Menu> | ||||
|           </Dropdown> | ||||
|         </Col> | ||||
|       </Row> | ||||
|           <Pagination className="pagination"> | ||||
|             <PaginationItem disabled={currentPage === 1}> | ||||
|               <PaginationLink previous onClick={() => handlePageChange(currentPage - 1)} /> | ||||
|             </PaginationItem> | ||||
|             {[...Array(totalPages)].map((_, index) => ( | ||||
|               <PaginationItem key={index} active={index + 1 === currentPage}> | ||||
|                 <PaginationLink onClick={() => handlePageChange(index + 1)} style={{ color: "#0b6592" }}> | ||||
|                   {index + 1} | ||||
|                 </PaginationLink> | ||||
|               </PaginationItem> | ||||
|             ))} | ||||
|             <PaginationItem disabled={currentPage === totalPages}> | ||||
|               <PaginationLink next onClick={() => handlePageChange(currentPage + 1)} /> | ||||
|             </PaginationItem> | ||||
|           </Pagination> | ||||
| 
 | ||||
|       <Pagination className="pagination"> | ||||
|         <PaginationItem disabled={currentPage === 1}> | ||||
|           <PaginationLink | ||||
|             previous | ||||
|             onClick={() => handlePageChange(currentPage - 1)} | ||||
|           {/* Add/Edit Token Modal */} | ||||
|           <Modal show={showGenerateTokenModal} onHide={handleClose}> | ||||
|   <Modal.Header> | ||||
|     <Modal.Title>Generate New Token</Modal.Title> | ||||
|     <FontAwesomeIcon | ||||
|       icon={faTimes} | ||||
|       size="lg" | ||||
|       onClick={handleClose} | ||||
|       style={{ | ||||
|         position: "absolute", | ||||
|         top: "25px", | ||||
|         right: "25px", | ||||
|         cursor: "pointer", | ||||
|       }} | ||||
|     /> | ||||
|   </Modal.Header> | ||||
|   <Modal.Body> | ||||
|     <Form> | ||||
|       <Form.Group controlId="formNewTokenName" className="mb-3"> | ||||
|         <Form.Label>Token Name</Form.Label> | ||||
|         <Form.Control | ||||
|           type="text" | ||||
|           value={newTokenName} | ||||
|           onChange={(e) => setNewTokenName(e.target.value)} | ||||
|           required | ||||
|           className="custom-hover-border" | ||||
|           placeholder="Enter a name for the new token" | ||||
|         /> | ||||
|       </Form.Group> | ||||
| 
 | ||||
|       <Form.Group controlId="formTokenScopes" className="mb-3"> | ||||
|         <Form.Label>Token Scopes</Form.Label> | ||||
|         <Form.Select | ||||
|           multiple | ||||
|           value={selectedScopes} | ||||
|           onChange={(e) => { | ||||
|             const options = [...e.target.options]; | ||||
|             const selectedValues = options | ||||
|               .filter(option => option.selected) | ||||
|               .map(option => option.value); | ||||
|             setSelectedScopes(selectedValues); | ||||
|           }} | ||||
|           className="custom-hover-border" | ||||
|           style={{ height: 'auto' }} | ||||
|         > | ||||
|           {availableScopes.map(scope => ( | ||||
|             <option key={scope.value} value={scope.value}> | ||||
|               {scope.label} | ||||
|             </option> | ||||
|           ))} | ||||
|         </Form.Select> | ||||
|         <Form.Text className="text-muted"> | ||||
|           Select the permissions this token should have (hold Ctrl/Cmd to select multiple) | ||||
|         </Form.Text> | ||||
|       </Form.Group> | ||||
| 
 | ||||
|       {generatedToken && ( | ||||
|         <Form.Group controlId="formGeneratedToken" className="mb-3"> | ||||
|           <Form.Label>Generated Token</Form.Label> | ||||
|           <Form.Control | ||||
|             as="textarea" | ||||
|             rows={3} | ||||
|             value={generatedToken} | ||||
|             readOnly | ||||
|             className="custom-hover-border" | ||||
|           /> | ||||
|         </PaginationItem> | ||||
|         {[...Array(totalPages)].map((_, index) => ( | ||||
|           <PaginationItem key={index} active={index + 1 === currentPage}> | ||||
|             <PaginationLink | ||||
|               onClick={() => handlePageChange(index + 1)} | ||||
|               style={{ color: "#0b6592" }} | ||||
|             > | ||||
|               {index + 1} | ||||
|             </PaginationLink> | ||||
|           </PaginationItem> | ||||
|         ))} | ||||
|         <PaginationItem disabled={currentPage === totalPages}> | ||||
|           <PaginationLink | ||||
|             next | ||||
|             onClick={() => handlePageChange(currentPage + 1)} | ||||
|           /> | ||||
|         </PaginationItem> | ||||
|       </Pagination> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|       <Modal show={showAddEditModal} onHide={() => setShowAddEditModal(false)}> | ||||
|         <Modal.Header > | ||||
|           <Modal.Title>{isEditing ? "Edit Token" : "Add Token"}</Modal.Title> | ||||
|           <FontAwesomeIcon | ||||
|             icon={faTimes} | ||||
|             size="lg" | ||||
|             onClick={handleClose} | ||||
|             style={{ | ||||
|               position: "absolute", | ||||
|               top: "25px", | ||||
|               right: "25px", | ||||
|               cursor: "pointer", | ||||
|             }} | ||||
|           /> | ||||
|        </Modal.Header> | ||||
|         <Modal.Body> | ||||
|           <Form onSubmit={handleSubmit}> | ||||
|             <Form.Group controlId="formTokenName"> | ||||
|               <Form.Label>Token Name</Form.Label> | ||||
|               <Form.Control | ||||
|                 type="text" | ||||
|                 name="tokenName" | ||||
|                 value={currentToken.tokenName} | ||||
|                 onChange={handleInputChange} | ||||
|                 required | ||||
|                 className="custom-hover-border" | ||||
|               /> | ||||
|             </Form.Group> | ||||
|             <Form.Group controlId="formTokenValue"> | ||||
|               <Form.Label>Token Value</Form.Label> | ||||
|               <Form.Control | ||||
|                 type="text" | ||||
|                 name="tokenValue" | ||||
|                 value={currentToken.tokenValue} | ||||
|                 onChange={handleInputChange} | ||||
|                 required | ||||
|                 className="custom-hover-border" | ||||
|               /> | ||||
|             </Form.Group> | ||||
|             <Form.Group controlId="formActive"> | ||||
|               <Form.Check | ||||
|                 type="checkbox" | ||||
|                 label="Active?" | ||||
|                 name="isActive" | ||||
|                 checked={currentToken.isActive} | ||||
|                 onChange={handleInputChange} | ||||
|                 className="custom-checkbox" | ||||
|               /> | ||||
|             </Form.Group> | ||||
|             <Modal.Footer> | ||||
|               <Button variant="primary" className="custom_button px-4" onClick={() => setShowAddEditModal(false)}>Close</Button> | ||||
|               <Button variant="primary" className="custom_button px-4" type="submit">{isEditing ? "Update Token" : "Add Token"}</Button> | ||||
|             </Modal.Footer> | ||||
|           </Form> | ||||
|         </Modal.Body> | ||||
|       </Modal> | ||||
|     </div> | ||||
|           <Form.Text className="text-muted"> | ||||
|             Copy this token and store it securely. You won't be able to see it again. | ||||
|           </Form.Text> | ||||
|         </Form.Group> | ||||
|       )} | ||||
|        | ||||
|       <Modal.Footer> | ||||
|         <Button variant="secondary" onClick={handleClose}> | ||||
|           Close | ||||
|         </Button> | ||||
|         <Button  | ||||
|           variant="primary"  | ||||
|           onClick={generateNewToken} | ||||
|           disabled={!newTokenName.trim()} | ||||
|         > | ||||
|           Generate Token | ||||
|         </Button> | ||||
|       </Modal.Footer> | ||||
|     </Form> | ||||
|   </Modal.Body> | ||||
| </Modal> | ||||
|         </div> | ||||
|       )} | ||||
|     </div> | ||||
|      | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export default TOKENRegistry; | ||||
| export default TOKENRegistry; | ||||
| @ -313,7 +313,7 @@ export function UserGroupMaintenance() { | ||||
|     ) | ||||
|     .slice((currentPage - 1) * recordsPerPage, currentPage * recordsPerPage); | ||||
|   return ( | ||||
|     <div style={{ marginTop: "11rem" }}> | ||||
|     <div style={{ marginTop: "7rem" }}> | ||||
|       {loading ? ( | ||||
|         <Spinner /> | ||||
|       ) : ( | ||||
| @ -366,11 +366,11 @@ export function UserGroupMaintenance() { | ||||
|             {/*Add Icons */} | ||||
|             <Col xs={12} md={4} lg={6} className="d-flex justify-content-end"> | ||||
|               <> | ||||
|                 <OverlayTrigger | ||||
|                 {/* <OverlayTrigger | ||||
|                   placement="bottom" | ||||
|                   overlay={<Tooltip>Add Group</Tooltip>} | ||||
|                 > | ||||
|                   <FontAwesomeIcon | ||||
|                 > */} | ||||
|                   {/* <FontAwesomeIcon | ||||
|                     icon={faPlus} | ||||
|                     onClick={() => handleAddItem(true)} | ||||
|                     style={{ | ||||
| @ -379,8 +379,8 @@ export function UserGroupMaintenance() { | ||||
|                       color: "#747264", | ||||
|                       marginRight: "20px", | ||||
|                     }} | ||||
|                   /> | ||||
|                 </OverlayTrigger> | ||||
|                   /> */} | ||||
|                 {/* </OverlayTrigger> */} | ||||
|                 <OverlayTrigger | ||||
|                   placement="bottom" | ||||
|                   overlay={<Tooltip>Download template</Tooltip>} | ||||
| @ -426,7 +426,7 @@ export function UserGroupMaintenance() { | ||||
|                     }} | ||||
|                   /> | ||||
|                 </OverlayTrigger> | ||||
|                 <OverlayTrigger | ||||
|                 {/* <OverlayTrigger | ||||
|                   placement="bottom" | ||||
|                   overlay={<Tooltip>Menu</Tooltip>} | ||||
|                 > | ||||
| @ -438,7 +438,7 @@ export function UserGroupMaintenance() { | ||||
|                       color: "#747264", | ||||
|                     }} | ||||
|                   /> | ||||
|                 </OverlayTrigger> | ||||
|                 </OverlayTrigger> */} | ||||
|                 {/* Add Icon */} | ||||
|               </> | ||||
|             </Col> | ||||
|  | ||||
| @ -579,7 +579,7 @@ function UserMaintenanceView() { | ||||
|   .slice((currentPage - 1) * recordsPerPage, currentPage * recordsPerPage); | ||||
|    | ||||
|   return ( | ||||
|     <div style={{marginTop:"8rem"}}> | ||||
|     <div style={{marginTop:"7rem"}}> | ||||
|       {loading ? ( | ||||
|         <Spinner/> | ||||
|       ):( | ||||
| @ -634,7 +634,7 @@ function UserMaintenanceView() { | ||||
|         <Col xs={12} md={4} lg={6} className="d-flex justify-content-end"> | ||||
|           <> | ||||
|             {/* Add Icon */} | ||||
|             <OverlayTrigger placement="bottom" overlay={<Tooltip>Add Items</Tooltip>}> | ||||
|             {/* <OverlayTrigger placement="bottom" overlay={<Tooltip>Add Items</Tooltip>}> | ||||
|             <FontAwesomeIcon | ||||
|               icon={faPlus} | ||||
|               onClick={() => handleAddItem(true)} | ||||
| @ -649,7 +649,7 @@ function UserMaintenanceView() { | ||||
|               title="Add Item" | ||||
|             /> | ||||
|             </OverlayTrigger> | ||||
|             | ||||
|             */} | ||||
|            <OverlayTrigger  placement="bottom" overlay={<Tooltip>Download template</Tooltip>}> | ||||
|            <FontAwesomeIcon | ||||
|               icon={faDownload} | ||||
| @ -687,7 +687,7 @@ function UserMaintenanceView() { | ||||
|             /> | ||||
|            </OverlayTrigger> | ||||
| 
 | ||||
|            <OverlayTrigger  placement="bottom" overlay={<Tooltip>Menu Items</Tooltip>}> | ||||
|            {/* <OverlayTrigger  placement="bottom" overlay={<Tooltip>Menu Items</Tooltip>}> | ||||
|            <FontAwesomeIcon | ||||
|               icon={faBars} | ||||
|               style={{ | ||||
| @ -697,7 +697,7 @@ function UserMaintenanceView() { | ||||
|               }} | ||||
|             /> | ||||
|            </OverlayTrigger> | ||||
|              | ||||
|              */} | ||||
|           </> | ||||
|         </Col> | ||||
|       </Row> | ||||
|  | ||||
| @ -7,6 +7,8 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; | ||||
| import { faTrash, faGripLines, faPen } from '@fortawesome/free-solid-svg-icons'; | ||||
| import { useNavigate, useParams } from 'react-router-dom'; | ||||
| import DashboardBuilderService from "../../../../APIServices/DashboardBuilderService"; | ||||
| import TextField from '@mui/material/TextField'; | ||||
| import FormControlLabel from '@mui/material/FormControlLabel'; | ||||
| 
 | ||||
| // Import chart components
 | ||||
| import LineChartComponent from '../gadgets/line-chart/LineChart'; | ||||
| @ -248,6 +250,7 @@ const EditNewDash = () => { | ||||
| 
 | ||||
|   // Edit widget
 | ||||
|   const editWidget = (widget) => { | ||||
|     console.log("Opening edit modal for:", widget); | ||||
|     setCurrentEditWidget(widget); | ||||
|     setEditModalOpen(true); | ||||
|   }; | ||||
| @ -420,6 +423,7 @@ const EditNewDash = () => { | ||||
|         > | ||||
|           <ResponsiveGridLayout | ||||
|             className="layout" | ||||
|             draggableCancel=".MuiButton-root, .MuiIconButton-root, button, [role='button']" | ||||
|             layouts={{ | ||||
|               lg: dashboardWidgets.map(widget => ({ | ||||
|                 i: widget.i, | ||||
| @ -458,17 +462,23 @@ const EditNewDash = () => { | ||||
|                       {widget.name} | ||||
|                     </Typography> | ||||
|                     <Box> | ||||
|                       <Button | ||||
|                         size="small" | ||||
|                         onClick={() => editWidget(widget)} | ||||
|                         sx={{ minWidth: 'auto', padding: '4px' }} | ||||
|                       > | ||||
|                         <FontAwesomeIcon icon={faPen} /> | ||||
|                       </Button> | ||||
| <Button | ||||
|   size="small" | ||||
|   onClick={(e) => { | ||||
|     e.stopPropagation(); | ||||
|     editWidget(widget); | ||||
|   }} | ||||
| > | ||||
|   <FontAwesomeIcon icon={faPen} /> | ||||
| </Button> | ||||
| 
 | ||||
|                       <Button | ||||
|                         size="small" | ||||
|                         color="error" | ||||
|                         onClick={() => removeWidget(widget.i)} | ||||
|                         onClick={() => { | ||||
|                           console.log("Edit button clicked for widget:", widget); | ||||
|                           removeWidget(widget.i)} | ||||
|                         } | ||||
|                         sx={{ minWidth: 'auto', padding: '4px', ml: 1 }} | ||||
|                       > | ||||
|                         <FontAwesomeIcon icon={faTrash} /> | ||||
| @ -512,93 +522,69 @@ const EditNewDash = () => { | ||||
| 
 | ||||
|       {/* Edit widget dialog */} | ||||
|       <Dialog open={editModalOpen} onClose={() => setEditModalOpen(false)} maxWidth="sm" fullWidth> | ||||
|         <DialogTitle>Edit {currentEditWidget.name}</DialogTitle> | ||||
|         <DialogContent sx={{ paddingTop: 2 }}> | ||||
|           <FormControl fullWidth sx={{ marginBottom: 2 }}> | ||||
|             <Typography variant="subtitle2" sx={{ marginBottom: 1 }}>Chart Title</Typography> | ||||
|             <Input | ||||
|               value={currentEditWidget.chartTitle || ''} | ||||
|               onChange={(e) => setCurrentEditWidget({ | ||||
|                 ...currentEditWidget, | ||||
|                 chartTitle: e.target.value | ||||
|               })} | ||||
|               placeholder="Enter chart title" | ||||
|               fullWidth | ||||
|   <DialogTitle>Edit {currentEditWidget?.name}</DialogTitle> | ||||
|   <DialogContent dividers> | ||||
|     <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}> | ||||
|       <TextField | ||||
|         label="Chart Title" | ||||
|         fullWidth | ||||
|         value={currentEditWidget?.chartTitle || ''} | ||||
|         onChange={(e) => | ||||
|           setCurrentEditWidget((prev) => ({ ...prev, chartTitle: e.target.value })) | ||||
|         } | ||||
|       /> | ||||
|       <TextField | ||||
|         label="X Axis Label" | ||||
|         fullWidth | ||||
|         value={currentEditWidget?.xAxis || ''} | ||||
|         onChange={(e) => | ||||
|           setCurrentEditWidget((prev) => ({ ...prev, xAxis: e.target.value })) | ||||
|         } | ||||
|       /> | ||||
|       <TextField | ||||
|         label="Y Axis Label" | ||||
|         fullWidth | ||||
|         value={currentEditWidget?.yAxis || ''} | ||||
|         onChange={(e) => | ||||
|           setCurrentEditWidget((prev) => ({ ...prev, yAxis: e.target.value })) | ||||
|         } | ||||
|       /> | ||||
|       <FormControl> | ||||
|         <FormControlLabel | ||||
|           control={ | ||||
|             <Checkbox | ||||
|               checked={currentEditWidget?.showLegend ?? true} | ||||
|               onChange={(e) => | ||||
|                 setCurrentEditWidget((prev) => ({ ...prev, showLegend: e.target.checked })) | ||||
|               } | ||||
|             /> | ||||
|           </FormControl> | ||||
| 
 | ||||
|           {currentEditWidget.name !== 'Grid View' && currentEditWidget.name !== 'Todo Chart' && ( | ||||
|             <> | ||||
|               <Box sx={{ display: 'flex', gap: 2, marginBottom: 2 }}> | ||||
|                 <FormControl sx={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}> | ||||
|                   <Checkbox | ||||
|                     checked={currentEditWidget.showLegend || false} | ||||
|                     onChange={(e) => setCurrentEditWidget({ | ||||
|                       ...currentEditWidget, | ||||
|                       showLegend: e.target.checked | ||||
|                     })} | ||||
|                   /> | ||||
|                   <Typography>Show Legend</Typography> | ||||
|                 </FormControl> | ||||
| 
 | ||||
|                 <FormControl sx={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}> | ||||
|                   <Checkbox | ||||
|                     checked={currentEditWidget.showLabel || false} | ||||
|                     onChange={(e) => setCurrentEditWidget({ | ||||
|                       ...currentEditWidget, | ||||
|                       showLabel: e.target.checked | ||||
|                     })} | ||||
|                   /> | ||||
|                   <Typography>Show Labels</Typography> | ||||
|                 </FormControl> | ||||
|               </Box> | ||||
|             </> | ||||
|           )} | ||||
| 
 | ||||
|           <FormControl fullWidth sx={{ marginBottom: 2 }}> | ||||
|             <Typography variant="subtitle2" sx={{ marginBottom: 1 }}>X-Axis</Typography> | ||||
|             <Select | ||||
|               value={currentEditWidget.xAxis || ''} | ||||
|               onChange={(e) => setCurrentEditWidget({ | ||||
|                 ...currentEditWidget, | ||||
|                 xAxis: e.target.value | ||||
|               })} | ||||
|               displayEmpty | ||||
|             > | ||||
|               <MenuItem value="" disabled>Select X-Axis</MenuItem> | ||||
|               {columnData.map((col, index) => ( | ||||
|                 <MenuItem key={index} value={col}>{col}</MenuItem> | ||||
|               ))} | ||||
|             </Select> | ||||
|           </FormControl> | ||||
| 
 | ||||
|           <FormControl fullWidth sx={{ marginBottom: 2 }}> | ||||
|             <Typography variant="subtitle2" sx={{ marginBottom: 1 }}>Y-Axis</Typography> | ||||
|             <Select | ||||
|               value={currentEditWidget.yAxis || ''} | ||||
|               onChange={(e) => setCurrentEditWidget({ | ||||
|                 ...currentEditWidget, | ||||
|                 yAxis: e.target.value | ||||
|               })} | ||||
|               displayEmpty | ||||
|             > | ||||
|               <MenuItem value="" disabled>Select Y-Axis</MenuItem> | ||||
|               {columnData.map((col, index) => ( | ||||
|                 <MenuItem key={index} value={col}>{col}</MenuItem> | ||||
|               ))} | ||||
|             </Select> | ||||
|           </FormControl> | ||||
|         </DialogContent> | ||||
|         <DialogActions sx={{ padding: 2 }}> | ||||
|           <Button onClick={() => setEditModalOpen(false)} color="inherit"> | ||||
|             Cancel | ||||
|           </Button> | ||||
|           <Button onClick={saveWidgetChanges} variant="contained" color="primary"> | ||||
|             Save Changes | ||||
|           </Button> | ||||
|         </DialogActions> | ||||
|       </Dialog> | ||||
|           } | ||||
|           label="Show Legend" | ||||
|         /> | ||||
|         <FormControlLabel | ||||
|           control={ | ||||
|             <Checkbox | ||||
|               checked={currentEditWidget?.showLabel ?? true} | ||||
|               onChange={(e) => | ||||
|                 setCurrentEditWidget((prev) => ({ ...prev, showLabel: e.target.checked })) | ||||
|               } | ||||
|             /> | ||||
|           } | ||||
|           label="Show Labels" | ||||
|         /> | ||||
|       </FormControl> | ||||
|     </Box> | ||||
|   </DialogContent> | ||||
|   <DialogActions> | ||||
|     <Button onClick={() => setEditModalOpen(false)} color="secondary"> | ||||
|       Cancel | ||||
|     </Button> | ||||
|     <Button onClick={saveWidgetChanges} variant="contained" color="primary"> | ||||
|       Save Changes | ||||
|     </Button> | ||||
|   </DialogActions> | ||||
| </Dialog> | ||||
| </Box> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										299
									
								
								src/components/Dashboard/sequencegenerator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										299
									
								
								src/components/Dashboard/sequencegenerator.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,299 @@ | ||||
| import React, { useState, useEffect } from 'react'; | ||||
| import {  | ||||
|   Table,  | ||||
|   Button,  | ||||
|   Modal,  | ||||
|   Form,  | ||||
|   Input,  | ||||
|   InputNumber,  | ||||
|   Dropdown,  | ||||
|   Alert, | ||||
|   message, | ||||
|   Card, | ||||
|   Descriptions | ||||
| } from 'antd'; | ||||
| import {  | ||||
|   EllipsisOutlined,  | ||||
|   PlusOutlined, | ||||
|   EditOutlined, | ||||
|   DeleteOutlined | ||||
| } from '@ant-design/icons'; | ||||
| import SequenceGeneratorAPI from './sequencegeneratorapi'; | ||||
| 
 | ||||
| const SequenceGenerator = () => { | ||||
|   const [sequences, setSequences] = useState([]); | ||||
|   const [loading, setLoading] = useState(false); | ||||
|   const [error, setError] = useState(null); | ||||
|   const [visible, setVisible] = useState(false); | ||||
|   const [editingId, setEditingId] = useState(null); | ||||
|   const [currentSequence, setCurrentSequence] = useState(null); | ||||
|   const [form] = Form.useForm(); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     fetchSequences(); | ||||
|   }, []); | ||||
| 
 | ||||
|   const fetchSequences = async () => { | ||||
|     setLoading(true); | ||||
|     try { | ||||
|       const data = await SequenceGeneratorAPI.getAll(); | ||||
|       setSequences(data); | ||||
|     } catch (err) { | ||||
|       setError(err.response?.data?.message || 'Failed to fetch sequences'); | ||||
|     } finally { | ||||
|       setLoading(false); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   const handleCreate = () => { | ||||
|     form.resetFields(); | ||||
|     setCurrentSequence(null); | ||||
|     setEditingId(null); | ||||
|     setVisible(true); | ||||
|   }; | ||||
| 
 | ||||
|   const handleEdit = (record) => { | ||||
|     form.setFieldsValue(record); | ||||
|     setCurrentSequence(record); | ||||
|     setEditingId(record.id); | ||||
|     setVisible(true); | ||||
|   }; | ||||
| 
 | ||||
|   const handleDelete = async (id) => { | ||||
|     Modal.confirm({ | ||||
|       title: 'Confirm Delete', | ||||
|       content: 'Are you sure you want to delete this sequence?', | ||||
|       okText: 'Delete', | ||||
|       okType: 'danger', | ||||
|       cancelText: 'Cancel', | ||||
|       onOk: async () => { | ||||
|         try { | ||||
|           await SequenceGeneratorAPI.delete(id); | ||||
|           message.success('Sequence deleted successfully'); | ||||
|           fetchSequences(); | ||||
|         } catch (err) { | ||||
|           message.error(err.response?.data?.message || 'Failed to delete sequence'); | ||||
|         } | ||||
|       } | ||||
|     }); | ||||
|   }; | ||||
| 
 | ||||
|   const handleSubmit = async () => { | ||||
|     try { | ||||
|       const values = await form.validateFields(); | ||||
|        | ||||
|       if (editingId) { | ||||
|         await SequenceGeneratorAPI.update(editingId, values); | ||||
|         message.success('Sequence updated successfully'); | ||||
|       } else { | ||||
|         await SequenceGeneratorAPI.create(values); | ||||
|         message.success('Sequence created successfully'); | ||||
|       } | ||||
|        | ||||
|       setVisible(false); | ||||
|       fetchSequences(); | ||||
|     } catch (err) { | ||||
|       message.error(err.response?.data?.message || 'Operation failed'); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   const columns = [ | ||||
|     { | ||||
|       title: 'Actions', | ||||
|       key: 'actions', | ||||
|       width: 100, | ||||
|       render: (_, record) => ( | ||||
|         <Dropdown | ||||
|           menu={{ | ||||
|             items: [ | ||||
|               { | ||||
|                 key: 'edit', | ||||
|                 label: 'Edit', | ||||
|                 icon: <EditOutlined />, | ||||
|                 onClick: () => handleEdit(record) | ||||
|               }, | ||||
|               { | ||||
|                 key: 'delete', | ||||
|                 label: 'Delete', | ||||
|                 icon: <DeleteOutlined />, | ||||
|                 danger: true, | ||||
|                 onClick: () => handleDelete(record.id) | ||||
|               } | ||||
|             ] | ||||
|           }} | ||||
|           trigger={['click']} | ||||
|         > | ||||
|           <Button type="text" icon={<EllipsisOutlined />} /> | ||||
|         </Dropdown> | ||||
|       ), | ||||
|     }, | ||||
|     { | ||||
|       title: 'Name', | ||||
|       dataIndex: 'sequence_name', | ||||
|       key: 'sequence_name', | ||||
|     }, | ||||
|     { | ||||
|       title: 'Sequence Code', | ||||
|       dataIndex: 'sequence_code', | ||||
|       key: 'sequence_code', | ||||
|     }, | ||||
|     { | ||||
|       title: 'Current No', | ||||
|       dataIndex: 'current_no', | ||||
|       key: 'current_no', | ||||
|     }, | ||||
|     { | ||||
|       title: 'Demonstration', | ||||
|       dataIndex: 'demonstration', | ||||
|       key: 'demonstration', | ||||
|     } | ||||
|   ]; | ||||
| 
 | ||||
|   return ( | ||||
|     <div className="sequence-generator-container"> | ||||
|       {error && ( | ||||
|         <Alert | ||||
|           message="Error" | ||||
|           description={error} | ||||
|           type="error" | ||||
|           showIcon | ||||
|           closable | ||||
|           onClose={() => setError(null)} | ||||
|           style={{ marginBottom: 16 }} | ||||
|         /> | ||||
|       )} | ||||
| 
 | ||||
|       <div style={{ marginBottom: 16, display: 'flex', justifyContent: 'space-between' }}> | ||||
|         <h2>Document Sequence</h2> | ||||
|         <Button  | ||||
|           type="primary"  | ||||
|           icon={<PlusOutlined />}  | ||||
|           onClick={handleCreate} | ||||
|         > | ||||
|           Add Sequence | ||||
|         </Button> | ||||
|       </div> | ||||
| 
 | ||||
|       <Table  | ||||
|         columns={columns}  | ||||
|         dataSource={sequences}  | ||||
|         rowKey="id" | ||||
|         loading={loading} | ||||
|         pagination={{ | ||||
|           pageSize: 10, | ||||
|           showSizeChanger: true, | ||||
|           showTotal: (total) => `Total ${total} sequences`, | ||||
|         }} | ||||
|       /> | ||||
| 
 | ||||
|       <Modal | ||||
|         title={<span style={{ fontWeight: 'bold' }}>Update Sequence Generator</span>} | ||||
|         open={visible} | ||||
|         onOk={handleSubmit} | ||||
|         onCancel={() => setVisible(false)} | ||||
|         confirmLoading={loading} | ||||
|         width={700} | ||||
|       > | ||||
|         {currentSequence && ( | ||||
|           <div style={{  | ||||
|             marginLeft: 20,  | ||||
|             marginBottom: 24, | ||||
|             border: '1px solid #d9d9d9', | ||||
|             borderRadius: 4, | ||||
|             padding: 16, | ||||
|             backgroundColor: '#fafafa' | ||||
|           }}> | ||||
|             <table style={{ width: '100%', borderCollapse: 'collapse' }}> | ||||
|               <tbody> | ||||
|                 <tr> | ||||
|                   <td style={{  | ||||
|                     padding: '8px 16px',  | ||||
|                     borderBottom: '1px solid #e8e8e8', | ||||
|                     fontWeight: 'bold', | ||||
|                     width: '30%' | ||||
|                   }}>Sequence ID</td> | ||||
|                   <td style={{  | ||||
|                     padding: '8px 16px',  | ||||
|                     borderBottom: '1px solid #e8e8e8' | ||||
|                   }}>{currentSequence.id}</td> | ||||
|                 </tr> | ||||
|                 <tr> | ||||
|                   <td style={{  | ||||
|                     padding: '8px 16px',  | ||||
|                     fontWeight: 'bold' | ||||
|                   }}>Demonstration</td> | ||||
|                   <td style={{ padding: '8px 16px' }}> | ||||
|                     <div style={{  | ||||
|                       backgroundColor: '#f5f5f5', | ||||
|                       padding: 8, | ||||
|                       textAlign: 'center', | ||||
|                       borderRadius: 4, | ||||
|                       fontWeight: 'bold' | ||||
|                     }}> | ||||
|                       {currentSequence.demonstration} | ||||
|                     </div> | ||||
|                   </td> | ||||
|                 </tr> | ||||
|               </tbody> | ||||
|             </table> | ||||
|           </div> | ||||
|         )} | ||||
| 
 | ||||
|         <Form form={form} layout="vertical" style={{ marginLeft: 20, marginRight: 20 }}> | ||||
|           <Form.Item | ||||
|             name="sequence_name" | ||||
|             label={<span style={{ fontWeight: 'bold' }}>Name*</span>} | ||||
|             rules={[{ required: true, message: 'Please input the sequence name!' }]} | ||||
|           > | ||||
|             <Input /> | ||||
|           </Form.Item> | ||||
| 
 | ||||
|           <Form.Item | ||||
|             name="sequence_code" | ||||
|             label={<span style={{ fontWeight: 'bold' }}>Sequence Code</span>} | ||||
|           > | ||||
|             <Input /> | ||||
|           </Form.Item> | ||||
| 
 | ||||
|           <Form.Item | ||||
|             name="prefix" | ||||
|             label={<span style={{ fontWeight: 'bold' }}>Prefix*</span>} | ||||
|             rules={[{ required: true, message: 'Please input the prefix!' }]} | ||||
|           > | ||||
|             <Input /> | ||||
|           </Form.Item> | ||||
| 
 | ||||
|           <Form.Item | ||||
|             name="suffix" | ||||
|             label={<span style={{ fontWeight: 'bold' }}>Suffix</span>} | ||||
|           > | ||||
|             <Input /> | ||||
|           </Form.Item> | ||||
| 
 | ||||
|           <Form.Item | ||||
|             name="seperator" | ||||
|             label={<span style={{ fontWeight: 'bold' }}>Separator</span>} | ||||
|           > | ||||
|             <Input /> | ||||
|           </Form.Item> | ||||
| 
 | ||||
|           <Form.Item | ||||
|             name="starting_no" | ||||
|             label={<span style={{ fontWeight: 'bold' }}>Starting No</span>} | ||||
|           > | ||||
|             <InputNumber min={1} style={{ width: '100%' }} /> | ||||
|           </Form.Item> | ||||
| 
 | ||||
|           <Form.Item | ||||
|             name="current_no" | ||||
|             label={<span style={{ fontWeight: 'bold' }}>Current No</span>} | ||||
|           > | ||||
|             <InputNumber min={1} style={{ width: '100%' }} /> | ||||
|           </Form.Item> | ||||
|         </Form> | ||||
|       </Modal> | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export default SequenceGenerator; | ||||
							
								
								
									
										80
									
								
								src/components/Dashboard/sequencegeneratorapi.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/components/Dashboard/sequencegeneratorapi.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,80 @@ | ||||
| import axios from 'axios'; | ||||
| import { getToken } from '../../utils/tokenService.js'; | ||||
| 
 | ||||
| const API_BASE_URL = process.env.REACT_APP_API_URL || ''; | ||||
| 
 | ||||
| const api = axios.create({ | ||||
|   baseURL: API_BASE_URL, | ||||
|   headers: { | ||||
|     'Content-Type': 'application/json' | ||||
|   } | ||||
| }); | ||||
| 
 | ||||
| // Add request interceptor to attach token
 | ||||
| api.interceptors.request.use((config) => { | ||||
|   // Always get fresh token for each request
 | ||||
|   const token = getToken(); | ||||
|   console.log('[API] Current token:', token); // Log the token
 | ||||
|   console.log('[API] Making request to:', config.url); // Log the request URL
 | ||||
|    | ||||
|   if (token) { | ||||
|     config.headers.Authorization = `Bearer ${token}`; | ||||
|   } else { | ||||
|     console.warn('No authToken found for request!'); | ||||
|   } | ||||
|    | ||||
|   return config; | ||||
| }, (error) => { | ||||
|   console.error('[API] Request error:', error); | ||||
|   return Promise.reject(error); | ||||
| }); | ||||
| 
 | ||||
| // ... rest of the interceptors and API methods remain the same ...
 | ||||
| 
 | ||||
| // Add response interceptor to log responses
 | ||||
| api.interceptors.response.use((response) => { | ||||
|   console.log('[API] Response received:', { | ||||
|     status: response.status, | ||||
|     url: response.config.url, | ||||
|     data: response.data | ||||
|   }); | ||||
|   return response; | ||||
| }, (error) => { | ||||
|   console.error('[API] Response error:', { | ||||
|     status: error.response?.status, | ||||
|     url: error.config?.url, | ||||
|     message: error.message, | ||||
|     response: error.response?.data | ||||
|   }); | ||||
|   return Promise.reject(error); | ||||
| }); | ||||
| 
 | ||||
| const SequenceGeneratorAPI = { | ||||
|   getAll: async () => { | ||||
|     try { | ||||
|       console.log('[API] Fetching all sequences'); // Additional log
 | ||||
|       const response = await api.get('/sureserve/sequence/seq'); | ||||
|       return response.data; | ||||
|     } catch (error) { | ||||
|       console.error('[API] Error fetching sequences:', error); | ||||
|       throw error; | ||||
|     } | ||||
|   }, | ||||
| 
 | ||||
|   getById: async (id) => { | ||||
|     try { | ||||
|       console.log(`[API] Fetching sequence with ID: ${id}`); | ||||
|       const response = await api.get(`/sureserve/sequence/seq/${id}`); | ||||
|       return response.data; | ||||
|     } catch (error) { | ||||
|       console.error(`[API] Error fetching sequence ${id}:`, error); | ||||
|       throw error; | ||||
|     } | ||||
|   }, | ||||
| 
 | ||||
|   create: async (data) => api.post('/sureserve/sequence/seq', data), // ✅ Make sure this exists
 | ||||
|   update: async (id, data) => api.put(`/sureserve/sequence/seq/${id}`, data), | ||||
|   delete: async (id) => api.delete(`/sureserve/sequence/seq/${id}`), | ||||
| }; | ||||
| 
 | ||||
| export default SequenceGeneratorAPI; | ||||
							
								
								
									
										88
									
								
								src/components/Dashboard/tokenregistryapi.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								src/components/Dashboard/tokenregistryapi.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,88 @@ | ||||
| // src/services/tokenRegistryAPI.js
 | ||||
| import axios from 'axios'; | ||||
| import { getToken } from '../../utils/tokenService.js'; | ||||
| 
 | ||||
| // Create axios instance with base configuration
 | ||||
| const apiClient = axios.create({ | ||||
|   baseURL: process.env.REACT_APP_API_URL || 'http://157.66.191.31:33730/back/', | ||||
| }); | ||||
| 
 | ||||
| // Add request interceptor to inject token
 | ||||
| apiClient.interceptors.request.use((config) => { | ||||
|   const token = getToken(); | ||||
|   if (token) { | ||||
|     config.headers.Authorization = `Bearer ${token}`; | ||||
|   } | ||||
|   return config; | ||||
| }, (error) => { | ||||
|   return Promise.reject(error); | ||||
| }); | ||||
| 
 | ||||
| // Response interceptor for error handling
 | ||||
| apiClient.interceptors.response.use( | ||||
|   (response) => response.data, | ||||
|   (error) => { | ||||
|     if (error.response) { | ||||
|       // Handle specific status codes
 | ||||
|       if (error.response.status === 401) { | ||||
|         // Handle unauthorized (token expired)
 | ||||
|         console.error('Authentication failed'); | ||||
|       } | ||||
|       throw new Error(error.response.data.message || 'Request failed'); | ||||
|     } | ||||
|     throw new Error(error.message || 'Network error'); | ||||
|   } | ||||
| ); | ||||
| 
 | ||||
| export const fetchAllTokens = async () => { | ||||
|   try { | ||||
|     return await apiClient.get('apiregistery/getall'); | ||||
|   } catch (error) { | ||||
|     console.error('Fetch tokens error:', error); | ||||
|     throw error; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| export const generateToken = async (token_name) => { | ||||
|   try { | ||||
|     return await apiClient.post( | ||||
|       'apiregistery/generateToken', | ||||
|       new URLSearchParams({ token_name }), | ||||
|       { | ||||
|         headers: { | ||||
|           'Content-Type': 'application/x-www-form-urlencoded' | ||||
|         } | ||||
|       } | ||||
|     ); | ||||
|   } catch (error) { | ||||
|     console.error('Generate token error:', error); | ||||
|     throw error; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| export const createToken = async (tokenData) => { | ||||
|   try { | ||||
|     return await apiClient.post('apiregistery/create', tokenData); | ||||
|   } catch (error) { | ||||
|     console.error('Create token error:', error); | ||||
|     throw error; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| export const updateToken = async (id, tokenData) => { | ||||
|   try { | ||||
|     return await apiClient.put(`apiregistery/update/${id}`, tokenData); | ||||
|   } catch (error) { | ||||
|     console.error('Update token error:', error); | ||||
|     throw error; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| export const deleteToken = async (id) => { | ||||
|   try { | ||||
|     return await apiClient.delete(`apiregistery/delete/${id}`); | ||||
|   } catch (error) { | ||||
|     console.error('Delete token error:', error); | ||||
|     throw error; | ||||
|   } | ||||
| }; | ||||
| @ -157,7 +157,7 @@ const Header = () => { | ||||
|   return ( | ||||
|     <> | ||||
|       <div | ||||
|         className="header bg-gradient-info pb-8 pt-7 pt-md-12" | ||||
|         className="header  pb-8 pt-7 pt-md-12" | ||||
|         style={{ marginTop: "6rem" }} | ||||
|       > | ||||
|         {" "} | ||||
|  | ||||
| @ -1,60 +1,31 @@ | ||||
| /*! | ||||
| 
 | ||||
| ========================================================= | ||||
| * Argon Dashboard React - v1.2.4 | ||||
| ========================================================= | ||||
| 
 | ||||
| * Product Page: https://www.creative-tim.com/product/argon-dashboard-react
 | ||||
| * Copyright 2024 Creative Tim (https://www.creative-tim.com)
 | ||||
| * Licensed under MIT (https://github.com/creativetimofficial/argon-dashboard-react/blob/master/LICENSE.md)
 | ||||
| 
 | ||||
| * Coded by Creative Tim | ||||
| 
 | ||||
| ========================================================= | ||||
| 
 | ||||
| * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||||
| 
 | ||||
| */ | ||||
| 
 | ||||
| // reactstrap components
 | ||||
| import { Button, Container, Row, Col } from "reactstrap"; | ||||
| 
 | ||||
| const UserHeader = () => { | ||||
| const UserHeader = ({ user }) => { | ||||
|   return ( | ||||
|     <> | ||||
|       <div | ||||
|         className="header pb-8 pt-5 pt-lg-8 d-flex align-items-center" | ||||
|         style={{ | ||||
|           minHeight: "600px", | ||||
|           backgroundImage: | ||||
|             "url(" + require("../../assets/img/theme/profile-cover.jpg") + ")", | ||||
|           backgroundSize: "cover", | ||||
|           backgroundPosition: "center top", | ||||
|         }} | ||||
|       > | ||||
|         {/* Mask */} | ||||
|         <span className="mask bg-gradient-default opacity-8" /> | ||||
|         {/* Header container */} | ||||
|         <Container className="d-flex align-items-center" fluid> | ||||
|           <Row> | ||||
|             <Col lg="7" md="10"> | ||||
|               <h1 className="display-2 text-white">Hello Jesse</h1> | ||||
|               <p className="text-white mt-0 mb-5"> | ||||
|                 This is your profile page. You can see the progress you've made | ||||
|                 with your work and manage your projects or assigned tasks | ||||
|               </p> | ||||
|               <Button | ||||
|                 color="info" | ||||
|                 href="#pablo" | ||||
|                 onClick={(e) => e.preventDefault()} | ||||
|               > | ||||
|                 Edit profile | ||||
|               </Button> | ||||
|             </Col> | ||||
|           </Row> | ||||
|         </Container> | ||||
|       </div> | ||||
|     </> | ||||
|     <div | ||||
|       className="header pb-8 pt-5 pt-lg-8 d-flex align-items-center" | ||||
|       style={{ | ||||
|         minHeight: "600px", | ||||
|         backgroundSize: "cover", | ||||
|         backgroundPosition: "center top", | ||||
|       }} | ||||
|     > | ||||
|       {/* Mask */} | ||||
|       <span className="mask bg-gradient-default opacity-8" /> | ||||
|       {/* Header container */} | ||||
|       <Container className="d-flex align-items-center" fluid> | ||||
|         <Row> | ||||
|           <Col lg="7" md="10"> | ||||
|             <h1 className="display-2 text-white"> | ||||
|               Hello {user?.firstName || "User"} | ||||
|             </h1> | ||||
|             <p className="text-white mt-0 mb-5"> | ||||
|               Welcome back, {user?.role || "team member"}! Manage your profile and activity here. | ||||
|             </p> | ||||
|           </Col> | ||||
|         </Row> | ||||
|       </Container> | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -9,6 +9,17 @@ | ||||
|   left: 0; | ||||
|   z-index: 1030; | ||||
| } | ||||
| .dropdown-submenu { | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
| .dropdown-submenu .dropdown-menu { | ||||
|   top: 0; | ||||
|   left: 100%; | ||||
|   margin-top: -6px; | ||||
|   margin-left: -1px; | ||||
|   border-radius: 0.25rem; | ||||
| } | ||||
| 
 | ||||
| /* Container */ | ||||
| .navbar-container { | ||||
| @ -153,21 +164,63 @@ body { | ||||
|   padding-top: 60px; | ||||
| } | ||||
| 
 | ||||
| /* Responsive */ | ||||
| @media (max-width: 768px) { | ||||
|   .navbar-container { | ||||
| @media (min-width: 992px) { | ||||
|   .mobile-sidebar-toggle { | ||||
|     display: none !important; | ||||
|   } | ||||
|   .mobile-right-sidebar { | ||||
|     display: none !important; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @media (max-width: 992px) { | ||||
|    | ||||
|   .mobile-sidebar-toggle { | ||||
|     display: block !important; | ||||
|     background: none; | ||||
|     border: none; | ||||
|     color: white; | ||||
|     font-size: 1.5rem; | ||||
|     margin-right: 1rem; | ||||
|   } | ||||
| 
 | ||||
|   .mobile-right-sidebar { | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     padding: 0.5rem; | ||||
|     position: fixed; | ||||
|     top: 68px; | ||||
|     right: 0; | ||||
|     background: #e8e8e8; | ||||
|     padding: 2rem; | ||||
|     z-index: 1050; | ||||
|     box-shadow: -2px 0 5px rgba(0, 0, 0, 0.2); | ||||
|     height: 100vh; | ||||
|     width: 240px; | ||||
|     gap: 1rem; | ||||
|     transform: translateX(100%); | ||||
|     transition: transform 0.3s ease-in-out; | ||||
|   } | ||||
|    | ||||
|   .mobile-right-sidebar.open { | ||||
|     transform: translateX(0); | ||||
|   } | ||||
| 
 | ||||
|   .mobile-right-sidebar .nav-icon { | ||||
|     color: #000; | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     font-size: 1rem; | ||||
|     gap: 0.5rem; | ||||
|     text-decoration: none; | ||||
|   } | ||||
| 
 | ||||
|   .mobile-right-sidebar .nav-icon:hover { | ||||
|     color: #0078b9; | ||||
|   } | ||||
| 
 | ||||
|   .nav-icons { | ||||
|     justify-content: center; | ||||
|     gap: 1rem; | ||||
|     display: none !important; | ||||
|   } | ||||
| 
 | ||||
|   .search-input-group { | ||||
|     width: 100%; | ||||
|     max-width: 300px; | ||||
|   } | ||||
| } | ||||
|    | ||||
| } | ||||
|  | ||||
| @ -1,19 +1,13 @@ | ||||
| import { useNavigate, Link } from "react-router-dom"; | ||||
| import { removeCurrentUser,getCurrentUser } from "../../utils/tokenService"; | ||||
| import { removeCurrentUser, getCurrentUser } from "../../utils/tokenService"; | ||||
| import React, { useState, useEffect } from 'react'; | ||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||
| import { faUser } from "@fortawesome/free-solid-svg-icons"; | ||||
| import { faUser, faBars } from "@fortawesome/free-solid-svg-icons"; | ||||
| import { | ||||
|   DropdownMenu, | ||||
|   DropdownItem, | ||||
|   UncontrolledDropdown, | ||||
|   DropdownToggle, | ||||
|   Form, | ||||
|   FormGroup, | ||||
|   InputGroupAddon, | ||||
|   InputGroupText, | ||||
|   Input, | ||||
|   InputGroup, | ||||
|   Navbar, | ||||
|   Nav, | ||||
|   Media, | ||||
| @ -22,118 +16,204 @@ import "./AdminNavbar.css"; | ||||
| import "bootstrap-icons/font/bootstrap-icons.css"; | ||||
| 
 | ||||
| const AdminNavbar = ({ brandText }) => { | ||||
|   const[currentUser,setCurrentUser]=useState(); | ||||
|   const [submenuOpen, setSubmenuOpen] = useState(false); | ||||
| 
 | ||||
|   const navigate = useNavigate(); | ||||
|   const [currentUser, setCurrentUser] = useState(); | ||||
|   const [sidebarOpen, setSidebarOpen] = useState(false); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     const user = getCurrentUser(); | ||||
|     console.log(user); | ||||
|     setCurrentUser(user); | ||||
|     console.log(currentUser); | ||||
|     if (!user) { | ||||
|       navigate("/login"); | ||||
|     } | ||||
|     if (!user) navigate("/login"); | ||||
|   }, []); | ||||
| 
 | ||||
|   console.log(brandText); | ||||
|   const navigate = useNavigate(); | ||||
| 
 | ||||
|   const handleLogout = () => { | ||||
|     removeCurrentUser(); | ||||
|     // localStorage.removeItem("authToken"); // Uncomment if needed
 | ||||
|     navigate("/login"); | ||||
|   }; | ||||
| 
 | ||||
|   const toggleSidebar = () => setSidebarOpen(!sidebarOpen); | ||||
| 
 | ||||
|   return ( | ||||
|     <Navbar className="navbar-top navbar-dark" expand="lg" id="navbar-main"> | ||||
|       <div className="navbar-container container-fluid"> | ||||
|         {/* Brand */} | ||||
|         <Link className="brand_name h4 mb-0 text-white text-uppercase" to="/"> | ||||
|           {brandText} | ||||
|         </Link> | ||||
|     <> | ||||
|       <Navbar className="navbar-top navbar-dark" expand={false} id="navbar-main"> | ||||
|       | ||||
|         <div className="navbar-container container-fluid"> | ||||
|           {/* Toggle sidebar on small screens */} | ||||
|           <button className="mobile-sidebar-toggle" onClick={toggleSidebar}> | ||||
|             <FontAwesomeIcon icon={faBars} /> | ||||
|           </button>     | ||||
| 
 | ||||
|         {/* Navigation Icons */} | ||||
|         <div className="nav-icons d-flex align-items-center"> | ||||
|           <Link to="/admin/index" className="nav-icon"> | ||||
|             <i className="fas fa-home" /> | ||||
|           <Link className="brand_name h4 mb-0 text-white text-uppercase" to="/"> | ||||
|             {brandText} | ||||
|           </Link> | ||||
|           <Link to="/admin/setting" className="nav-icon"> | ||||
|             <i className="ni ni-settings-gear-65" /> | ||||
|           </Link> | ||||
|           <Link to="/admin/dashboard-runner-all" className="nav-icon"> | ||||
|             <i className="bi bi-grid" /> | ||||
|           </Link> | ||||
|           <Link to="/admin/report-runner" className="nav-icon"> | ||||
|             <i className="ni ni-chart-bar-32" /> | ||||
|           </Link> | ||||
|           <Link to="/admin/user-report" className="nav-icon"> | ||||
|             <i className="ni ni-grid" /> | ||||
|           </Link> | ||||
|         </div> | ||||
| 
 | ||||
|         {/* Search and Profile */} | ||||
|         <div className="nav-right d-flex align-items-center"> | ||||
|           <Form className="navbar-search navbar-search-dark form-inline"> | ||||
|             {/* <FormGroup className="mb-0"> | ||||
|               <InputGroup className="input-group-alternative search-input-group"> | ||||
|                 <InputGroupAddon addonType="prepend"> | ||||
|                   <InputGroupText className="search-icon"> | ||||
|                     <i className="fas fa-search" /> | ||||
|                   </InputGroupText> | ||||
|                 </InputGroupAddon> | ||||
|                 <Input placeholder="Search" type="text" className="search-input" /> | ||||
|               </InputGroup> | ||||
|             </FormGroup> */} | ||||
|           </Form> | ||||
|           <div className="nav-icons d-none d-lg-flex"> | ||||
|             <Link to="/admin/index" className="nav-icon"> | ||||
|               <i className="fas fa-home" /> | ||||
|             </Link> | ||||
|             <Link to="/admin/setting" className="nav-icon"> | ||||
|               <i className="ni ni-settings-gear-65" /> | ||||
|             </Link> | ||||
|             <Link to="/admin/dashboard-runner-all" className="nav-icon"> | ||||
|               <i className="bi bi-grid" /> | ||||
|             </Link> | ||||
|             <Link to="/admin/report-runner" className="nav-icon"> | ||||
|               <i className="ni ni-chart-bar-32" /> | ||||
|             </Link> | ||||
|             <Link to="/admin/user-report" className="nav-icon"> | ||||
|               <i className="ni ni-grid" /> | ||||
|             </Link> | ||||
|           </div> | ||||
| 
 | ||||
|           <Nav className="align-items-center" navbar> | ||||
|             <UncontrolledDropdown nav> | ||||
|               <DropdownToggle className="pr-0" nav> | ||||
|                 <Media className="align-items-center"> | ||||
|                   <span className="avatar avatar-sm rounded-circle"> | ||||
|                     {/* <img | ||||
|                       alt="Profile" | ||||
|                       src={require("../../assets/img/theme/team-4-800x800.jpg")} | ||||
|                     /> */} | ||||
|                     <FontAwesomeIcon icon={faUser} /> | ||||
|                   </span> | ||||
|                   <Media className="ml-2 d-none d-lg-block"> | ||||
|                     <span className="brand_name mb-0 text-sm font-weight-bold text-white-50"> | ||||
|                       {currentUser ? currentUser.fullname : "Guest"} | ||||
| 
 | ||||
| 
 | ||||
|           {/* Right Sidebar for larger screens */} | ||||
|           <div className="nav-right d-none d-lg-flex align-items-center"> | ||||
|             <Nav className="align-items-center" navbar> | ||||
|               <UncontrolledDropdown nav> | ||||
|                 <DropdownToggle className="pr-0" nav> | ||||
|                   <Media className="align-items-center"> | ||||
|                     <span className="avatar avatar-sm rounded-circle"> | ||||
|                       <FontAwesomeIcon icon={faUser} /> | ||||
|                     </span> | ||||
|                     <Media className="ml-2 d-none d-lg-block"> | ||||
|                       <span className="brand_name mb-0 text-sm font-weight-bold text-white-50"> | ||||
|                         {currentUser ? currentUser.fullname : "Guest"} | ||||
|                       </span> | ||||
|                     </Media> | ||||
|                   </Media> | ||||
|                 </Media> | ||||
|               </DropdownToggle> | ||||
|               <DropdownMenu className="dropdown-menu-arrow" right> | ||||
|                 <DropdownItem className="noti-title" header tag="div"> | ||||
|                 </DropdownToggle> | ||||
|                 <DropdownMenu className="dropdown-menu-arrow" right> | ||||
|                 <DropdownItem header tag="div"> | ||||
|                   <h6 className="text-overflow m-0">Welcome!</h6> | ||||
|                 </DropdownItem> | ||||
|                 <DropdownItem to="/admin/user-profile" tag={Link}> | ||||
|                <DropdownItem to="/admin/about" tag={Link}> | ||||
|                 <i className="fas fa-info-circle" /> {/* Font Awesome alternative */} | ||||
|                 <span>About</span> | ||||
|               </DropdownItem> | ||||
|                <DropdownItem to="/admin/profile" tag={Link}> | ||||
|                   <i className="ni ni-single-02" /> | ||||
|                   <span>My profile</span> | ||||
|                 </DropdownItem> | ||||
|                 <DropdownItem to="/admin/user-profile" tag={Link}> | ||||
|                   <i className="ni ni-settings-gear-65" /> | ||||
|                   <span>Settings</span> | ||||
|                 </DropdownItem> | ||||
|                 <DropdownItem to="/admin/user-profile" tag={Link}> | ||||
|                 <DropdownItem to="/admin/dashboard-runner-all" tag={Link}> | ||||
|                   <i className="ni ni-calendar-grid-58" /> | ||||
|                   <span>Activity</span> | ||||
|                 </DropdownItem> | ||||
|                 <DropdownItem to="/admin/user-profile" tag={Link}> | ||||
|                   <i className="ni ni-support-16" /> | ||||
|                   <span>Support</span> | ||||
| 
 | ||||
|                 {/* Nested Language Dropdown */} | ||||
|                 <div | ||||
|                     className="dropdown-submenu" | ||||
|                     onMouseEnter={() => setSubmenuOpen(true)} | ||||
|                     onMouseLeave={() => setSubmenuOpen(false)} | ||||
|                   > | ||||
|                     <DropdownItem | ||||
|                       className="dropdown-toggle" | ||||
|                       toggle={false} | ||||
|                       onClick={() => setSubmenuOpen(!submenuOpen)} | ||||
|                     > | ||||
|                       <i className="ni ni-world" /> | ||||
|                       <span>Choose Language</span> | ||||
|                     </DropdownItem> | ||||
| 
 | ||||
|                     {submenuOpen && ( | ||||
|                       <div className="dropdown-menu show"> | ||||
|                         <DropdownItem onClick={() => handleLanguageSelect("en")}>English</DropdownItem> | ||||
|                         <DropdownItem onClick={() => handleLanguageSelect("hi")}>Hindi</DropdownItem> | ||||
|                         <DropdownItem onClick={() => handleLanguageSelect("ta")}>Tamil</DropdownItem> | ||||
|                         <DropdownItem onClick={() => handleLanguageSelect("te")}>Telugu</DropdownItem> | ||||
|                       </div> | ||||
|                     )} | ||||
|                   </div> | ||||
| 
 | ||||
|                 <DropdownItem to="/admin/resetpassword" tag={Link}> | ||||
|                   <i className="ni ni-lock-circle-open" /> | ||||
|                   <span>Reset Password</span> | ||||
|                 </DropdownItem> | ||||
|                 <DropdownItem divider /> | ||||
|                 <DropdownItem onClick={handleLogout}> | ||||
|                   <i className="ni ni-user-run" /> | ||||
|                   <span>Logout</span> | ||||
|                 </DropdownItem> | ||||
|               </DropdownMenu> | ||||
|             </UncontrolledDropdown> | ||||
|           </Nav> | ||||
| 
 | ||||
|                 </DropdownMenu> | ||||
|               </UncontrolledDropdown> | ||||
|                    | ||||
|             </Nav> | ||||
|           </div> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|           { /* Mobile Right Sidebar */} | ||||
|           <div className="nav-right-mobile d-flex d-lg-none align-items-center ml-auto"> | ||||
|               <Nav className="align-items-center" navbar> | ||||
|                 <UncontrolledDropdown nav> | ||||
|                   <DropdownToggle className="pr-0" nav> | ||||
|                     <Media className="align-items-center"> | ||||
|                       <span className="avatar avatar-sm rounded-circle"> | ||||
|                         <FontAwesomeIcon icon={faUser} /> | ||||
|                       </span> | ||||
|                     </Media> | ||||
|                   </DropdownToggle> | ||||
|                   <DropdownMenu className="dropdown-menu-arrow" right> | ||||
|                     <DropdownItem header tag="div"> | ||||
|                       <h6 className="text-overflow m-0">Welcome!</h6> | ||||
|                     </DropdownItem> | ||||
|                     <DropdownItem to="/admin/profile" tag={Link}> | ||||
|                       <i className="ni ni-single-02" /> | ||||
|                       <span>My profile</span> | ||||
|                     </DropdownItem> | ||||
|                     <DropdownItem to="/admin/dashboard-runner-all" tag={Link}> | ||||
|                       <i className="ni ni-calendar-grid-58" /> | ||||
|                       <span>Activity</span> | ||||
|                     </DropdownItem> | ||||
|                     <DropdownItem to="/admin/resetpassword" tag={Link}> | ||||
|                       <i className="ni ni-lock-circle-open" /> | ||||
|                       <span>Reset Password</span> | ||||
|                     </DropdownItem> | ||||
|                     <DropdownItem divider /> | ||||
|                     <DropdownItem onClick={handleLogout}> | ||||
|                       <i className="ni ni-user-run" /> | ||||
|                       <span>Logout</span> | ||||
|                     </DropdownItem> | ||||
|                   </DropdownMenu> | ||||
|                 </UncontrolledDropdown> | ||||
|               </Nav> | ||||
|             </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </Navbar> | ||||
|       </Navbar> | ||||
|            | ||||
|       {/* Mobile Sidebar */} | ||||
|           <div className={`mobile-right-sidebar ${sidebarOpen ? 'open' : ''}`}> | ||||
|              <Link to="/admin/index" className="nav-icon" onClick={toggleSidebar}> | ||||
|                 <i className="fas fa-home" />  | ||||
|               </Link> | ||||
|               <Link to="/admin/setting" className="nav-icon" onClick={toggleSidebar}> | ||||
|                 <i className="ni ni-settings-gear-65" /> </Link> | ||||
|               <Link to="/admin/dashboard-runner-all" className="nav-icon" onClick={toggleSidebar}> | ||||
|                 <i className="bi bi-grid" /> | ||||
|               </Link> | ||||
|               <Link to="/admin/report-runner" className="nav-icon" onClick={toggleSidebar}> | ||||
|                 <i className="ni ni-chart-bar-32" /> | ||||
|               </Link> | ||||
|               <Link to="/admin/user-report" className="nav-icon" onClick={toggleSidebar}> | ||||
|                 <i className="ni ni-grid" />  | ||||
|               </Link> | ||||
|                | ||||
|             </div> | ||||
|            | ||||
|        | ||||
|     </> | ||||
|   ); | ||||
|   const handleLanguageSelect = (lang) => { | ||||
|     localStorage.setItem("appLanguage", lang); | ||||
|     setSubmenuOpen(false);        // Close submenu
 | ||||
|     document.body.click();        // Close parent dropdown
 | ||||
|     window.location.reload();     // Or use i18n if configured
 | ||||
|   }; | ||||
|    | ||||
| }; | ||||
| 
 | ||||
| export default AdminNavbar; | ||||
| 
 | ||||
| export default AdminNavbar; | ||||
|  | ||||
| @ -77,10 +77,10 @@ | ||||
| 
 | ||||
| /* Adjust main content margin when sidebar is expanded/collapsed */ | ||||
| .main-content { | ||||
|   margin-left: 250px; | ||||
|   margin-left:250px; | ||||
|   transition: margin-left 0.3s ease; | ||||
| } | ||||
| 
 | ||||
| .main-content.sidebar-collapsed-main { | ||||
|   margin-left: 50px; | ||||
|   margin-left: 60px; | ||||
| } | ||||
| @ -1,54 +1,18 @@ | ||||
| import { useState, useEffect } from "react"; | ||||
| import { Link, useLocation } from "react-router-dom"; | ||||
| import { useState } from "react"; | ||||
| import { useNavigate } from "react-router-dom"; | ||||
| import PropTypes from "prop-types"; | ||||
| import { Sidebar as ProSidebar, Menu, MenuItem, SubMenu } from "react-pro-sidebar"; | ||||
| import { fetchMenuItems } from "../../APIServices/MenuAPI"; | ||||
| import routes from "routes.js"; | ||||
| import { | ||||
|   Sidebar as ProSidebar, | ||||
|   Menu, | ||||
|   MenuItem, | ||||
|   SubMenu, | ||||
| } from "react-pro-sidebar"; | ||||
| import { FaChevronLeft, FaChevronRight, FaDatabase, FaExclamationCircle } from "react-icons/fa"; | ||||
| import "../Sidebar/Sidebar.css"; | ||||
| 
 | ||||
| const Sidebar = (props) => { | ||||
|   const [menuItems, setMenuItems] = useState([]); | ||||
|   const [collapsed, setCollapsed] = useState(false); | ||||
|   const [error, setError] = useState(""); | ||||
|   const location = useLocation(); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     loadMenuItems(); | ||||
|   }, []); | ||||
| 
 | ||||
|   const loadMenuItems = async () => { | ||||
|     try { | ||||
|       const respdata = await fetchMenuItems(); | ||||
|       const data = respdata.data; | ||||
|       if (Array.isArray(data)) { | ||||
|         const dynamicRoutes = mapMenuToRoutes(data); | ||||
|         setMenuItems(dynamicRoutes); | ||||
|       } else if (data && typeof data === "object") { | ||||
|         const dynamicRoutes = mapMenuToRoutes([data]); | ||||
|         setMenuItems(dynamicRoutes); | ||||
|       } else { | ||||
|         console.error("Invalid menu data format:", data); | ||||
|         setError("Invalid menu data format."); | ||||
|       } | ||||
|     } catch (err) { | ||||
|       console.error("Error fetching menu items:", err); | ||||
|       setError(err.message || "Failed to fetch menu items."); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   const mapMenuToRoutes = (menuArray) => { | ||||
|     if (!Array.isArray(menuArray)) { | ||||
|       console.error('Expected an array for menuArray, received:', menuArray); | ||||
|       return []; | ||||
|     } | ||||
| 
 | ||||
|     return menuArray.map(menu => ({ | ||||
|       path: menu.path || '#', | ||||
|       name: menu.name || menu.menuName || '', | ||||
|       icon: menu.icon || 'bi bi-grid', | ||||
|       submenu: Array.isArray(menu.submenu) ? mapMenuToRoutes(menu.submenu) : [] | ||||
|     })); | ||||
|   }; | ||||
|   const [collapsed, setCollapsed] = useState(true); | ||||
|   const navigate = useNavigate(); | ||||
| 
 | ||||
|   const toggleSidebar = () => { | ||||
|     setCollapsed(!collapsed); | ||||
| @ -57,71 +21,41 @@ const Sidebar = (props) => { | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   const renderMenuItems = () => { | ||||
|     const allRoutes = [...routes, ...menuItems]; | ||||
| 
 | ||||
|     return allRoutes.map((route, key) => { | ||||
|       if (route.submenu && route.submenu.length > 0) { | ||||
|         return ( | ||||
|           <SubMenu | ||||
|             key={key} | ||||
|             label={route.name} | ||||
|             icon={<i className={route.icon} />} | ||||
|           > | ||||
|             {route.submenu.map((submenu, subKey) => ( | ||||
|               <MenuItem | ||||
|                 key={`${key}-${subKey}`} | ||||
|                 component={<Link to={submenu.path} />} | ||||
|                 icon={<i className={submenu.icon || "bi bi-grid"} />} | ||||
|               > | ||||
|                 {submenu.name} | ||||
|               </MenuItem> | ||||
|             ))} | ||||
|           </SubMenu> | ||||
|         ); | ||||
|       } | ||||
| 
 | ||||
|       return ( | ||||
|         <MenuItem | ||||
|           key={key} | ||||
|           component={<Link to={route.path} />} | ||||
|           icon={<i className={route.icon || "bi bi-grid"} />} | ||||
|         > | ||||
|           {route.name} | ||||
|         </MenuItem> | ||||
|       ); | ||||
|     }); | ||||
|   }; | ||||
| 
 | ||||
|   const { logo } = props; | ||||
| 
 | ||||
|   return ( | ||||
|     <div className="sidebar-wrapper"> | ||||
|       <ProSidebar | ||||
|         collapsed={collapsed} | ||||
|         className="app-sidebar" | ||||
|         backgroundColor="white" | ||||
|         backgroundColor="#e8e8e8" | ||||
|         width="220px" | ||||
|         collapsedWidth="30px" | ||||
|       > | ||||
|         <div className="sidebar-header"> | ||||
|           {/* {logo && ( | ||||
|             <Link to={logo.innerLink} className="logo-container"> | ||||
|               <img alt={logo.imgAlt} className="navbar-brand-img" src={logo.imgSrc} /> | ||||
|             </Link> | ||||
|           )} */} | ||||
|         <div className="sidebar-header d-flex justify-content-end px-2 pt-2"> | ||||
|           <button | ||||
|             className="sidebar-toggle-btn" | ||||
|             type="button" | ||||
|             className="sidebar-toggle-btn btn btn-link p-0" | ||||
|             onClick={toggleSidebar} | ||||
|             title={collapsed ? "Expand sidebar" : "Collapse sidebar"} | ||||
|           > | ||||
|             <i className={`bi ${collapsed ? "bi-chevron-right" : "bi-chevron-left"}`} /> | ||||
|             {collapsed ? <FaChevronRight /> : <FaChevronLeft />} | ||||
|           </button> | ||||
|         </div> | ||||
| 
 | ||||
|         <Menu> | ||||
|           {renderMenuItems()} | ||||
|           <SubMenu label="Transactions" icon={<FaExclamationCircle />}> | ||||
|             <MenuItem onClick={() => navigate("/admin/regform")}> | ||||
|               Regform | ||||
|             </MenuItem> | ||||
|             <MenuItem onClick={() => navigate("/admin/error404")}> | ||||
|               Additional container | ||||
|             </MenuItem> | ||||
|           </SubMenu> | ||||
| 
 | ||||
|           <MenuItem | ||||
|             icon={<FaDatabase />} | ||||
|             onClick={() => navigate("/admin/error404")} | ||||
|           > | ||||
|             Masters | ||||
|           </MenuItem> | ||||
|         </Menu> | ||||
|       </ProSidebar> | ||||
|     </div> | ||||
| @ -137,4 +71,4 @@ Sidebar.propTypes = { | ||||
|   onSidebarToggle: PropTypes.func, | ||||
| }; | ||||
| 
 | ||||
| export default Sidebar; | ||||
| export default Sidebar; | ||||
|  | ||||
| @ -70,7 +70,7 @@ const Admin = (props) => { | ||||
|       > | ||||
|          | ||||
|         {/* This is where the nested routes will render */} | ||||
|         <div className="px-0" style={{ marginTop: "100px" }}> | ||||
|         <div className="px-0" style={{ marginTop: "7rem" }}> | ||||
|           <Outlet /> | ||||
|         </div> | ||||
| 
 | ||||
|  | ||||
| @ -19,7 +19,7 @@ | ||||
| // import AccessTypeManagement from "components/Dashboard/AccessType";
 | ||||
| // import APIRegistry from "components/Dashboard/APIRegistry";
 | ||||
| // import TOKENRegistry from "components/Dashboard/TOKENRegistry";
 | ||||
| // import DataType1 from "components/Dashboard/DataType1";
 | ||||
| // import SequenceGenerator from "components/Dashboard/sequencegenerator";
 | ||||
| // import DataType2 from "components/Dashboard/DataType2";
 | ||||
| // import DataType3 from "components/Dashboard/DataType3";
 | ||||
| // import DataType4 from "components/Dashboard/DataType4";
 | ||||
| @ -210,7 +210,7 @@ | ||||
| //     path: "/datatype-1",
 | ||||
| //     name: "Datatype-1",
 | ||||
| //     icon: "fa-solid fa-utensils",
 | ||||
| //     component: <DataType1/>, // should be a component function or class
 | ||||
| //     component: <sequencegenerator/>, // should be a component function or class
 | ||||
| //     layout: "/admin",
 | ||||
| //     showInSidebar: false
 | ||||
| //   },
 | ||||
| @ -284,7 +284,7 @@ import MenuMaintenance from "components/Dashboard/MenuMaintenance"; | ||||
| import AccessTypeManagement from "components/Dashboard/AccessType"; | ||||
| import APIRegistry from "components/Dashboard/APIRegistry"; | ||||
| import TOKENRegistry from "components/Dashboard/TOKENRegistry"; | ||||
| import DataType1 from "components/Dashboard/DataType1"; | ||||
| import SequenceGenerator from "components/Dashboard/sequencegenerator"; | ||||
| import DataType2 from "components/Dashboard/DataType2"; | ||||
| import DataType3 from "components/Dashboard/DataType3"; | ||||
| import DataType4 from "components/Dashboard/DataType4"; | ||||
| @ -448,7 +448,7 @@ var routes = [ | ||||
|     path: "/admin/datatype-1", | ||||
|     name: "Datatype-1", | ||||
|     icon: "fa-solid fa-utensils", | ||||
|     component: <DataType1/>, // should be a component function or class
 | ||||
|     component: <SequenceGenerator/>, // should be a component function or class
 | ||||
|     layout: "/admin", | ||||
|     showInSidebar: false | ||||
|   }, | ||||
|  | ||||
| @ -81,285 +81,285 @@ const Index = (props) => { | ||||
|     setChartExample1Data("data" + index); | ||||
|   }; | ||||
|   return ( | ||||
|     <>Home Page</> | ||||
|     // <div >
 | ||||
|     // <>Home Page</>
 | ||||
|     <div > | ||||
| 
 | ||||
|     //   <Header />
 | ||||
|     //   <Sidebar menuData={menuData} />
 | ||||
|       <Header /> | ||||
|       <Sidebar menuData={menuData} /> | ||||
| 
 | ||||
| 
 | ||||
|     //   {/* Page content */}
 | ||||
|     //   <Container className="mt--7" fluid style={{ marginTop: "-4rem" }}>
 | ||||
|     //     <Row>
 | ||||
|     //       <Col className="mb-5 mb-xl-0" xl="8">
 | ||||
|     //         <Card className="bg-gradient-default shadow">
 | ||||
|     //           <CardHeader className="bg-transparent">
 | ||||
|     //             <Row className="align-items-center">
 | ||||
|     //               <div className="col">
 | ||||
|     //                 <h6 className="text-uppercase text-light ls-1 mb-1">
 | ||||
|     //                   Overview
 | ||||
|     //                 </h6>
 | ||||
|     //                 <h2 className="text-white mb-0">Sales value</h2>
 | ||||
|     //               </div>
 | ||||
|     //               <div className="col">
 | ||||
|     //                 <Nav className="justify-content-end" pills>
 | ||||
|     //                   <NavItem>
 | ||||
|     //                     <NavLink
 | ||||
|     //                       className={classnames("py-2 px-3", {
 | ||||
|     //                         active: activeNav === 1,
 | ||||
|     //                       })}
 | ||||
|     //                       href="#pablo"
 | ||||
|     //                       onClick={(e) => toggleNavs(e, 1)}
 | ||||
|     //                     >
 | ||||
|     //                       <span className="d-none d-md-block">Month</span>
 | ||||
|     //                       <span className="d-md-none">M</span>
 | ||||
|     //                     </NavLink>
 | ||||
|     //                   </NavItem>
 | ||||
|     //                   <NavItem>
 | ||||
|     //                     <NavLink
 | ||||
|     //                       className={classnames("py-2 px-3", {
 | ||||
|     //                         active: activeNav === 2,
 | ||||
|     //                       })}
 | ||||
|     //                       data-toggle="tab"
 | ||||
|     //                       href="#pablo"
 | ||||
|     //                       onClick={(e) => toggleNavs(e, 2)}
 | ||||
|     //                     >
 | ||||
|     //                       <span className="d-none d-md-block">Week</span>
 | ||||
|     //                       <span className="d-md-none">W</span>
 | ||||
|     //                     </NavLink>
 | ||||
|     //                   </NavItem>
 | ||||
|     //                 </Nav>
 | ||||
|     //               </div>
 | ||||
|     //             </Row>
 | ||||
|     //           </CardHeader>
 | ||||
|     //           <CardBody>
 | ||||
|     //             {/* Chart */}
 | ||||
|     //             <div className="chart">
 | ||||
|     //               {chartExample1[chartExample1Data] ? (
 | ||||
|     //                 <Line
 | ||||
|     //                   data={chartExample1[chartExample1Data]}
 | ||||
|     //                   options={chartExample1.options}
 | ||||
|     //                 />
 | ||||
|     //               ) : (
 | ||||
|     //                 <p>Loading chart...</p>
 | ||||
|     //               )}
 | ||||
|       {/* Page content */} | ||||
|       <Container className="mt--7" fluid style={{ marginTop: "-4rem" }}> | ||||
|         <Row> | ||||
|           <Col className="mb-5 mb-xl-0" xl="8"> | ||||
|             <Card className="bg-gradient-default shadow"> | ||||
|               <CardHeader className="bg-transparent"> | ||||
|                 <Row className="align-items-center"> | ||||
|                   <div className="col"> | ||||
|                     <h6 className="text-uppercase text-light ls-1 mb-1"> | ||||
|                       Overview | ||||
|                     </h6> | ||||
|                     <h2 className="text-white mb-0">Sales value</h2> | ||||
|                   </div> | ||||
|                   <div className="col"> | ||||
|                     <Nav className="justify-content-end" pills> | ||||
|                       <NavItem> | ||||
|                         <NavLink | ||||
|                           className={classnames("py-2 px-3", { | ||||
|                             active: activeNav === 1, | ||||
|                           })} | ||||
|                           href="#pablo" | ||||
|                           onClick={(e) => toggleNavs(e, 1)} | ||||
|                         > | ||||
|                           <span className="d-none d-md-block">Month</span> | ||||
|                           <span className="d-md-none">M</span> | ||||
|                         </NavLink> | ||||
|                       </NavItem> | ||||
|                       <NavItem> | ||||
|                         <NavLink | ||||
|                           className={classnames("py-2 px-3", { | ||||
|                             active: activeNav === 2, | ||||
|                           })} | ||||
|                           data-toggle="tab" | ||||
|                           href="#pablo" | ||||
|                           onClick={(e) => toggleNavs(e, 2)} | ||||
|                         > | ||||
|                           <span className="d-none d-md-block">Week</span> | ||||
|                           <span className="d-md-none">W</span> | ||||
|                         </NavLink> | ||||
|                       </NavItem> | ||||
|                     </Nav> | ||||
|                   </div> | ||||
|                 </Row> | ||||
|               </CardHeader> | ||||
|               <CardBody> | ||||
|                 {/* Chart */} | ||||
|                 <div className="chart"> | ||||
|                   {chartExample1[chartExample1Data] ? ( | ||||
|                     <Line | ||||
|                       data={chartExample1[chartExample1Data]} | ||||
|                       options={chartExample1.options} | ||||
|                     /> | ||||
|                   ) : ( | ||||
|                     <p>Loading chart...</p> | ||||
|                   )} | ||||
| 
 | ||||
|     //             </div>
 | ||||
|     //           </CardBody>
 | ||||
|     //         </Card>
 | ||||
|     //       </Col>
 | ||||
|     //       <Col xl="4">
 | ||||
|     //         <Card className="shadow">
 | ||||
|     //           <CardHeader className="bg-transparent">
 | ||||
|     //             <Row className="align-items-center">
 | ||||
|     //               <div className="col">
 | ||||
|     //                 <h6 className="text-uppercase text-muted ls-1 mb-1">
 | ||||
|     //                   Performance
 | ||||
|     //                 </h6>
 | ||||
|     //                 <h2 className="mb-0">Total orders</h2>
 | ||||
|     //               </div>
 | ||||
|     //             </Row>
 | ||||
|     //           </CardHeader>
 | ||||
|     //           <CardBody>
 | ||||
|     //             {/* Chart */}
 | ||||
|     //             <div className="chart">
 | ||||
|     //               <Bar
 | ||||
|     //                 data={chartExample2.data}
 | ||||
|     //                 options={chartExample2.options}
 | ||||
|     //               />
 | ||||
|     //             </div>
 | ||||
|     //           </CardBody>
 | ||||
|     //         </Card>
 | ||||
|     //       </Col>
 | ||||
|     //     </Row>
 | ||||
|     //     <Row className="mt-5">
 | ||||
|     //       <Col className="mb-5 mb-xl-0" xl="8">
 | ||||
|     //         <Card className="shadow">
 | ||||
|     //           <CardHeader className="border-0">
 | ||||
|     //             <Row className="align-items-center">
 | ||||
|     //               <div className="col">
 | ||||
|     //                 <h3 className="mb-0">Page visits</h3>
 | ||||
|     //               </div>
 | ||||
|     //               <div className="col text-right">
 | ||||
|     //                 <Button
 | ||||
|     //                   color="primary"
 | ||||
|     //                   href="#pablo"
 | ||||
|     //                   onClick={(e) => e.preventDefault()}
 | ||||
|     //                   size="sm"
 | ||||
|     //                 >
 | ||||
|     //                   See all
 | ||||
|     //                 </Button>
 | ||||
|     //               </div>
 | ||||
|     //             </Row>
 | ||||
|     //           </CardHeader>
 | ||||
|     //           <Table className="align-items-center table-flush" responsive>
 | ||||
|     //             <thead className="thead-light">
 | ||||
|     //               <tr>
 | ||||
|     //                 <th scope="col">Page name</th>
 | ||||
|     //                 <th scope="col">Visitors</th>
 | ||||
|     //                 <th scope="col">Unique users</th>
 | ||||
|     //                 <th scope="col">Bounce rate</th>
 | ||||
|     //               </tr>
 | ||||
|     //             </thead>
 | ||||
|     //             <tbody>
 | ||||
|     //               <tr>
 | ||||
|     //                 <th scope="row">/argon/</th>
 | ||||
|     //                 <td>4,569</td>
 | ||||
|     //                 <td>340</td>
 | ||||
|     //                 <td>
 | ||||
|     //                   <i className="fas fa-arrow-up text-success mr-3" /> 46,53%
 | ||||
|     //                 </td>
 | ||||
|     //               </tr>
 | ||||
|     //               <tr>
 | ||||
|     //                 <th scope="row">/argon/index.html</th>
 | ||||
|     //                 <td>3,985</td>
 | ||||
|     //                 <td>319</td>
 | ||||
|     //                 <td>
 | ||||
|     //                   <i className="fas fa-arrow-down text-warning mr-3" />{" "}
 | ||||
|     //                   46,53%
 | ||||
|     //                 </td>
 | ||||
|     //               </tr>
 | ||||
|     //               <tr>
 | ||||
|     //                 <th scope="row">/argon/charts.html</th>
 | ||||
|     //                 <td>3,513</td>
 | ||||
|     //                 <td>294</td>
 | ||||
|     //                 <td>
 | ||||
|     //                   <i className="fas fa-arrow-down text-warning mr-3" />{" "}
 | ||||
|     //                   36,49%
 | ||||
|     //                 </td>
 | ||||
|     //               </tr>
 | ||||
|     //               <tr>
 | ||||
|     //                 <th scope="row">/argon/tables.html</th>
 | ||||
|     //                 <td>2,050</td>
 | ||||
|     //                 <td>147</td>
 | ||||
|     //                 <td>
 | ||||
|     //                   <i className="fas fa-arrow-up text-success mr-3" /> 50,87%
 | ||||
|     //                 </td>
 | ||||
|     //               </tr>
 | ||||
|     //               <tr>
 | ||||
|     //                 <th scope="row">/argon/profile.html</th>
 | ||||
|     //                 <td>1,795</td>
 | ||||
|     //                 <td>190</td>
 | ||||
|     //                 <td>
 | ||||
|     //                   <i className="fas fa-arrow-down text-danger mr-3" />{" "}
 | ||||
|     //                   46,53%
 | ||||
|     //                 </td>
 | ||||
|     //               </tr>
 | ||||
|     //             </tbody>
 | ||||
|     //           </Table>
 | ||||
|     //         </Card>
 | ||||
|     //       </Col>
 | ||||
|     //       <Col xl="4">
 | ||||
|     //         <Card className="shadow">
 | ||||
|     //           <CardHeader className="border-0">
 | ||||
|     //             <Row className="align-items-center">
 | ||||
|     //               <div className="col">
 | ||||
|     //                 <h3 className="mb-0">Social traffic</h3>
 | ||||
|     //               </div>
 | ||||
|     //               <div className="col text-right">
 | ||||
|     //                 <Button
 | ||||
|     //                   color="primary"
 | ||||
|     //                   href="#pablo"
 | ||||
|     //                   onClick={(e) => e.preventDefault()}
 | ||||
|     //                   size="sm"
 | ||||
|     //                 >
 | ||||
|     //                   See all
 | ||||
|     //                 </Button>
 | ||||
|     //               </div>
 | ||||
|     //             </Row>
 | ||||
|     //           </CardHeader>
 | ||||
|     //           <Table className="align-items-center table-flush" responsive>
 | ||||
|     //             <thead className="thead-light">
 | ||||
|     //               <tr>
 | ||||
|     //                 <th scope="col">Referral</th>
 | ||||
|     //                 <th scope="col">Visitors</th>
 | ||||
|     //                 <th scope="col" />
 | ||||
|     //               </tr>
 | ||||
|     //             </thead>
 | ||||
|     //             <tbody>
 | ||||
|     //               <tr>
 | ||||
|     //                 <th scope="row">Facebook</th>
 | ||||
|     //                 <td>1,480</td>
 | ||||
|     //                 <td>
 | ||||
|     //                   <div className="d-flex align-items-center">
 | ||||
|     //                     <span className="mr-2">60%</span>
 | ||||
|     //                     <div>
 | ||||
|     //                       <Progress
 | ||||
|     //                         max="100"
 | ||||
|     //                         value="60"
 | ||||
|     //                         barClassName="bg-gradient-danger"
 | ||||
|     //                       />
 | ||||
|     //                     </div>
 | ||||
|     //                   </div>
 | ||||
|     //                 </td>
 | ||||
|     //               </tr>
 | ||||
|     //               <tr>
 | ||||
|     //                 <th scope="row">Facebook</th>
 | ||||
|     //                 <td>5,480</td>
 | ||||
|     //                 <td>
 | ||||
|     //                   <div className="d-flex align-items-center">
 | ||||
|     //                     <span className="mr-2">70%</span>
 | ||||
|     //                     <div>
 | ||||
|     //                       <Progress
 | ||||
|     //                         max="100"
 | ||||
|     //                         value="70"
 | ||||
|     //                         barClassName="bg-gradient-success"
 | ||||
|     //                       />
 | ||||
|     //                     </div>
 | ||||
|     //                   </div>
 | ||||
|     //                 </td>
 | ||||
|     //               </tr>
 | ||||
|     //               <tr>
 | ||||
|     //                 <th scope="row">Google</th>
 | ||||
|     //                 <td>4,807</td>
 | ||||
|     //                 <td>
 | ||||
|     //                   <div className="d-flex align-items-center">
 | ||||
|     //                     <span className="mr-2">80%</span>
 | ||||
|     //                     <div>
 | ||||
|     //                       <Progress max="100" value="80" />
 | ||||
|     //                     </div>
 | ||||
|     //                   </div>
 | ||||
|     //                 </td>
 | ||||
|     //               </tr>
 | ||||
|     //               <tr>
 | ||||
|     //                 <th scope="row">Instagram</th>
 | ||||
|     //                 <td>3,678</td>
 | ||||
|     //                 <td>
 | ||||
|     //                   <div className="d-flex align-items-center">
 | ||||
|     //                     <span className="mr-2">75%</span>
 | ||||
|     //                     <div>
 | ||||
|     //                       <Progress
 | ||||
|     //                         max="100"
 | ||||
|     //                         value="75"
 | ||||
|     //                         barClassName="bg-gradient-info"
 | ||||
|     //                       />
 | ||||
|     //                     </div>
 | ||||
|     //                   </div>
 | ||||
|     //                 </td>
 | ||||
|     //               </tr>
 | ||||
|     //               <tr>
 | ||||
|     //                 <th scope="row">twitter</th>
 | ||||
|     //                 <td>2,645</td>
 | ||||
|     //                 <td>
 | ||||
|     //                   <div className="d-flex align-items-center">
 | ||||
|     //                     <span className="mr-2">30%</span>
 | ||||
|     //                     <div>
 | ||||
|     //                       <Progress
 | ||||
|     //                         max="100"
 | ||||
|     //                         value="30"
 | ||||
|     //                         barClassName="bg-gradient-warning"
 | ||||
|     //                       />
 | ||||
|     //                     </div>
 | ||||
|     //                   </div>
 | ||||
|     //                 </td>
 | ||||
|     //               </tr>
 | ||||
|     //             </tbody>
 | ||||
|     //           </Table>
 | ||||
|     //         </Card>
 | ||||
|     //       </Col>
 | ||||
|     //     </Row>
 | ||||
|     //   </Container>
 | ||||
|     // </div>
 | ||||
|                 </div> | ||||
|               </CardBody> | ||||
|             </Card> | ||||
|           </Col> | ||||
|           <Col xl="4"> | ||||
|             <Card className="shadow"> | ||||
|               <CardHeader className="bg-transparent"> | ||||
|                 <Row className="align-items-center"> | ||||
|                   <div className="col"> | ||||
|                     <h6 className="text-uppercase text-muted ls-1 mb-1"> | ||||
|                       Performance | ||||
|                     </h6> | ||||
|                     <h2 className="mb-0">Total orders</h2> | ||||
|                   </div> | ||||
|                 </Row> | ||||
|               </CardHeader> | ||||
|               <CardBody> | ||||
|                 {/* Chart */} | ||||
|                 <div className="chart"> | ||||
|                   <Bar | ||||
|                     data={chartExample2.data} | ||||
|                     options={chartExample2.options} | ||||
|                   /> | ||||
|                 </div> | ||||
|               </CardBody> | ||||
|             </Card> | ||||
|           </Col> | ||||
|         </Row> | ||||
|         <Row className="mt-5"> | ||||
|           <Col className="mb-5 mb-xl-0" xl="8"> | ||||
|             <Card className="shadow"> | ||||
|               <CardHeader className="border-0"> | ||||
|                 <Row className="align-items-center"> | ||||
|                   <div className="col"> | ||||
|                     <h3 className="mb-0">Page visits</h3> | ||||
|                   </div> | ||||
|                   <div className="col text-right"> | ||||
|                     <Button | ||||
|                       color="primary" | ||||
|                       href="#pablo" | ||||
|                       onClick={(e) => e.preventDefault()} | ||||
|                       size="sm" | ||||
|                     > | ||||
|                       See all | ||||
|                     </Button> | ||||
|                   </div> | ||||
|                 </Row> | ||||
|               </CardHeader> | ||||
|               <Table className="align-items-center table-flush" responsive> | ||||
|                 <thead className="thead-light"> | ||||
|                   <tr> | ||||
|                     <th scope="col">Page name</th> | ||||
|                     <th scope="col">Visitors</th> | ||||
|                     <th scope="col">Unique users</th> | ||||
|                     <th scope="col">Bounce rate</th> | ||||
|                   </tr> | ||||
|                 </thead> | ||||
|                 <tbody> | ||||
|                   <tr> | ||||
|                     <th scope="row">/argon/</th> | ||||
|                     <td>4,569</td> | ||||
|                     <td>340</td> | ||||
|                     <td> | ||||
|                       <i className="fas fa-arrow-up text-success mr-3" /> 46,53% | ||||
|                     </td> | ||||
|                   </tr> | ||||
|                   <tr> | ||||
|                     <th scope="row">/argon/index.html</th> | ||||
|                     <td>3,985</td> | ||||
|                     <td>319</td> | ||||
|                     <td> | ||||
|                       <i className="fas fa-arrow-down text-warning mr-3" />{" "} | ||||
|                       46,53% | ||||
|                     </td> | ||||
|                   </tr> | ||||
|                   <tr> | ||||
|                     <th scope="row">/argon/charts.html</th> | ||||
|                     <td>3,513</td> | ||||
|                     <td>294</td> | ||||
|                     <td> | ||||
|                       <i className="fas fa-arrow-down text-warning mr-3" />{" "} | ||||
|                       36,49% | ||||
|                     </td> | ||||
|                   </tr> | ||||
|                   <tr> | ||||
|                     <th scope="row">/argon/tables.html</th> | ||||
|                     <td>2,050</td> | ||||
|                     <td>147</td> | ||||
|                     <td> | ||||
|                       <i className="fas fa-arrow-up text-success mr-3" /> 50,87% | ||||
|                     </td> | ||||
|                   </tr> | ||||
|                   <tr> | ||||
|                     <th scope="row">/argon/profile.html</th> | ||||
|                     <td>1,795</td> | ||||
|                     <td>190</td> | ||||
|                     <td> | ||||
|                       <i className="fas fa-arrow-down text-danger mr-3" />{" "} | ||||
|                       46,53% | ||||
|                     </td> | ||||
|                   </tr> | ||||
|                 </tbody> | ||||
|               </Table> | ||||
|             </Card> | ||||
|           </Col> | ||||
|           <Col xl="4"> | ||||
|             <Card className="shadow"> | ||||
|               <CardHeader className="border-0"> | ||||
|                 <Row className="align-items-center"> | ||||
|                   <div className="col"> | ||||
|                     <h3 className="mb-0">Social traffic</h3> | ||||
|                   </div> | ||||
|                   <div className="col text-right"> | ||||
|                     <Button | ||||
|                       color="primary" | ||||
|                       href="#pablo" | ||||
|                       onClick={(e) => e.preventDefault()} | ||||
|                       size="sm" | ||||
|                     > | ||||
|                       See all | ||||
|                     </Button> | ||||
|                   </div> | ||||
|                 </Row> | ||||
|               </CardHeader> | ||||
|               <Table className="align-items-center table-flush" responsive> | ||||
|                 <thead className="thead-light"> | ||||
|                   <tr> | ||||
|                     <th scope="col">Referral</th> | ||||
|                     <th scope="col">Visitors</th> | ||||
|                     <th scope="col" /> | ||||
|                   </tr> | ||||
|                 </thead> | ||||
|                 <tbody> | ||||
|                   <tr> | ||||
|                     <th scope="row">Facebook</th> | ||||
|                     <td>1,480</td> | ||||
|                     <td> | ||||
|                       <div className="d-flex align-items-center"> | ||||
|                         <span className="mr-2">60%</span> | ||||
|                         <div> | ||||
|                           <Progress | ||||
|                             max="100" | ||||
|                             value="60" | ||||
|                             barClassName="bg-gradient-danger" | ||||
|                           /> | ||||
|                         </div> | ||||
|                       </div> | ||||
|                     </td> | ||||
|                   </tr> | ||||
|                   <tr> | ||||
|                     <th scope="row">Facebook</th> | ||||
|                     <td>5,480</td> | ||||
|                     <td> | ||||
|                       <div className="d-flex align-items-center"> | ||||
|                         <span className="mr-2">70%</span> | ||||
|                         <div> | ||||
|                           <Progress | ||||
|                             max="100" | ||||
|                             value="70" | ||||
|                             barClassName="bg-gradient-success" | ||||
|                           /> | ||||
|                         </div> | ||||
|                       </div> | ||||
|                     </td> | ||||
|                   </tr> | ||||
|                   <tr> | ||||
|                     <th scope="row">Google</th> | ||||
|                     <td>4,807</td> | ||||
|                     <td> | ||||
|                       <div className="d-flex align-items-center"> | ||||
|                         <span className="mr-2">80%</span> | ||||
|                         <div> | ||||
|                           <Progress max="100" value="80" /> | ||||
|                         </div> | ||||
|                       </div> | ||||
|                     </td> | ||||
|                   </tr> | ||||
|                   <tr> | ||||
|                     <th scope="row">Instagram</th> | ||||
|                     <td>3,678</td> | ||||
|                     <td> | ||||
|                       <div className="d-flex align-items-center"> | ||||
|                         <span className="mr-2">75%</span> | ||||
|                         <div> | ||||
|                           <Progress | ||||
|                             max="100" | ||||
|                             value="75" | ||||
|                             barClassName="bg-gradient-info" | ||||
|                           /> | ||||
|                         </div> | ||||
|                       </div> | ||||
|                     </td> | ||||
|                   </tr> | ||||
|                   <tr> | ||||
|                     <th scope="row">twitter</th> | ||||
|                     <td>2,645</td> | ||||
|                     <td> | ||||
|                       <div className="d-flex align-items-center"> | ||||
|                         <span className="mr-2">30%</span> | ||||
|                         <div> | ||||
|                           <Progress | ||||
|                             max="100" | ||||
|                             value="30" | ||||
|                             barClassName="bg-gradient-warning" | ||||
|                           /> | ||||
|                         </div> | ||||
|                       </div> | ||||
|                     </td> | ||||
|                   </tr> | ||||
|                 </tbody> | ||||
|               </Table> | ||||
|             </Card> | ||||
|           </Col> | ||||
|         </Row> | ||||
|       </Container> | ||||
|      </div> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										34
									
								
								src/views/examples/Error404.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/views/examples/Error404.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| import React from 'react'; | ||||
| import { useNavigate } from 'react-router-dom'; | ||||
| import { Button } from 'react-bootstrap'; | ||||
| 
 | ||||
| const Error404 = () => { | ||||
|   const navigate = useNavigate(); | ||||
| 
 | ||||
|   return ( | ||||
|     <div | ||||
|       className="d-flex flex-column justify-content-center align-items-center vh-100" | ||||
|       style={{ backgroundColor: '#f7f7f7' }} | ||||
|     > | ||||
|       <div className="text-center"> | ||||
|         <div style={{ fontSize: '80px', color: '#f44336' }}> | ||||
|           <span style={{ fontSize: '100px' }}>🛡️❌</span> | ||||
|         </div> | ||||
|         <h1 style={{ color: 'red', fontWeight: 'bold' }}>error 404</h1> | ||||
|         <p style={{ color: '#555', fontSize: '18px' }}> | ||||
|           Not found your page requested. | ||||
|         </p> | ||||
| 
 | ||||
|         <Button | ||||
|           variant="primary" | ||||
|           className="mt-4" | ||||
|           onClick={() => navigate('/admin/index')} // Adjust path if needed
 | ||||
|         > | ||||
|           Go to home | ||||
|         </Button> | ||||
|       </div> | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export default Error404; | ||||
| @ -1,329 +1,325 @@ | ||||
| /*! | ||||
| // // // reactstrap components
 | ||||
| // // import {
 | ||||
| // //   Button,
 | ||||
| // //   Card,
 | ||||
| // //   CardHeader,
 | ||||
| // //   CardBody,
 | ||||
| // //   FormGroup,
 | ||||
| // //   Form,
 | ||||
| // //   Input,
 | ||||
| // //   Container,
 | ||||
| // //   Row,
 | ||||
| // //   Col,
 | ||||
| // // } from "reactstrap";
 | ||||
| // // // core components
 | ||||
| // // import UserHeader from "components/Headers/UserHeader.js";
 | ||||
| 
 | ||||
| ========================================================= | ||||
| * Argon Dashboard React - v1.2.4 | ||||
| ========================================================= | ||||
| // // const Profile = () => {
 | ||||
| // //   return (
 | ||||
| // //     <>
 | ||||
| // //       <UserHeader />
 | ||||
| // //       {/* Page content */}
 | ||||
| // //       {/* <Container className="mt--7" fluid>
 | ||||
| // //         <Row>
 | ||||
| // //           <Col xl="12">
 | ||||
| // //             <Card className="bg-secondary shadow">
 | ||||
| // //               <CardHeader className="bg-white border-0">
 | ||||
| // //                 <Row className="align-items-center">
 | ||||
| // //                   <Col xs="8">
 | ||||
| // //                     <h3 className="mb-0">My Profile Settings</h3>
 | ||||
| // //                   </Col>
 | ||||
| // //                 </Row>
 | ||||
| // //               </CardHeader>
 | ||||
| // //               <CardBody>
 | ||||
| // //                 <Form>
 | ||||
| // //                   <Row>
 | ||||
| // //                     <Col md="6">
 | ||||
| // //                       <FormGroup>
 | ||||
| // //                         <label>Your Full Name</label>
 | ||||
| // //                         <Input placeholder="Enter full name" type="text" />
 | ||||
| // //                       </FormGroup>
 | ||||
| // //                     </Col>
 | ||||
| // //                     <Col md="6">
 | ||||
| // //                       <FormGroup>
 | ||||
| // //                         <label>Pronouns</label>
 | ||||
| // //                         <Input placeholder="Enter pronouns" type="text" />
 | ||||
| // //                       </FormGroup>
 | ||||
| // //                     </Col>
 | ||||
| // //                   </Row>
 | ||||
| // //                   <Row>
 | ||||
| // //                     <Col md="6">
 | ||||
| // //                       <FormGroup>
 | ||||
| // //                         <label>Role</label>
 | ||||
| // //                         <Input placeholder="Enter role" type="text" />
 | ||||
| // //                       </FormGroup>
 | ||||
| // //                     </Col>
 | ||||
| // //                     <Col md="6">
 | ||||
| // //                       <FormGroup>
 | ||||
| // //                         <label>Department or Team</label>
 | ||||
| // //                         <Input placeholder="Enter department" type="text" />
 | ||||
| // //                       </FormGroup>
 | ||||
| // //                     </Col>
 | ||||
| // //                   </Row>
 | ||||
| // //                   <Row>
 | ||||
| // //                     <Col md="12">
 | ||||
| // //                       <FormGroup>
 | ||||
| // //                         <label>Email</label>
 | ||||
| // //                         <Input placeholder="Enter email" type="email" />
 | ||||
| // //                       </FormGroup>
 | ||||
| // //                     </Col>
 | ||||
| // //                   </Row>
 | ||||
| // //                   <FormGroup>
 | ||||
| // //                     <label>About Me</label>
 | ||||
| // //                     <Input
 | ||||
| // //                       type="textarea"
 | ||||
| // //                       rows="4"
 | ||||
| // //                       placeholder="Enter description"
 | ||||
| // //                     />
 | ||||
| // //                   </FormGroup>
 | ||||
| // //                   <Button color="primary" type="submit">
 | ||||
| // //                     Update
 | ||||
| // //                   </Button>
 | ||||
| // //                 </Form>
 | ||||
| // //               </CardBody>
 | ||||
| // //             </Card>
 | ||||
| // //           </Col>
 | ||||
| // //         </Row>
 | ||||
| // //       </Container>*/}
 | ||||
| // //      </> 
 | ||||
| // //   );
 | ||||
| // // };
 | ||||
| 
 | ||||
| * Product Page: https://www.creative-tim.com/product/argon-dashboard-react
 | ||||
| * Copyright 2024 Creative Tim (https://www.creative-tim.com)
 | ||||
| * Licensed under MIT (https://github.com/creativetimofficial/argon-dashboard-react/blob/master/LICENSE.md)
 | ||||
| // // export default Profile;
 | ||||
| 
 | ||||
| * Coded by Creative Tim | ||||
| // import React from 'react';
 | ||||
| // import { Link, useNavigate } from 'react-router-dom';
 | ||||
| // import 'bootstrap/dist/css/bootstrap.min.css';
 | ||||
| 
 | ||||
| ========================================================= | ||||
| // const Profile = () => {
 | ||||
| //   const navigate = useNavigate();
 | ||||
| 
 | ||||
| * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||||
| //   const handleLogout = () => {
 | ||||
| //     // Clear user session/token and redirect to login or homepage
 | ||||
| //     localStorage.removeItem("authToken");
 | ||||
| //     navigate('/auth/login');
 | ||||
| //   };
 | ||||
| 
 | ||||
| */ | ||||
| //   return (
 | ||||
| //     <div className="container mt-5">
 | ||||
| //       <h3 className="mb-4">My Profile Settings</h3>
 | ||||
| 
 | ||||
| // reactstrap components
 | ||||
| import { | ||||
|   Button, | ||||
|   Card, | ||||
|   CardHeader, | ||||
|   CardBody, | ||||
|   FormGroup, | ||||
|   Form, | ||||
|   Input, | ||||
|   Container, | ||||
|   Row, | ||||
|   Col, | ||||
| } from "reactstrap"; | ||||
| // core components
 | ||||
| import UserHeader from "components/Headers/UserHeader.js"; | ||||
| //       <div className="mb-3">
 | ||||
| //         <label>Your Full Name</label>
 | ||||
| //         <input type="text" className="form-control" value="sysadmin" readOnly />
 | ||||
| //       </div>
 | ||||
| 
 | ||||
| //       <div className="mb-3">
 | ||||
| //         <label>Pronouns</label>
 | ||||
| //         <input type="text" className="form-control" placeholder="Enter Pronouns" />
 | ||||
| //       </div>
 | ||||
| 
 | ||||
| //       <div className="mb-3">
 | ||||
| //         <label>Role</label>
 | ||||
| //         <input type="text" className="form-control" placeholder="Enter Role" />
 | ||||
| //       </div>
 | ||||
| 
 | ||||
| //       <div className="mb-3">
 | ||||
| //         <label>Department or Team</label>
 | ||||
| //         <input type="text" className="form-control" placeholder="Enter Department" />
 | ||||
| //       </div>
 | ||||
| 
 | ||||
| //       <div className="mb-3">
 | ||||
| //         <label>Email</label>
 | ||||
| //         <input type="email" className="form-control" value="sysadmin" readOnly />
 | ||||
| //       </div>
 | ||||
| 
 | ||||
| //       <div className="mb-3">
 | ||||
| //         <label>About Me</label>
 | ||||
| //         <textarea className="form-control" placeholder="Enter Description"></textarea>
 | ||||
| //       </div>
 | ||||
| 
 | ||||
| //       <button
 | ||||
| //         className="btn btn-primary mb-4"
 | ||||
| //         onClick={() => navigate('/error404')}
 | ||||
| //       >
 | ||||
| //         Update
 | ||||
| //       </button>
 | ||||
| 
 | ||||
| //       <hr />
 | ||||
| 
 | ||||
| //       <p><strong>Password:</strong> Change Password for your account <Link to="/auth/resetpassword">Change password</Link></p>
 | ||||
| 
 | ||||
| //       <hr />
 | ||||
| 
 | ||||
| //       <p><strong>Security:</strong> Logout of all sessions except this current browser <span style={{ color: 'blue', cursor: 'pointer' }} onClick={handleLogout}>Logout other sessions</span></p>
 | ||||
| 
 | ||||
| //       <hr />
 | ||||
| 
 | ||||
| //       <p><strong>Deactivation:</strong> Remove access to all organizations and workspace in CloudnSure <span style={{ color: 'blue', cursor: 'pointer' }} onClick={handleLogout}>Deactivate account</span></p>
 | ||||
| //     </div>
 | ||||
| //   );
 | ||||
| // };
 | ||||
| 
 | ||||
| // export default Profile;
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| import React, { useState, useRef } from 'react'; | ||||
| import { Link, useNavigate } from 'react-router-dom'; | ||||
| import 'bootstrap/dist/css/bootstrap.min.css'; | ||||
| 
 | ||||
| const Profile = () => { | ||||
|   const navigate = useNavigate(); | ||||
|   const [preview, setPreview] = useState(null); | ||||
|   const [selectedFile, setSelectedFile] = useState(null); | ||||
|   const fileInputRef = useRef(null); | ||||
| 
 | ||||
|   const handleLogout = () => { | ||||
|     localStorage.removeItem("authToken"); | ||||
|     navigate('/auth/login'); | ||||
|   }; | ||||
| 
 | ||||
|   const handleFileChange = (e) => { | ||||
|     const file = e.target.files[0]; | ||||
|     if (file) { | ||||
|       setSelectedFile(file); | ||||
|       const reader = new FileReader(); | ||||
|       reader.onloadend = () => { | ||||
|         setPreview(reader.result); | ||||
|       }; | ||||
|       reader.readAsDataURL(file); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   const triggerFileInput = () => { | ||||
|     fileInputRef.current.click(); | ||||
|   }; | ||||
| 
 | ||||
|   const handleCancel = () => { | ||||
|     setPreview(null); | ||||
|     setSelectedFile(null); | ||||
|     fileInputRef.current.value = ''; | ||||
|   }; | ||||
| 
 | ||||
|   const handleUpload = () => { | ||||
|     if (!selectedFile) return; | ||||
|      | ||||
|     // Here you would typically upload the file to your server
 | ||||
|     // For example:
 | ||||
|     // const formData = new FormData();
 | ||||
|     // formData.append('profileImage', selectedFile);
 | ||||
|     // fetch('/api/upload-profile-image', {
 | ||||
|     //   method: 'POST',
 | ||||
|     //   body: formData
 | ||||
|     // })
 | ||||
|     // .then(response => response.json())
 | ||||
|     // .then(data => {
 | ||||
|     //   console.log('Upload successful', data);
 | ||||
|     // })
 | ||||
|     // .catch(error => {
 | ||||
|     //   console.error('Upload error', error);
 | ||||
|     // });
 | ||||
| 
 | ||||
|     alert('Upload functionality would go here'); | ||||
|   }; | ||||
| 
 | ||||
|   return ( | ||||
|     <> | ||||
|       <UserHeader /> | ||||
|       {/* Page content */} | ||||
|       <Container className="mt--7" fluid> | ||||
|         <Row> | ||||
|           <Col className="order-xl-2 mb-5 mb-xl-0" xl="4"> | ||||
|             <Card className="card-profile shadow"> | ||||
|               <Row className="justify-content-center"> | ||||
|                 <Col className="order-lg-2" lg="3"> | ||||
|                   <div className="card-profile-image"> | ||||
|                     <a href="#pablo" onClick={(e) => e.preventDefault()}> | ||||
|                       <img | ||||
|                         alt="..." | ||||
|                         className="rounded-circle" | ||||
|                         src={require("../../assets/img/theme/team-4-800x800.jpg")} | ||||
|                       /> | ||||
|                     </a> | ||||
|                   </div> | ||||
|                 </Col> | ||||
|               </Row> | ||||
|               <CardHeader className="text-center border-0 pt-8 pt-md-4 pb-0 pb-md-4"> | ||||
|                 <div className="d-flex justify-content-between"> | ||||
|                   <Button | ||||
|                     className="mr-4" | ||||
|                     color="info" | ||||
|                     href="#pablo" | ||||
|                     onClick={(e) => e.preventDefault()} | ||||
|                     size="sm" | ||||
|                   > | ||||
|                     Connect | ||||
|                   </Button> | ||||
|                   <Button | ||||
|                     className="float-right" | ||||
|                     color="default" | ||||
|                     href="#pablo" | ||||
|                     onClick={(e) => e.preventDefault()} | ||||
|                     size="sm" | ||||
|                   > | ||||
|                     Message | ||||
|                   </Button> | ||||
|                 </div> | ||||
|               </CardHeader> | ||||
|               <CardBody className="pt-0 pt-md-4"> | ||||
|                 <Row> | ||||
|                   <div className="col"> | ||||
|                     <div className="card-profile-stats d-flex justify-content-center mt-md-5"> | ||||
|                       <div> | ||||
|                         <span className="heading">22</span> | ||||
|                         <span className="description">Friends</span> | ||||
|                       </div> | ||||
|                       <div> | ||||
|                         <span className="heading">10</span> | ||||
|                         <span className="description">Photos</span> | ||||
|                       </div> | ||||
|                       <div> | ||||
|                         <span className="heading">89</span> | ||||
|                         <span className="description">Comments</span> | ||||
|                       </div> | ||||
|                     </div> | ||||
|                   </div> | ||||
|                 </Row> | ||||
|                 <div className="text-center"> | ||||
|                   <h3> | ||||
|                     Jessica Jones | ||||
|                     <span className="font-weight-light">, 27</span> | ||||
|                   </h3> | ||||
|                   <div className="h5 font-weight-300"> | ||||
|                     <i className="ni location_pin mr-2" /> | ||||
|                     Bucharest, Romania | ||||
|                   </div> | ||||
|                   <div className="h5 mt-4"> | ||||
|                     <i className="ni business_briefcase-24 mr-2" /> | ||||
|                     Solution Manager - Creative Tim Officer | ||||
|                   </div> | ||||
|                   <div> | ||||
|                     <i className="ni education_hat mr-2" /> | ||||
|                     University of Computer Science | ||||
|                   </div> | ||||
|                   <hr className="my-4" /> | ||||
|                   <p> | ||||
|                     Ryan — the name taken by Melbourne-raised, Brooklyn-based | ||||
|                     Nick Murphy — writes, performs and records all of his own | ||||
|                     music. | ||||
|                   </p> | ||||
|                   <a href="#pablo" onClick={(e) => e.preventDefault()}> | ||||
|                     Show more | ||||
|                   </a> | ||||
|                 </div> | ||||
|               </CardBody> | ||||
|             </Card> | ||||
|           </Col> | ||||
|           <Col className="order-xl-1" xl="8"> | ||||
|             <Card className="bg-secondary shadow"> | ||||
|               <CardHeader className="bg-white border-0"> | ||||
|                 <Row className="align-items-center"> | ||||
|                   <Col xs="8"> | ||||
|                     <h3 className="mb-0">My account</h3> | ||||
|                   </Col> | ||||
|                   <Col className="text-right" xs="4"> | ||||
|                     <Button | ||||
|                       color="primary" | ||||
|                       href="#pablo" | ||||
|                       onClick={(e) => e.preventDefault()} | ||||
|                       size="sm" | ||||
|                     > | ||||
|                       Settings | ||||
|                     </Button> | ||||
|                   </Col> | ||||
|                 </Row> | ||||
|               </CardHeader> | ||||
|               <CardBody> | ||||
|                 <Form> | ||||
|                   <h6 className="heading-small text-muted mb-4"> | ||||
|                     User information | ||||
|                   </h6> | ||||
|                   <div className="pl-lg-4"> | ||||
|                     <Row> | ||||
|                       <Col lg="6"> | ||||
|                         <FormGroup> | ||||
|                           <label | ||||
|                             className="form-control-label" | ||||
|                             htmlFor="input-username" | ||||
|                           > | ||||
|                             Username | ||||
|                           </label> | ||||
|                           <Input | ||||
|                             className="form-control-alternative" | ||||
|                             defaultValue="lucky.jesse" | ||||
|                             id="input-username" | ||||
|                             placeholder="Username" | ||||
|                             type="text" | ||||
|                           /> | ||||
|                         </FormGroup> | ||||
|                       </Col> | ||||
|                       <Col lg="6"> | ||||
|                         <FormGroup> | ||||
|                           <label | ||||
|                             className="form-control-label" | ||||
|                             htmlFor="input-email" | ||||
|                           > | ||||
|                             Email address | ||||
|                           </label> | ||||
|                           <Input | ||||
|                             className="form-control-alternative" | ||||
|                             id="input-email" | ||||
|                             placeholder="jesse@example.com" | ||||
|                             type="email" | ||||
|                           /> | ||||
|                         </FormGroup> | ||||
|                       </Col> | ||||
|                     </Row> | ||||
|                     <Row> | ||||
|                       <Col lg="6"> | ||||
|                         <FormGroup> | ||||
|                           <label | ||||
|                             className="form-control-label" | ||||
|                             htmlFor="input-first-name" | ||||
|                           > | ||||
|                             First name | ||||
|                           </label> | ||||
|                           <Input | ||||
|                             className="form-control-alternative" | ||||
|                             defaultValue="Lucky" | ||||
|                             id="input-first-name" | ||||
|                             placeholder="First name" | ||||
|                             type="text" | ||||
|                           /> | ||||
|                         </FormGroup> | ||||
|                       </Col> | ||||
|                       <Col lg="6"> | ||||
|                         <FormGroup> | ||||
|                           <label | ||||
|                             className="form-control-label" | ||||
|                             htmlFor="input-last-name" | ||||
|                           > | ||||
|                             Last name | ||||
|                           </label> | ||||
|                           <Input | ||||
|                             className="form-control-alternative" | ||||
|                             defaultValue="Jesse" | ||||
|                             id="input-last-name" | ||||
|                             placeholder="Last name" | ||||
|                             type="text" | ||||
|                           /> | ||||
|                         </FormGroup> | ||||
|                       </Col> | ||||
|                     </Row> | ||||
|                   </div> | ||||
|                   <hr className="my-4" /> | ||||
|                   {/* Address */} | ||||
|                   <h6 className="heading-small text-muted mb-4"> | ||||
|                     Contact information | ||||
|                   </h6> | ||||
|                   <div className="pl-lg-4"> | ||||
|                     <Row> | ||||
|                       <Col md="12"> | ||||
|                         <FormGroup> | ||||
|                           <label | ||||
|                             className="form-control-label" | ||||
|                             htmlFor="input-address" | ||||
|                           > | ||||
|                             Address | ||||
|                           </label> | ||||
|                           <Input | ||||
|                             className="form-control-alternative" | ||||
|                             defaultValue="Bld Mihail Kogalniceanu, nr. 8 Bl 1, Sc 1, Ap 09" | ||||
|                             id="input-address" | ||||
|                             placeholder="Home Address" | ||||
|                             type="text" | ||||
|                           /> | ||||
|                         </FormGroup> | ||||
|                       </Col> | ||||
|                     </Row> | ||||
|                     <Row> | ||||
|                       <Col lg="4"> | ||||
|                         <FormGroup> | ||||
|                           <label | ||||
|                             className="form-control-label" | ||||
|                             htmlFor="input-city" | ||||
|                           > | ||||
|                             City | ||||
|                           </label> | ||||
|                           <Input | ||||
|                             className="form-control-alternative" | ||||
|                             defaultValue="New York" | ||||
|                             id="input-city" | ||||
|                             placeholder="City" | ||||
|                             type="text" | ||||
|                           /> | ||||
|                         </FormGroup> | ||||
|                       </Col> | ||||
|                       <Col lg="4"> | ||||
|                         <FormGroup> | ||||
|                           <label | ||||
|                             className="form-control-label" | ||||
|                             htmlFor="input-country" | ||||
|                           > | ||||
|                             Country | ||||
|                           </label> | ||||
|                           <Input | ||||
|                             className="form-control-alternative" | ||||
|                             defaultValue="United States" | ||||
|                             id="input-country" | ||||
|                             placeholder="Country" | ||||
|                             type="text" | ||||
|                           /> | ||||
|                         </FormGroup> | ||||
|                       </Col> | ||||
|                       <Col lg="4"> | ||||
|                         <FormGroup> | ||||
|                           <label | ||||
|                             className="form-control-label" | ||||
|                             htmlFor="input-country" | ||||
|                           > | ||||
|                             Postal code | ||||
|                           </label> | ||||
|                           <Input | ||||
|                             className="form-control-alternative" | ||||
|                             id="input-postal-code" | ||||
|                             placeholder="Postal code" | ||||
|                             type="number" | ||||
|                           /> | ||||
|                         </FormGroup> | ||||
|                       </Col> | ||||
|                     </Row> | ||||
|                   </div> | ||||
|                   <hr className="my-4" /> | ||||
|                   {/* Description */} | ||||
|                   <h6 className="heading-small text-muted mb-4">About me</h6> | ||||
|                   <div className="pl-lg-4"> | ||||
|                     <FormGroup> | ||||
|                       <label>About Me</label> | ||||
|                       <Input | ||||
|                         className="form-control-alternative" | ||||
|                         placeholder="A few words about you ..." | ||||
|                         rows="4" | ||||
|                         defaultValue="A beautiful Dashboard for Bootstrap 4. It is Free and | ||||
|                         Open Source." | ||||
|                         type="textarea" | ||||
|                       /> | ||||
|                     </FormGroup> | ||||
|                   </div> | ||||
|                 </Form> | ||||
|               </CardBody> | ||||
|             </Card> | ||||
|           </Col> | ||||
|         </Row> | ||||
|       </Container> | ||||
|     </> | ||||
|     <div className="container mt-5"> | ||||
|       <h3 className="mb-4">My Profile Settings</h3> | ||||
| 
 | ||||
|       {/* Simple Image Upload Section */} | ||||
|       <div className="mb-4"> | ||||
|         <h5>PROFILE PHOTO</h5> | ||||
|         <div className="d-flex align-items-center mb-3"> | ||||
|           <div className="me-3"> | ||||
|             {preview ? ( | ||||
|               <img  | ||||
|                 src={preview}  | ||||
|                 alt="Profile Preview"  | ||||
|                 style={{ width: '100px', height: '100px', borderRadius: '50%', objectFit: 'cover' }}  | ||||
|               /> | ||||
|             ) : ( | ||||
|               <div style={{ width: '100px', height: '100px', borderRadius: '50%', backgroundColor: '#f0f0f0' }}></div> | ||||
|             )} | ||||
|           </div> | ||||
|           <div> | ||||
|             <input | ||||
|               type="file" | ||||
|               ref={fileInputRef} | ||||
|               onChange={handleFileChange} | ||||
|               accept="image/*" | ||||
|               style={{ display: 'none' }} | ||||
|             /> | ||||
|             <button className="btn btn-outline-primary" onClick={triggerFileInput}> | ||||
|               Choose File | ||||
|             </button> | ||||
|           </div> | ||||
|         </div> | ||||
| 
 | ||||
|         {/* Action buttons - shown only when an image is selected */} | ||||
|         {preview && ( | ||||
|           <div className="d-flex justify-content-end gap-2 mt-3"> | ||||
|             <button className="btn btn-outline-secondary" onClick={handleCancel}> | ||||
|               Cancel | ||||
|             </button> | ||||
|             <button className="btn btn-primary" onClick={handleUpload}> | ||||
|               Upload | ||||
|             </button> | ||||
|           </div> | ||||
|         )} | ||||
|       </div> | ||||
| 
 | ||||
|       {/* Rest of the profile form */} | ||||
|       <div className="mb-3"> | ||||
|         <label>Your Full Name</label> | ||||
|         <input type="text" className="form-control" value="sysadmin" readOnly /> | ||||
|       </div> | ||||
| 
 | ||||
|       <div className="mb-3"> | ||||
|         <label>Pronouns</label> | ||||
|         <input type="text" className="form-control" placeholder="Enter Pronouns" /> | ||||
|       </div> | ||||
| 
 | ||||
|       <div className="mb-3"> | ||||
|         <label>Role</label> | ||||
|         <input type="text" className="form-control" placeholder="Enter Role" /> | ||||
|       </div> | ||||
| 
 | ||||
|       <div className="mb-3"> | ||||
|         <label>Department or Team</label> | ||||
|         <input type="text" className="form-control" placeholder="Enter Department" /> | ||||
|       </div> | ||||
| 
 | ||||
|       <div className="mb-3"> | ||||
|         <label>Email</label> | ||||
|         <input type="email" className="form-control" value="sysadmin" readOnly /> | ||||
|       </div> | ||||
| 
 | ||||
|       <div className="mb-3"> | ||||
|         <label>About Me</label> | ||||
|         <textarea className="form-control" placeholder="Enter Description"></textarea> | ||||
|       </div> | ||||
| 
 | ||||
|       <button | ||||
|         className="btn btn-primary mb-4" | ||||
|         onClick={() => navigate('/error404')} | ||||
|       > | ||||
|         Update Profile | ||||
|       </button> | ||||
| 
 | ||||
|       <hr /> | ||||
| 
 | ||||
|       <p><strong>Password:</strong> Change Password for your account <Link to="/admin/resetpassword">Change password</Link></p> | ||||
| 
 | ||||
|       <hr /> | ||||
| 
 | ||||
|       <p><strong>Security:</strong> Logout of all sessions except this current browser <span style={{ color: 'blue', cursor: 'pointer' }} onClick={handleLogout}>Logout other sessions</span></p> | ||||
| 
 | ||||
|       <hr /> | ||||
| 
 | ||||
|       <p><strong>Deactivation:</strong> Remove access to all organizations and workspace in CloudnSure <span style={{ color: 'blue', cursor: 'pointer' }} onClick={handleLogout}>Deactivate account</span></p> | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export default Profile; | ||||
| export default Profile; | ||||
							
								
								
									
										23
									
								
								src/views/examples/about.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/views/examples/about.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| // src/views/examples/about.js
 | ||||
| import React from "react"; | ||||
| 
 | ||||
| const About = () => ( | ||||
|   <div className="text-center p-4"> | ||||
|     <img | ||||
|   src="https://your-domain.com/about-image.png" | ||||
|   alt="About Us" | ||||
|   onError={(e) => { | ||||
|     e.target.onerror = null; | ||||
|     e.target.src = "https://via.placeholder.com/300x200?text=About+Image"; | ||||
|   }} | ||||
|   style={{ width: "300px", height: "200px", objectFit: "cover" }} | ||||
| /> | ||||
| 
 | ||||
|     <h1 className="text-4xl font-bold text-blue-600">About Us</h1> | ||||
|     <p className="mt-4 text-lg text-gray-600"> | ||||
|       Create new project for new users if you have access. If you don't have access, please contact the admin. | ||||
|     </p> | ||||
|   </div> | ||||
| ); | ||||
| 
 | ||||
| export default About; | ||||
							
								
								
									
										89
									
								
								src/views/examples/regform.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								src/views/examples/regform.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,89 @@ | ||||
| import React, { useState, useEffect } from "react"; | ||||
| import { Table, Button } from "react-bootstrap"; | ||||
| import { FaFilter } from "react-icons/fa"; | ||||
| 
 | ||||
| const Regform = () => { | ||||
|   const [data, setData] = useState([]); | ||||
|   const [loading, setLoading] = useState(true); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     const fetchData = async () => { | ||||
|       setLoading(true); | ||||
|       const dummyData = [ | ||||
|         { | ||||
|           name: "kk", | ||||
|           rollNumber: "101", | ||||
|           date: "2025-05-19", | ||||
|           email: "kab@dekatc.com", | ||||
|         }, | ||||
|         { | ||||
|           name: "b", | ||||
|           rollNumber: "1", | ||||
|           date: "2025-05-24", | ||||
|           email: "kab@gmail.com", | ||||
|         }, | ||||
|       ]; | ||||
|       setTimeout(() => { | ||||
|         setData(dummyData); | ||||
|         setLoading(false); | ||||
|       }, 500); | ||||
|     }; | ||||
| 
 | ||||
|     fetchData(); | ||||
|   }, []); | ||||
| 
 | ||||
|   return ( | ||||
|     <div className="container mt-5"> | ||||
|       <h3 className="mb-4">Registration Records</h3> | ||||
| 
 | ||||
|       {loading ? ( | ||||
|         <div className="text-center my-4">Loading...</div> | ||||
|       ) : ( | ||||
|         <> | ||||
|           {data.length === 0 ? ( | ||||
|             <div className="text-center my-4">No data available</div> | ||||
|           ) : ( | ||||
|             <Table striped bordered hover responsive> | ||||
|               <thead className="table-light"> | ||||
|                 <tr> | ||||
|                   <th> | ||||
|                     <input type="checkbox" disabled /> | ||||
|                   </th> | ||||
|                   <th> | ||||
|                     Name <FaFilter className="ms-1" /> | ||||
|                   </th> | ||||
|                   <th> | ||||
|                     Roll Number <FaFilter className="ms-1" /> | ||||
|                   </th> | ||||
|                   <th> | ||||
|                     Date Field <FaFilter className="ms-1" /> | ||||
|                   </th> | ||||
|                   <th>Email Field</th> | ||||
|                 </tr> | ||||
|               </thead> | ||||
|               <tbody> | ||||
|                 {data.map((entry, index) => ( | ||||
|                   <tr key={index}> | ||||
|                     <td> | ||||
|                       <input type="checkbox" /> | ||||
|                     </td> | ||||
|                     <td>{entry.name}</td> | ||||
|                     <td>{entry.rollNumber}</td> | ||||
|                     <td>{entry.date}</td> | ||||
|                     <td>{entry.email}</td> | ||||
|                   </tr> | ||||
|                 ))} | ||||
|               </tbody> | ||||
|             </Table> | ||||
|           )} | ||||
|         </> | ||||
|       )} | ||||
| 
 | ||||
|       <Button variant="outline-secondary" className="mt-3"> | ||||
|         Manage Columns | ||||
|       </Button> | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export default Regform; | ||||
| @ -1,140 +1,105 @@ | ||||
| 
 | ||||
| import React, { useState } from 'react'; | ||||
| import { useNavigate } from 'react-router-dom'; | ||||
| import { FaEye, FaEyeSlash } from 'react-icons/fa'; | ||||
| import 'bootstrap/dist/css/bootstrap.min.css'; | ||||
| 
 | ||||
| function ResetPassword() { | ||||
|     const [email, setEmail] = useState(''); | ||||
|     const [message, setMessage] = useState(''); | ||||
|     const [error, setError] = useState(''); | ||||
| const ResetPassword = () => { | ||||
|   const [oldPassword, setOldPassword] = useState(''); | ||||
|   const [newPassword, setNewPassword] = useState(''); | ||||
|   const [reenterPassword, setReenterPassword] = useState(''); | ||||
|   const [showPassword, setShowPassword] = useState(false); | ||||
|   const navigate = useNavigate(); | ||||
| 
 | ||||
|     const handleEmailChange = (e) => { | ||||
|         setEmail(e.target.value); | ||||
|     }; | ||||
|   const isFormValid = | ||||
|     oldPassword.trim() && | ||||
|     newPassword.trim().length >= 3 && | ||||
|     reenterPassword.trim(); | ||||
| 
 | ||||
|     const handleSubmit = async (e) => { | ||||
|         e.preventDefault(); | ||||
|         setMessage(""); | ||||
|         setError(""); | ||||
|      | ||||
|         const token = localStorage.getItem("authToken"); | ||||
|      | ||||
|         if (!token) { | ||||
|           setError("Authorization token is missing."); | ||||
|           return; | ||||
|         } | ||||
|      | ||||
|         try { | ||||
|           const response = await fetch(`${process.env.REACT_APP_API_URL}api/resources/forgotpassword`, { | ||||
|             method: "POST", | ||||
|             headers: { | ||||
|               "Content-Type": "application/json", | ||||
|               Authorization: `Bearer ${token}`, | ||||
|             }, | ||||
|             body: JSON.stringify({ email }), | ||||
|           }); | ||||
|      | ||||
|           const data = await response.json(); | ||||
|      | ||||
|           if (response.ok) { | ||||
|             setMessage("A reset link has been sent to your email address."); | ||||
|           } else { | ||||
|             setError(data.message || "There was an issue sending the reset link. Please try again."); | ||||
|           } | ||||
|         } catch (error) { | ||||
|           setError("An error occurred. Please try again later."); | ||||
|         } | ||||
|       }; | ||||
|     return ( | ||||
|         // <div className="position-fixed top-0 start-0 w-100 h-100 d-flex justify-content-center align-items-center" style={{ backgroundColor: 'gray' }}>
 | ||||
|         //     <div className="card p-5" style={{ borderRadius: '15px', width: '100%', maxWidth: '500px' }}>
 | ||||
|         //         <h5 className="text-center mb-4">Forgot My Username and Password</h5>
 | ||||
|         //         <p className="text-center mb-4">
 | ||||
|         //             By signing up, I agree to the CloudnSure <a href="/privacy-policy" target="_blank" rel="noopener noreferrer"><u>Privacy Policy</u></a> and <a href="/terms-of-service" target="_blank" rel="noopener noreferrer"><u>Terms of Service</u></a>.
 | ||||
|         //         </p>
 | ||||
|         //         <form onSubmit={handleSubmit}>
 | ||||
|         //             <div className="form-group mb-3">
 | ||||
|         //                 <label htmlFor="email">Email Address:</label>
 | ||||
|         //                 <input
 | ||||
|         //                     type="email"
 | ||||
|         //                     id="email"
 | ||||
|         //                     className="form-control"
 | ||||
|         //                     value={email}
 | ||||
|         //                     onChange={handleEmailChange}
 | ||||
|         //                     required
 | ||||
|         //                 />
 | ||||
|         //             </div>
 | ||||
|         //             <button type="submit" className="btn btn-block mb-2" style={{backgroundColor:" #007bff"}}>Send Reset Link</button>
 | ||||
|         //         </form>
 | ||||
|         //         {message && <p className="text-success text-center mt-3">{message}</p>}
 | ||||
|         //         {error && <p className="text-danger text-center mt-3">{error}</p>}
 | ||||
|         //     </div>
 | ||||
|         // </div>
 | ||||
|   const toggleShowPassword = () => { | ||||
|     setShowPassword(!showPassword); | ||||
|   }; | ||||
| 
 | ||||
|         <div | ||||
|   className="position-fixed top-0 start-0 w-100 h-100" | ||||
|   style={{ | ||||
|     backgroundColor: 'rgba(128, 128, 128, -0.1)', // Full-page background with slight transparency
 | ||||
|     zIndex: 1, // Ensure background is behind the card
 | ||||
|   }} | ||||
| > | ||||
|   <div | ||||
|     className="d-flex justify-content-center align-items-center h-100" | ||||
|     style={{ | ||||
|       position: 'relative', // Ensures proper stacking
 | ||||
|       zIndex: 2, // Ensures card stays above background
 | ||||
|     }} | ||||
|   > | ||||
|   const handleSubmit = (e) => { | ||||
|     e.preventDefault(); | ||||
|     navigate('/error404'); // Assuming your route path is /error404
 | ||||
|   }; | ||||
| 
 | ||||
|   return ( | ||||
|     <div | ||||
|       className="card shadow-lg p-5" | ||||
|       style={{ | ||||
|         borderRadius: '15px', | ||||
|         width: '100%', | ||||
|         maxWidth: '500px', | ||||
|         backgroundColor: '#fff', // Explicit white background for card
 | ||||
|         zIndex: 3, // Card always stays on top
 | ||||
|       }} | ||||
|       className="d-flex justify-content-center align-items-center vh-100" | ||||
|       style={{ backgroundColor: '#f7f7f7' }} | ||||
|     > | ||||
|       <h5 className="text-center mb-4">Forgot My Username and Password</h5> | ||||
|       <p className="text-center mb-4"> | ||||
|         By signing up, I agree to the CloudnSure{' '} | ||||
|         <a href="/privacy-policy" target="_blank" rel="noopener noreferrer"> | ||||
|           <u>Privacy Policy</u> | ||||
|         </a>{' '} | ||||
|         and{' '} | ||||
|         <a href="/terms-of-service" target="_blank" rel="noopener noreferrer"> | ||||
|           <u>Terms of Service</u> | ||||
|         </a>. | ||||
|       </p> | ||||
|       <form onSubmit={handleSubmit}> | ||||
|         <div className="form-group mb-3"> | ||||
|           <label htmlFor="email">Email Address:</label> | ||||
|           <input | ||||
|             type="email" | ||||
|             id="email" | ||||
|             className="form-control" | ||||
|             value={email} | ||||
|             onChange={handleEmailChange} | ||||
|             required | ||||
|           /> | ||||
|         </div> | ||||
|         <button | ||||
|           type="submit" | ||||
|           className="btn btn-block mb-2" | ||||
|           style={{ | ||||
|             backgroundColor: '#007bff', | ||||
|             color: '#fff', | ||||
|           }} | ||||
|         > | ||||
|           Send Reset Link | ||||
|         </button> | ||||
|       </form> | ||||
|       {message && <p className="text-success text-center mt-3">{message}</p>} | ||||
|       {error && <p className="text-danger text-center mt-3">{error}</p>} | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|       <div | ||||
|         className="p-5 shadow bg-white rounded" | ||||
|         style={{ maxWidth: '500px', width: '100%' }} | ||||
|       > | ||||
|         <h3 className="text-center mb-3">Please Reset Your Password</h3> | ||||
|         <p className="text-center text-muted mb-4">you're signed in as sysadmin</p> | ||||
| 
 | ||||
|        | ||||
|     ); | ||||
| } | ||||
|         <form onSubmit={handleSubmit}> | ||||
|           {[ | ||||
|             { label: 'Enter Old Password', value: oldPassword, setter: setOldPassword }, | ||||
|             { label: 'Enter New Password', value: newPassword, setter: setNewPassword }, | ||||
|             { label: 'Re-Enter New Password', value: reenterPassword, setter: setReenterPassword }, | ||||
|           ].map(({ label, value, setter }, index) => ( | ||||
|             <div key={index} className="form-group position-relative mb-3"> | ||||
|               <label>{label}</label> | ||||
|               <input | ||||
|                 type={showPassword ? 'text' : 'password'} | ||||
|                 className="form-control" | ||||
|                 placeholder={label} | ||||
|                 value={value} | ||||
|                 onChange={(e) => setter(e.target.value)} | ||||
|               /> | ||||
|               <span | ||||
|                 className="position-absolute" | ||||
|                 onClick={toggleShowPassword} | ||||
|                 style={{ | ||||
|                   top: '38px', | ||||
|                   right: '15px', | ||||
|                   cursor: 'pointer', | ||||
|                   color: '#999', | ||||
|                 }} | ||||
|               > | ||||
|                 {showPassword ? <FaEyeSlash /> : <FaEye />} | ||||
|               </span> | ||||
|             </div> | ||||
|           ))} | ||||
| 
 | ||||
|           <button | ||||
|             type="submit" | ||||
|             className="btn w-100" | ||||
|             style={{ | ||||
|               backgroundColor: isFormValid ? '#6c63ff' : '#d6d6ff', | ||||
|               color: '#fff', | ||||
|               textTransform: 'uppercase', | ||||
|               letterSpacing: '1px', | ||||
|             }} | ||||
|             disabled={!isFormValid} | ||||
|           > | ||||
|             Continue | ||||
|           </button> | ||||
|            | ||||
|         </form> | ||||
|         <div className="d-flex justify-content-between mt-4"> | ||||
|           <button | ||||
|             className="btn btn-outline-primary w-50 me-2" | ||||
|             onClick={() => navigate('/admin/index')} | ||||
|           > | ||||
|             Go to Home | ||||
|           </button> | ||||
| 
 | ||||
|           <button | ||||
|             className="btn btn-outline-primary w-50 ms-2" | ||||
|             onClick={() => navigate('/auth/login')} | ||||
|           > | ||||
|             Login | ||||
|           </button> | ||||
|           </div> | ||||
|         </div> | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export default ResetPassword; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user