diff --git a/Documentation/documentation.html b/Documentation/documentation.html index 3ff2949..dae821e 100644 --- a/Documentation/documentation.html +++ b/Documentation/documentation.html @@ -17,6 +17,7 @@ */ --> + @@ -136,7 +137,7 @@
@@ -157,7 +158,7 @@
-
+
>>>>>> 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", diff --git a/src/APIRequestService/APIService.js b/src/APIRequestService/APIService.js index f306539..00f80fe 100644 --- a/src/APIRequestService/APIService.js +++ b/src/APIRequestService/APIService.js @@ -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; diff --git a/src/APIServices/MenuMaintenanceAPI.js b/src/APIServices/MenuMaintenanceAPI.js index 09e226f..0d1f1d6 100644 --- a/src/APIServices/MenuMaintenanceAPI.js +++ b/src/APIServices/MenuMaintenanceAPI.js @@ -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; + } +}; \ No newline at end of file diff --git a/src/App.js b/src/App.js index 2f3f406..cdc3640 100644 --- a/src/App.js +++ b/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 const App = () => { return ( @@ -90,22 +93,28 @@ const App = () => { }> + } /> + } /> + } /> + }/> } /> } /> } /> + } /> + {/* Dynamic Routes */} } /> } /> } /> } /> - + } /> {/* Static Routes */} } /> } /> - + } /> + } /> } /> - } /> } /> } /> @@ -128,7 +137,7 @@ const App = () => { }/> }/> }/> - + {/* buildercomponents */} @@ -137,7 +146,6 @@ const App = () => { }> } /> } /> - } /> diff --git a/src/assets/css/argon-dashboard-react.css b/src/assets/css/argon-dashboard-react.css index 0708113..3e6c79c 100644 --- a/src/assets/css/argon-dashboard-react.css +++ b/src/assets/css/argon-dashboard-react.css @@ -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; diff --git a/src/assets/img/brand/micrologo.png b/src/assets/img/brand/micrologo.png new file mode 100644 index 0000000..7334d56 Binary files /dev/null and b/src/assets/img/brand/micrologo.png differ diff --git a/src/components/ChartConfigModal.js b/src/components/ChartConfigModal.js new file mode 100644 index 0000000..cee9daf --- /dev/null +++ b/src/components/ChartConfigModal.js @@ -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 ( + + Configure Chart + + handleChange('title', e.target.value)} + margin="dense" + /> + handleChange('showLegend', e.target.checked)} + /> + } + label="Show Chart Legend" + /> + handleChange('showLabel', e.target.checked)} + /> + } + label="Show Chart Label" + /> + handleChange('tableName', e.target.value)} + margin="dense" + /> + handleChange('xAxis', e.target.value)} + margin="dense" + > + {columns.map(col => ( + {col} + ))} + + handleChange('yAxis', e.target.value)} + margin="dense" + > + {columns.map(col => ( + {col} + ))} + + + + + + + + ); +}; + +export default ChartConfigModal; diff --git a/src/components/Dashboard/AccessType.js b/src/components/Dashboard/AccessType.js index a3c5696..b8b57e1 100644 --- a/src/components/Dashboard/AccessType.js +++ b/src/components/Dashboard/AccessType.js @@ -168,7 +168,7 @@ function AccessTypeManagement() { }; return ( -
+
{loading ? ( ):( diff --git a/src/components/Dashboard/CSS/CSS/CommonStyle.css b/src/components/Dashboard/CSS/CSS/CommonStyle.css index 6adaa25..c6f71c0 100644 --- a/src/components/Dashboard/CSS/CSS/CommonStyle.css +++ b/src/components/Dashboard/CSS/CSS/CommonStyle.css @@ -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; } diff --git a/src/components/Dashboard/CSS/CSS/SetupView.css b/src/components/Dashboard/CSS/CSS/SetupView.css index d6a63b6..0f8b110 100644 --- a/src/components/Dashboard/CSS/CSS/SetupView.css +++ b/src/components/Dashboard/CSS/CSS/SetupView.css @@ -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 */ } diff --git a/src/components/Dashboard/DynamicForm/DynamicForm2.js b/src/components/Dashboard/DynamicForm/DynamicForm2.js index e7de001..94405fa 100644 --- a/src/components/Dashboard/DynamicForm/DynamicForm2.js +++ b/src/components/Dashboard/DynamicForm/DynamicForm2.js @@ -184,7 +184,7 @@ const DynamicForm2 = () => { ); return ( -
+
{loading ? ( ) : ( diff --git a/src/components/Dashboard/DynamicForm/DynamicFormAdd.js b/src/components/Dashboard/DynamicForm/DynamicFormAdd.js index 0fc466f..f8b852a 100644 --- a/src/components/Dashboard/DynamicForm/DynamicFormAdd.js +++ b/src/components/Dashboard/DynamicForm/DynamicFormAdd.js @@ -296,7 +296,7 @@ function DynamicFormAdd() { return ( -
+
{loading ? ( ) : ( diff --git a/src/components/Dashboard/MenuAccessControl.js b/src/components/Dashboard/MenuAccessControl.js index 235f09d..60159f1 100644 --- a/src/components/Dashboard/MenuAccessControl.js +++ b/src/components/Dashboard/MenuAccessControl.js @@ -1,3 +1,771 @@ +// import React, { useState, useEffect } from "react"; +// import { +// Button, Dropdown, Modal, Form, Row, Col, InputGroup, +// FormControl, +// } from "react-bootstrap"; +// import { +// Table, Pagination, +// PaginationItem, +// PaginationLink, Input, Label +// } from 'reactstrap'; +// import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +// 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 { FaSearch, FaTimes } from "react-icons/fa"; +// import { BsJournals } from "react-icons/bs"; +// import Spinner from '../../UIComponants/Spinner'; +// import { getByUsrGrpId } from "APIServices/MenuAccessControlAPI"; +// import { toast } from "react-toastify"; +// import {getToken } from "../../utils/tokenService" +// import { faSync } from "@fortawesome/free-solid-svg-icons"; + +// function MenuAccessControl({ selected, Sync }) { +// const [loading, setLoading] = useState(true); +// const [menuItems, setMenuItems] = useState([]); +// const [menus, setMenus] = useState([]); +// const [showAddEditModal, setShowAddEditModal] = useState(false); +// const [selectedMenuId, setSelectedMenuId] = useState(null); +// const [usrgrp, setUsrgrp] = useState(1); +// const [allData, setAllData] = useState([]); + + +// const [currentMenuItem, setCurrentMenuItem] = useState({ +// menuId: "", +// menuItemName: "", +// accessLevel: "", +// isActive: false, +// view: false, // For View checkbox +// create: false, // For Create checkbox +// edit: false, // For Edit checkbox +// delete: false, // For Delete checkbox +// query: false, // For Query checkbox +// export: false, // For Export checkbox +// }); +// const [alldata, setAlldata] = useState([]); +// // const [slicedMenus, setSlicedMenus] = useState([]); +// const [toggle, setToggle] = useState(false); +// const [allMenus, setAllMenus] = useState([]); + +// const [currentPage, setCurrentPage] = useState(1); +// const [isEditing, setIsEditing] = useState(false); +// const [recordsPerPage, setRecordsPerPage] = useState(10); +// const [searchQuery, setSearchQuery] = useState(""); +// let [slicedMenus, setSlicedMenus] = useState([ +// { +// menuId: 1, +// view: false, +// create: false, +// edit: false, +// delete: false, +// query: false, +// export: false, +// isActive: true, +// }, +// { +// menuId: 2, +// view: false, +// create: false, +// edit: false, +// delete: false, +// query: false, +// export: false, +// isActive: false, +// }, +// ]); +// const [visibleColumns, setVisibleColumns] = useState({ +// No: true, +// menuId: true, +// menuItemName: true, +// view: true, +// create: true, +// edit: true, +// delete: true, +// query: true, +// export: true, +// isActive: true, +// actions: true +// }); + +// const [newItemData, setNewItemData] = useState({ + +// menuId: "", +// menuItemName: "", +// view: "", +// create: "", +// edit: "", +// delete: "", +// query: "", +// export: "", +// isActive: true, +// }); + +// useEffect(() => { +// // Simulate loading data +// setTimeout(() => { +// setLoading(false); +// }, 3000); // Simulated 3 seconds loading +// }, []); + +// useEffect(() => { +// const defaultGroup = 1; // or whatever default ID you want +// setUsrgrp(defaultGroup); // ✅ sets correctly +// }, []); + + +// useEffect(() => { +// const filtered = toggle +// ? allMenus.filter(item => Number(item.menuId) !== 0) +// : allMenus; + +// setSlicedMenus(filtered); +// }, [toggle, allMenus]); + +// useEffect(() => { +// const apiUrl = `${process.env.REACT_APP_API_URL}api/getAllUsrGrp`; +// // const token = localStorage.getItem("CurrentUser"); +// const token = getToken() +// const fetchMenuItems = 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(); +// console.log("Menu items fetched successfully:", data); +// setMenuItems(data); +// } catch (error) { +// console.error("Error fetching menu items:", error); +// } +// }; + + +// fetchMenuItems(); +// }, []); + +// useEffect(() => { +// fetchData(); +// }, []); +// useEffect(() => { +// if (usrgrp) { +// fetchData(); +// } +// }, [usrgrp]); + +// // const fetchData = async () => { +// // try { +// // const data = await getByUsrGrpId(usrgrp); +// // console.log("Data fetched successfully:", data); + +// // setAlldata(data); // Update the state with fetched data +// // toast.success("Data fetched successfully!"); +// // } catch (error) { +// // console.error('Error fetching data:', error); +// // toast.error("Failed to fetch data."); +// // } +// // }; + +// // const fetchData = async () => { +// // try { +// // console.log("Fetching data for usrgrp:", usrgrp); +// // const data = await getByUsrGrpId(usrgrp); +// // if (!data) { +// // console.error("Received undefined data"); +// // toast.error("Failed to fetch data."); +// // return; +// // } +// // console.log("Data fetched successfully:", data); +// // setAlldata(data); +// // toast.success("Data fetched successfully!"); +// // } catch (error) { +// // console.error("Error fetching data:", error); +// // toast.error("Failed to fetch data."); +// // } +// // }; + +// const fetchData = async () => { +// try { +// console.log("Calling getByUsrGrpId with usrgrp:", usrgrp); + +// const data = await getByUsrGrpId(usrgrp); // or your API call +// console.log("API response:", data); + +// const transformedData = data.map(item => ({ +// menuId: item.menuItemId.menuItemId, +// menuItemName: item.menuItemDesc || '', +// view: item.mvisible === "true", +// create: item.mcreate === "true", +// edit: item.medit === "true", +// delete: item.mdelete === "true", +// query: item.mquery === "true", +// export: item.mexport === "true", +// isActive: item.status === "Enable" +// })); + +// setAllMenus(transformedData); +// setSlicedMenus(transformedData); // initially show all +// } catch (error) { +// console.error("Fetch failed:", error); +// } +// }; + +// const idselected = (value) => { +// setSelectedMenuId(value); +// }; + +// const toggleColumn = (column) => { +// setVisibleColumns((prev) => ({ +// ...prev, +// [column]: !prev[column], +// })); +// }; + +// const handleInputChange = (event, menuId) => { +// const { name, value, checked, type } = event.target; + +// const newValue = type === "checkbox" ? checked : value; + +// setCurrentMenuItem(prev => ({ +// ...prev, +// [name]: newValue +// })); +// setSlicedMenus((prevMenus) => { +// console.log("Before update:", prevMenus, "Changing menuId:", menuId, "Field:", name, "Value:", newValue); + +// return prevMenus.map((menu) => +// menu.menuId === menuId +// ? { ...menu, [name]: newValue } +// : menu +// ); +// }); +// }; +// const handleSearch = (query) => { +// setSearchQuery(query); +// }; + +// const handleAddItem = () => { +// setIsEditing(false); +// setNewItemData({ +// menuId: "", +// menuItemName: "", +// isActive: true, +// }); +// setShowAddEditModal(true) +// }; + +// const handleClose = () => { +// setShowAddEditModal(false); // Close the modal by setting the state to false +// }; + + +// const handleSubmit = (event) => { +// event.preventDefault(); +// if (isEditing) { +// setMenuItems(menuItems.map(item => +// item.menuId === currentMenuItem.menuId ? currentMenuItem : item +// )); +// } else { +// const newMenuId = `ID${menuItems.length + 1}`; +// setMenuItems([...menuItems, { ...currentMenuItem, menuId: newMenuId }]); +// } +// setShowAddEditModal(false); +// }; +// const [loading2, setLoading2] = useState(false); + +// const handleSync = async () => { +// setLoading2(true); +// await fetchData(); +// setLoading2(false); +// }; + +// const openModal = (item = { menuId: "", menuName: "", accessLevel: "", isActive: false }) => { +// setIsEditing(!!item.menuId); +// setCurrentMenuItem(item); +// setShowAddEditModal(true); +// }; + +// const handleDelete = (menuId) => { +// setMenuItems(menuItems.filter(item => item.menuId !== menuId)); +// }; + +// const handleRecordsPerPageChange = (number) => { +// setRecordsPerPage(number); +// setCurrentPage(1); +// } + +// const totalPages = Math.ceil(menuItems.length / recordsPerPage); +// const handlePageChange = (pageNumber) => { +// setCurrentPage(pageNumber); +// }; + +// const handleSelectChange = (value) => { +// console.log(value); +// setUsrgrp(value); + +// }; +// const handleToggleCheckbox = () => { +// setToggle((prev) => !prev); +// console.log("Toggled:", !toggle); // This should show up in console +// }; + + +// const filteredMenus = slicedMenus +// .filter((item) => +// item.menuItemName && item.menuItemName.toLowerCase().includes(searchQuery.toLowerCase()) +// ) +// .slice((currentPage - 1) * recordsPerPage, currentPage * recordsPerPage); +// return ( +//
+// {loading ? ( +// +// ) : ( +//
+//
+// {/* Left Side */} +//
+//

Menu Access Control

+// +// Edit Mode +// +//
+ +// {/* Right Side */} +//
+// For +// +// +// +// {toggle ? "Only Main Menu" : "Show All"} +// + +//
+// +// +//
+//
+//
+// +// {/* Left: Search Bar */} +// +// +// +// +// +// handleSearch(e.target.value)} +// style={{ +// padding: "10px", +// border: "none", +// paddingRight: "5px", // More space on the right side of input field +// }} +// /> +// +// + +// {/*Add Icons */} +// +// <> +// {/* Add Icon */} +// handleAddItem(true)} +// style={{ +// cursor: "pointer", +// fontSize: "1.5rem", +// color: "#747264", +// marginRight: "20px", +// }} +// /> +// +// +// +// + +//
+// +// +// +// {Object.entries(visibleColumns).map(([key, visible], colIndex) => +// visible ? ( +// +// ) : null +// )} +// +// +// +// {slicedMenus.length === 0 ? ( +// +// +// +// ) : ( +// slicedMenus +// .filter(item => !toggle || item.menuId > 10 ) // Filter out items with menuId <= 10 if toggle is true +// .map((item, index) => ( +// +// {Object.entries(visibleColumns).map(([key, visible]) => +// visible ? ( +// +// ) : null +// )} +// +// )) +// )} +// +//
+// {colIndex === 0 && ( +// + +// )} +// {key.charAt(0).toUpperCase() + key.slice(1)} +//
visibleColumns[key]).length +// } +// className="text-center" +// > +// No items found. Please add new items. +//
+// {key === "actions" ? ( +// <> +// openModal(item)} +// style={{ +// cursor: "pointer", +// fontSize: "1rem", +// color: "green", +// marginRight: "15px", +// }} +// /> +// +// ) : ["view", "create", "edit", "delete", "query", "export"].includes(key) ? ( +// handleInputChange(e, item.menuId)} +// /> + +// ) : ( +// item[key]?.toString() +// )} +//
+//
+ +// {/* Manage Columns & Records Per Page */} +// +// +// +// +// Manage Columns +// +// +// {Object.keys(visibleColumns).map((column) => ( +// toggleColumn(column)} +// > +// +// +// ))} +// +// +// + +// +// +// +// +// +// +// {[1, 5, 10, 20, 50].map((number) => ( +// handleRecordsPerPageChange(number)} +// className="text-dark d-flex justify-content-between align-items-center" +// > +// {number} +// +// +// ))} +// +// +// +// + +// +// +// handlePageChange(currentPage - 1)} /> +// +// {[...Array(totalPages)].map((_, index) => ( +// +// handlePageChange(index + 1)} style={{ color: '#0b6592' }}> +// {index + 1} +// +// +// ))} +// +// handlePageChange(currentPage + 1)} /> +// +// + +// {/* Add/Edit Model */} + +// {/* setShowAddEditModal(false)}> +// +// {isEditing ? "Edit Menu Access" : "Add Menu Access"} +// +// +// +//
+// +// Menu Name +// +// +// +// +// idselected(e.target.value)}> +// {menus.map((sub) => ( +// +// ))} +// +// +// +// +// +// + +// +// +// +//
+//
+//
*/} + +// setShowAddEditModal(false)}> +// +// {isEditing ? "Edit Menu Access" : "Add Menu Access"} +// +// +// +//
+// {/* Menu Name Input */} +// +// Menu Items Name +// +// + +// {/* Select Menu Item */} +// +// +// idselected(e.target.value)} +// > +// {menus.map((sub) => ( +// +// ))} +// +// + +// {/* Active Checkbox */} +// +// +// + +// {/* Modal Footer with buttons */} +// +// +// +// +//
+//
+//
+ + +//
+// )} +//
+// ); +// } + +// export default MenuAccessControl; + + + import React, { useState, useEffect } from "react"; import { Button, Dropdown, Modal, Form, Row, Col, InputGroup, @@ -21,6 +789,7 @@ import Spinner from '../../UIComponants/Spinner'; import { getByUsrGrpId } from "APIServices/MenuAccessControlAPI"; import { toast } from "react-toastify"; import {getToken } from "../../utils/tokenService" +import { faSync } from "@fortawesome/free-solid-svg-icons"; function MenuAccessControl({ selected, Sync }) { const [loading, setLoading] = useState(true); @@ -47,6 +816,8 @@ function MenuAccessControl({ selected, Sync }) { const [alldata, setAlldata] = useState([]); // const [slicedMenus, setSlicedMenus] = useState([]); const [toggle, setToggle] = useState(false); + const [allMenus, setAllMenus] = useState([]); + const [currentPage, setCurrentPage] = useState(1); const [isEditing, setIsEditing] = useState(false); const [recordsPerPage, setRecordsPerPage] = useState(10); @@ -107,13 +878,19 @@ function MenuAccessControl({ selected, Sync }) { }, 3000); // Simulated 3 seconds loading }, []); +useEffect(() => { + const defaultGroup = 1; // or whatever default ID you want + setUsrgrp(defaultGroup); // ✅ sets correctly +}, []); - useEffect(() => { - // Simulate fetching or setting a default value - // const defaultGroup = 'Admin'; // Replace with fetched or derived value - setUsrgrp(); - }, []); +useEffect(() => { + const filtered = toggle + ? allMenus.filter(item => Number(item.menuId) !== 0) + : allMenus; + + setSlicedMenus(filtered); +}, [toggle, allMenus]); useEffect(() => { const apiUrl = `${process.env.REACT_APP_API_URL}api/getAllUsrGrp`; @@ -134,11 +911,13 @@ function MenuAccessControl({ selected, Sync }) { } const data = await response.json(); + console.log("Menu items fetched successfully:", data); setMenuItems(data); } catch (error) { console.error("Error fetching menu items:", error); } }; + fetchMenuItems(); }, []); @@ -146,6 +925,11 @@ function MenuAccessControl({ selected, Sync }) { useEffect(() => { fetchData(); }, []); +useEffect(() => { + if (usrgrp) { + fetchData(); + } +}, [usrgrp]); // const fetchData = async () => { // try { @@ -179,37 +963,31 @@ function MenuAccessControl({ selected, Sync }) { // }; const fetchData = async () => { - try { - console.log("Fetching data for usrgrp:", usrgrp); - const data = await getByUsrGrpId(usrgrp); - if (!data) { - console.error("Received undefined data"); - toast.error("Failed to fetch data."); - return; - } - console.log("Data fetched successfully:", data); - - // Transform the data to match the table structure - const transformedData = data.map(item => ({ - menuId: item.menuItemId.menuItemId, - menuItemName: item.main_menu_action_name || item.menuItemDesc, - view: item.mvisible === "true", - create: item.mcreate === "true", - edit: item.medit === "true", - delete: item.mdelete === "true", - query: item.mquery === "true", - export: item.mexport === "true", - isActive: item.status === "Enable" - })); + try { + console.log("Calling getByUsrGrpId with usrgrp:", usrgrp); + + const data = await getByUsrGrpId(usrgrp); // or your API call + console.log("API response:", data); + + const transformedData = data.map(item => ({ + menuId: item.menuItemId.menuItemId, + menuItemName: item.menuItemDesc || '', + view: item.mvisible === "true", + create: item.mcreate === "true", + edit: item.medit === "true", + delete: item.mdelete === "true", + query: item.mquery === "true", + export: item.mexport === "true", + isActive: item.status === "Enable" + })); + + setAllMenus(transformedData); + setSlicedMenus(transformedData); // initially show all + } catch (error) { + console.error("Fetch failed:", error); + } +}; - setSlicedMenus(transformedData); - setAlldata(data); - toast.success("Data fetched successfully!"); - } catch (error) { - console.error("Error fetching data:", error.message || error); - toast.error("Failed to fetch data."); - } - }; const idselected = (value) => { setSelectedMenuId(value); }; @@ -222,20 +1000,24 @@ function MenuAccessControl({ selected, Sync }) { }; const handleInputChange = (event, menuId) => { - const { name, value, checked, type } = event.target; - setCurrentMenuItem(prev => ({ - ...prev, - [name]: type === "checkbox" ? checked : value - })); - setSlicedMenus((prevMenus) => - prevMenus.map((menu) => - menu.menuId === currentMenuItem.menuId // Identify the correct menu item - ? { ...menu, [name]: value } // Update the specific field - : menu - ) - ); - }; + const { name, value, checked, type } = event.target; + const newValue = type === "checkbox" ? checked : value; + + setCurrentMenuItem(prev => ({ + ...prev, + [name]: newValue + })); +setSlicedMenus((prevMenus) => { + console.log("Before update:", prevMenus, "Changing menuId:", menuId, "Field:", name, "Value:", newValue); + + return prevMenus.map((menu) => + menu.menuId === menuId + ? { ...menu, [name]: newValue } + : menu + ); +}); +}; const handleSearch = (query) => { setSearchQuery(query); }; @@ -267,6 +1049,13 @@ function MenuAccessControl({ selected, Sync }) { } setShowAddEditModal(false); }; +const [loading2, setLoading2] = useState(false); + +const handleSync = async () => { + setLoading2(true); + await fetchData(); + setLoading2(false); +}; const openModal = (item = { menuId: "", menuName: "", accessLevel: "", isActive: false }) => { setIsEditing(!!item.menuId); @@ -293,10 +1082,11 @@ function MenuAccessControl({ selected, Sync }) { setUsrgrp(value); }; +const handleToggleCheckbox = () => { + setToggle((prev) => !prev); + console.log("Toggled:", !toggle); // This should show up in console +}; - const handleToggleCheckbox = () => { - setToggle(!toggle); - }; const filteredMenus = slicedMenus .filter((item) => @@ -304,7 +1094,7 @@ function MenuAccessControl({ selected, Sync }) { ) .slice((currentPage - 1) * recordsPerPage, currentPage * recordsPerPage); return ( -
+
{loading ? ( ) : ( @@ -355,19 +1145,19 @@ function MenuAccessControl({ selected, Sync }) {
- - -
+ +
+
{/* Left: Search Bar */} -
- - - - {Object.entries(visibleColumns).map(([key, visible]) => - visible ? : null - )} - - - - {slicedMenus.length === 0 ? ( - - - - ) : ( - slicedMenus.map((item, index) => ( - - {Object.entries(visibleColumns).map(([key, visible]) => - visible ? ( - - ) : null - )} - - )) - )} - -
{key.charAt(0).toUpperCase() + key.slice(1)}
visibleColumns[key]) - .length - } - className="text-center" - > - No items found. Please add new items. -
- {key === "actions" ? ( - <> - openModal(item)} - style={{ - cursor: "pointer", - fontSize: "1rem", - color: "green", - marginRight: "15px", - }} - /> - handleDelete(item.menuId)} - style={{ - cursor: "pointer", - fontSize: "1rem", - color: "#dc3545", - }} - /> - - ) : ["view", "create", "edit", "delete", "query", "export"].includes(key) ? ( - - // handleInputChange({ - // target: { - // name: key, - // value: e.target.checked, - // }, - // }) - onChange={(e) => handleInputChange(e, item.menuId)} - disabled={false} - /> - ) : key === "isActive" ? ( - - {item.isActive ? "Active" : "Inactive"} - - ) : ( - item[key] - )} -
-
+
+ + + + {/* New column for sync button */} + {Object.entries(visibleColumns).map(([key, visible]) => + visible ? : null + )} + + + + + {slicedMenus.length === 0 ? ( + + + + ) : ( + slicedMenus + .filter(item => !toggle || item.menuId >= 10) // Show submenus only when toggle is off + .map((item, index) => ( + + {item.menuId !== 0 && item.menuId >= 10 ? ( + + ) : ( + + ) : null + )} + + + )) + )} + +
Sync{key.charAt(0).toUpperCase() + key.slice(1)}
visibleColumns[key]).length + } + className="text-center" + > + No items found. Please add new items. +
+ + // Empty cell to maintain alignment + )} + + {Object.entries(visibleColumns).map(([key, visible]) => + visible ? ( + + {key === "actions" ? ( + <> + openModal(item)} + style={{ + cursor: "pointer", + fontSize: "1rem", + color: "green", + marginRight: "15px", + }} + /> + + ) : ["view", "create", "edit", "delete", "query", "export"].includes(key) ? ( + handleInputChange(e, item.menuId)} + /> + ) : ( + item[key]?.toString() + )} +
+
{/* Manage Columns & Records Per Page */} diff --git a/src/components/Dashboard/MenuAccessControl2.js b/src/components/Dashboard/MenuAccessControl2.js index 3b46179..b709323 100644 --- a/src/components/Dashboard/MenuAccessControl2.js +++ b/src/components/Dashboard/MenuAccessControl2.js @@ -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 diff --git a/src/components/Dashboard/MenuMaintenance.js b/src/components/Dashboard/MenuMaintenance.js index d8ab85e..3b5da7d 100644 --- a/src/components/Dashboard/MenuMaintenance.js +++ b/src/components/Dashboard/MenuMaintenance.js @@ -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 ( + +
{loading ? ( @@ -597,6 +626,7 @@ function MenuMaintenance() { padding: "10px 15px", }} > + - Menu Items} > @@ -705,7 +735,7 @@ function MenuMaintenance() { color: "#747264", }} /> - + */} @@ -757,7 +787,7 @@ function MenuMaintenance() { ) )} Actions - {!isSubMenu && Sub-Menu} + {!dd && Sub-Menu} @@ -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() { }} /> - {!isSubMenu && ( + {!dd && ( setShowAddEditPopup(false)} - centered - > - - - {isEditing ? "Edit Menu Item" : "Add New Menu Item"} - - - - -
- - menuId - - - - Title - - - - Link - - - - Status - - - - - - - - - - -
-
- - )} + setShowAddEditPopup(false)} + centered + size="lg" + > + + + {isEditing ? "Edit Menu Item" : "Add New Menu Item"} + + + + +
+ + {/* Menu ID (Fixed at 0) */} + + + Menu ID* + + + + + {/* Menu Item Name */} + + + Menu Item Name* + + + + + + + {/* Sequence */} + + + Sequence + + + + + {/* Module Name */} + + + Module Name + + + + + + + {/* Menu Action Link */} + + + Menu Action Link + + + + + {/* Menu Icon Name */} + + + Menu Icon Name + + + + + + {/* Status */} + + Status + + + + + + + + + + +
+
+
+)} +
)}
diff --git a/src/components/Dashboard/Reportbuild2/Report-build2all/ReportBuild2All.js b/src/components/Dashboard/Reportbuild2/Report-build2all/ReportBuild2All.js index 46a2c0a..d3e41da 100644 --- a/src/components/Dashboard/Reportbuild2/Report-build2all/ReportBuild2All.js +++ b/src/components/Dashboard/Reportbuild2/Report-build2all/ReportBuild2All.js @@ -322,78 +322,74 @@ const ReportBuild2All = () => { {visibleColumns.action && Action} + - {filteredData.length === 0 ? ( - - - No data available - - - ) : ( - filteredData.filter((user) => user.isSql === false).map((user) => ( - - {visibleColumns.goTo && ( - - goToLines(user)} - > - Set Up - - - )} - {visibleColumns.reportName && {user.reportName}} - {visibleColumns.description && {user.description}} - {visibleColumns.active && ( - - {user.active ? "Yes" : "No"} - - )} - {visibleColumns.action && ( - - confirmDelete(e, user)} - style={{ - cursor: "pointer", - fontSize: "1rem", - color: "red", - marginRight: "15px", - }} - /> - - )} + {filteredData.length === 0 ? ( + + + No data available + - )) - )} - + ) : ( + filteredData.filter(user => user.isSql === false).map(user => ( + + {visibleColumns.goTo && ( + + goToLines(user)} + > + Set Up + + + )} + {visibleColumns.reportName && {user.reportName}} + {visibleColumns.description && {user.description}} + {visibleColumns.active && ( + + {user.active ? "Yes" : "No"} + + )} + {visibleColumns.action && ( + + confirmDelete(e, user)} + style={{ + cursor: "pointer", + fontSize: "1rem", + color: "red", + marginRight: "15px", + }} + /> + + )} + + )) + )} + + )} diff --git a/src/components/Dashboard/Reportbuilder/UserDetailsView.js b/src/components/Dashboard/Reportbuilder/UserDetailsView.js index 186969e..1cfef24 100644 --- a/src/components/Dashboard/Reportbuilder/UserDetailsView.js +++ b/src/components/Dashboard/Reportbuilder/UserDetailsView.js @@ -464,14 +464,16 @@ function UserDetailsView() { responsive hover className=" align-middle table-flush shadow-sm" + > + Go To Report Name Description Status Actions - Go To + @@ -489,6 +491,20 @@ function UserDetailsView() { style={{ cursor: "pointer" }} onClick={() => handleRowClick(detail)} > + + { + e.stopPropagation(); // Prevent row click event + handleGoTo(detail); + }} + style={{ + cursor: "pointer", + fontSize: "1.2rem", + color: "#0E6591", + }} + /> + {detail.reportName} {detail.description || "No description available"} - - { - e.stopPropagation(); // Prevent row click event - handleGoTo(detail); - }} - style={{ - cursor: "pointer", - fontSize: "1.2rem", - color: "#0E6591", - }} - /> - + )) )} diff --git a/src/components/Dashboard/SetupView.js b/src/components/Dashboard/SetupView.js index 8045ede..c99b462 100644 --- a/src/components/Dashboard/SetupView.js +++ b/src/components/Dashboard/SetupView.js @@ -38,161 +38,60 @@ function SetupView({ // Display the spinner while loading ) : (
-
-
{ - console.log("User Maintenance card clicked"); - console.log("Navigating to:", "/admin/user-maintenance"); - - navigate("/admin/user-maintenance"); - }} - // onClick={onUserMaintenanceClick} - > - -

User Maintenance

-

Content for Card 1

-
-
{ - navigate("/admin/menu-access-control"); - // navigate("/admin/menu-access-control2") - }} - > - -

Menu Access Control

-

Content for Card 2

-
-
{ - navigate("/admin/user-Group-Maintenance"); - }}> - -

User Group Maintenance

-

Content for Card 3

-
-
{ - navigate("/admin/system-parameter"); - }}> - -

System Parameter

-

Content for Card 4

-
-
{ - navigate("/admin/menu-maintenance"); - }}> - -

Menu Maintenance

-

Content for Card 5

-
-
{ - navigate("/admin/access-type"); - }}> - -

Access Type

-

Content for Card 6

-
-
{ - navigate("/admin/api-registry") - }}> - -

API Registry

-

Content for Card 7

-
-
{ - navigate("/admin/token-registry") - }}> - -

Token Registry

-

Content for Card 8

-
- {/*
{ - navigate("/admin/datatype-1") - }}> - -

DATATYPE1

-

Content for Card 9

-
-
{ - navigate("/admin/datatype-2") - }}> - -

DATATYPE2

-

Content for Card 10

-
-
{ - navigate("/admin/datatype-3") - }}> - -

DATATYPE3

-

Content for Card 11

-
-
{ - navigate("/admin/datatype-4") - }}> - -

DATATYPE4

-

Content for Card 12

-
-
{ - navigate("/admin/datatype-5") - }}> - -

DATATYPE5

-

Content for Card 13

-
-
{ - navigate("/admin/datatype-6") - }}> - -

DATATYPE6

-

Content for Card 14

-
-
{ - navigate("/admin/basics-datatypes") - }}> - -

Basics Datatypes

-

Content for Card 15

-
-
{ - navigate("/admin/advance-datatypes") - }}> - -

Advanced Datatypes

-

Content for Card 16

-
-
{ - navigate("/admin/advance-datatypes2") - }}> - -

Advanced Datatypes 2

-

Content for Card 17

-
-
{ - navigate("/admin/premium-datatypes") - }}> - -

Premium Datatypes

-

Content for Card 18

-
*/} -
{ - navigate("/admin/user-report") - }}> - -

Reports

-

Report Description

-
-
{ - navigate("/admin/dynamic-form") - }}> - -

DynamicForm

-

Content for Card 16

-
- -
-
+
+
navigate("/admin/user-maintenance")}> + +

User Maintenance

+

User Maintainance

+
+
navigate("/admin/user-Group-Maintenance")}> + +

User Group Maintenance

+

User Group Maintenance

+
+
navigate("/admin/menu-maintenance")}> + +

Menu Maintenance

+

Menu Maintenance

+
+
navigate("/admin/menu-access-control")}> + +

Menu Access Control

+

Menu Access Control

+
+
navigate("/admin/system-parameter")}> + +

System Parameter

+

System Parameter

+
+
navigate("/admin/access-type")}> + +

Access Type

+

Access Type

+
+
navigate("/admin/sequence-generator")}> + +

Document Sequence

+

Manage document sequences

+
+
navigate("/admin/user-report")}> + +

Reports

+

Reports Description

+
+
navigate("/admin/api-registry")}> + +

API Registry

+

API Registry

+
+
navigate("/admin/token-registry")}> + +

Token Registry

+

Token Registry

+
+ +
+
)}
diff --git a/src/components/Dashboard/SubmenuMaintenance.js b/src/components/Dashboard/SubmenuMaintenance.js index 3d41c75..bd558de 100644 --- a/src/components/Dashboard/SubmenuMaintenance.js +++ b/src/components/Dashboard/SubmenuMaintenance.js @@ -1,548 +1,2438 @@ -import React, { useState, useEffect } from "react"; -import Spinner from "../../UIComponants/Spinner"; -import "../Dashboard/CSS/CSS/MenuMaitenance.css"; -import { Table, Pagination, PaginationItem, PaginationLink } from "reactstrap"; -import { BsJournals } from "react-icons/bs"; -import { - Button, - Dropdown, - Modal, - Form, - Row, - Col, - InputGroup, - FormControl, - OverlayTrigger, - Tooltip, -} from "react-bootstrap"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { FaSearch } from "react-icons/fa"; -import { faEdit, faTrashAlt } from "@fortawesome/free-solid-svg-icons"; -import { addSubmenuItem } from "../../APIServices/MenuMaintenanceAPI"; -import { toast } from "react-toastify"; -const SubMenuMaintenance = ({ selectedMainMenuId }) => { - const [recordsPerPage, setRecordsPerPage] = useState(10); - const [currentPage, setCurrentPage] = useState(1); - const [subMenu, setSubMenu] = useState([]); - const [modalAdd, setModalAdd] = useState(false); - const [modalDelete, setModalDelete] = useState(false); - const [modalEdit, setModalEdit] = useState(false); - const [loading, setLoading] = useState(false); - const [rowSelected, setRowSelected] = useState({}); +// import React, { useState, useEffect } from "react"; +// import Spinner from "../../UIComponants/Spinner"; +// import "../Dashboard/CSS/CSS/MenuMaitenance.css"; +// import { Table, Pagination, PaginationItem, PaginationLink } from "reactstrap"; +// import { BsJournals } from "react-icons/bs"; +// import { +// Button, +// Dropdown, +// Modal, +// Form, +// Row, +// Col, +// InputGroup, +// FormControl, +// OverlayTrigger, +// Tooltip, +// } from "react-bootstrap"; +// import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +// import { FaSearch } from "react-icons/fa"; +// import { faEdit, faTrashAlt } from "@fortawesome/free-solid-svg-icons"; +// import { addSubmenuItem } from "../../APIServices/MenuMaintenanceAPI"; +// import { toast } from "react-toastify"; +// const SubMenuMaintenance = ({ selectedMainMenuId }) => { +// const [recordsPerPage, setRecordsPerPage] = useState(10); +// const [currentPage, setCurrentPage] = useState(1); +// const [subMenu, setSubMenu] = useState([]); +// const [modalAdd, setModalAdd] = useState(false); +// const [modalDelete, setModalDelete] = useState(false); +// const [modalEdit, setModalEdit] = useState(false); +// const [loading, setLoading] = useState(false); +// const [rowSelected, setRowSelected] = useState({}); - const [entryForm, setEntryForm] = useState({ - menuId: selectedMainMenuId, +// const [entryForm, setEntryForm] = useState({ +// menuId: selectedMainMenuId, +// menuItemDesc: "", +// itemSeq: "", +// moduleName: "", +// status: "Enable", +// main_menu_action_name: "", +// }); +// const [data, setData] = useState([]); + +// const [visibleColumns, setVisibleColumns] = useState({ +// menuItemId: true, +// menuItemDesc: true, +// itemSeq: true, +// }); + +// const [isSubMenu, setIsSubMenu] = useState(false); +// const [searchQuery, setSearchQuery] = useState(""); +// const [menuItems, setMenuItems] = useState([]); +// const [slicedSubMenus, setSlicedSubMenus] = useState([]); +// const [currentMenuItem, setCurrentMenuItem] = useState({}); +// const [subMenuItems, setSubMenuItems] = useState([]); + +// useEffect(() => { +// // Simulate loading data +// setTimeout(() => { +// setLoading(false); +// }, 3000); // Simulated 3 seconds loading +// }, []); + +// useEffect(() => { +// if (selectedMainMenuId) { +// setEntryForm((prev) => ({ ...prev, menuId: selectedMainMenuId })); +// } +// }, [selectedMainMenuId]); + +// useEffect(() => { +// const filteredSubMenus = subMenu +// .filter( +// (submenu) => +// submenu.menuItemDesc && +// submenu.menuItemDesc.toLowerCase().includes(searchQuery.toLowerCase()) +// ) +// .slice((currentPage - 1) * recordsPerPage, currentPage * recordsPerPage); + +// setSlicedSubMenus(filteredSubMenus); +// }, [subMenu, searchQuery, currentPage, recordsPerPage]); + +// const handleInputChange = (e) => { +// const { name, value } = e.target; +// setEntryForm((prev) => ({ ...prev, [name]: value })); +// }; + +// const handleRowChange = (e) => { +// const { name, value } = e.target; +// setRowSelected((prev) => ({ ...prev, [name]: value })); +// }; + +// const handleSearch = (query) => { +// setSearchQuery(query); +// }; + +// // const goToAdd = () => { +// // setEntryForm((prev) => ({ +// // ...prev, +// // menuId: selectedMainMenuId, // Set the main menu ID +// // })); +// // setModalAdd(true); +// // }; + +// const goToAdd = () => { +// console.log("selectedMainMenuId:", selectedMainMenuId); // Debugging line +// if (!selectedMainMenuId) { +// toast.error("Please select a main menu item first."); +// return; +// } +// setEntryForm((prev) => ({ +// ...prev, +// menuId: selectedMainMenuId, +// })); +// setModalAdd(true); +// }; + + +// const onSubmit = async (event) => { +// event.preventDefault(); + +// // Include menuId in the form data +// const formData = { +// menuItemDesc: entryForm.menuItemDesc, +// }; + +// try { +// // Pass menuId as a string +// const data = await addSubmenuItem( +// selectedMainMenuId.toString(), +// formData +// ); +// toast.success("Submenu item added successfully!"); +// console.log("Submenu item added successfully:", data); +// // Handle successful submission, e.g., close modal, refresh data, etc. +// setModalAdd(false); +// } catch (error) { +// console.error("Error adding submenu item:", error); +// toast.error( +// "Unexpected error: " + +// (error.message || "Server error occurred. Please try again.") +// ); +// // Handle error, e.g., show a message to the user +// } +// }; + +// const goToEdit = (user) => { +// setRowSelected(user); +// setEntryForm({ +// menuId: user.menuId, +// menuItemDesc: user.menuItemDesc, +// }); +// setModalEdit(true); +// }; + +// const onUpdate = (e) => { +// e.preventDefault(); + +// // Prepare the updated entry from the form +// const updatedEntry = { +// menuId: entryForm.menuId, +// menuItemDesc: entryForm.menuItemDesc, +// // Add other fields as needed +// }; + +// // Find the index of the subMenu to update +// const index = slicedSubMenus.findIndex( +// (subMenu) => subMenu.menuId === updatedEntry.menuId +// ); + +// if (index !== -1) { +// // Update the subMenu in the state +// const updatedSubMenus = [...slicedSubMenus]; +// updatedSubMenus[index] = updatedEntry; + +// // Update the state with the new subMenus list +// setSlicedSubMenus(updatedSubMenus); + +// // Close the modal after updating +// setModalEdit(false); +// } +// }; + +// const onDelete = (user) => { +// setRowSelected(user); +// setModalDelete(true); +// }; + +// const confirmDelete = () => { +// // Logic to delete +// console.log("Deleted:", rowSelected); +// setModalDelete(false); +// }; + +// // pagination +// const toggleColumn = (column) => { +// setVisibleColumns((prev) => ({ +// ...prev, +// [column]: !prev[column], +// })); +// }; + +// const totalPages = Math.ceil(subMenu.length / recordsPerPage); +// const handlePageChange = (pageNumber) => { +// setCurrentPage(pageNumber); +// }; +// const handleRecordsPerPageChange = (number) => { +// setRecordsPerPage(number); +// }; +// return ( +//
+// {loading ? ( +// +// ) : ( +//
+// {/* Header */} +//
+//
+//

Sub-Menu Maintenance

+// Sub Menu +//
+//
+ +// +// {/* Left: Search Bar */} +// +// +// +// +// +// handleSearch(e.target.value)} +// style={{ +// padding: "10px", +// border: "none", +// paddingRight: "5px", // More space on the right side of input field +// }} +// /> +// +// +// +//
+// +//
+// +//
+ +//
+// +// +// +// +// {Object.entries(visibleColumns).map( +// ( +// [key, visible]) => +// visible && ( +// +// ) +// )} +// +// +// +// +// {slicedSubMenus.length === 0 ? ( +// +// +// +// ) : ( +// slicedSubMenus.map((subMenu, index) => ( +// +// +// {Object.keys(visibleColumns).map( +// (key) => +// visibleColumns[key] && ( +// +// ) +// )} +// +// +// )) +// )} +// +//
No +// {key.charAt(0).toUpperCase() + key.slice(1)} +// Actions
visibleColumns[key] +// ).length + +// (isSubMenu ? 1 : 2) +// } +// className="text-center" +// > +// No menu items found. Please add new items. +//
{index + 1} +// {key === "status" ? ( +// +// {subMenu.status ? "Enabled" : "Disabled"} +// +// ) : ( +// subMenu[key] +// )} +// +// goToEdit(subMenu)} +// style={{ +// cursor: "pointer", +// fontSize: "1rem", +// color: "green", +// marginRight: "15px", +// }} +// /> +// onDelete(subMenu)} +// style={{ +// cursor: "pointer", +// fontSize: "1rem", +// color: "#dc3545", +// }} +// /> +//
+//
+ +// {/* Manage Columns & Records Per Page */} +// +// +// +// +// Manage Columns +// +// +// {Object.keys(visibleColumns).map((column) => ( +// toggleColumn(column)} +// > +// +// +// ))} +// +// +// + +// +// +// +// +// +// +// {[1, 5, 10, 20, 50].map((number) => ( +// handleRecordsPerPageChange(number)} +// className="text-dark d-flex justify-content-between align-items-center" +// > +// {number} +// +// +// ))} +// +// +// +// + +// +// +// handlePageChange(currentPage - 1)} +// /> +// +// {[...Array(totalPages)].map((_, index) => ( +// +// handlePageChange(index + 1)} +// style={{ color: "#0b6592" }} +// > +// {index + 1} +// +// +// ))} +// +// handlePageChange(currentPage + 1)} +// /> +// +// + +// {/* Modals */} +// {modalAdd && ( +//
+//
+//
+//
+//
Add Sub-Menu
+// +//
+//
+//
+// + +// +// +//
+//
+//
+//
+//
+// )} + +// {modalEdit && ( +//
+//
+//
+//
+//
Edit Sub-Menu
+// +//
+//
+//
+// +// +// +//
+//
+//
+//
+//
+// )} +//
+// )} +//
+ +// ); +// }; + +// export default SubMenuMaintenance; + +// export default SubMenuMaintenance; +// import React, { useEffect, useState } from "react"; +// import { useParams } from "react-router-dom"; +// import { +// getSubmenuItems, +// addSubmenuItem, +// deleteMenuItem +// } from "../../APIRequestService/APIService"; +// import { Table, Button, Form } from "react-bootstrap"; +// import { toast } from "react-toastify"; + +// const SubMenuMaintenance = () => { +// const { menuItemId } = useParams(); + +// const [subMenus, setSubMenus] = useState([]); + +// const [newItem, setNewItem] = useState({ +// menuId: menuItemId, +// menuItemName: "", +// sequence: "", +// moduleName: "", +// status: "", +// menuActionLink: "" +// }); + +// useEffect(() => { +// const fetchData = async () => { +// try { +// const data = await getSubmenuItems(menuItemId); +// console.log("Fetched submenu data:", data); + +// if (Array.isArray(data)) { +// setSubMenus(data); +// } else if (Array.isArray(data?.data)) { +// setSubMenus(data.data); +// } else { +// setSubMenus([]); +// toast.error("Invalid submenu data received from API"); +// console.error("Invalid submenu response:", data); +// } +// } catch (err) { +// toast.error("Failed to fetch submenu items"); +// console.error("Fetch submenu error:", err); +// } +// }; + +// fetchData(); +// }, [menuItemId]); + +// const handleAdd = async () => { +// try { +// const added = await addSubmenuItem(menuItemId, newItem); +// setSubMenus((prev) => [...prev, added]); +// setNewItem({ +// menuId: menuItemId, +// menuItemName: "", +// sequence: "", +// moduleName: "", +// status: "", +// menuActionLink: "" +// }); +// toast.success("Submenu added"); +// } catch (err) { +// toast.error("Failed to add submenu"); +// console.error("Add submenu error:", err); +// } +// }; + +// const handleDelete = async (id) => { +// try { +// await deleteMenuItem(id); +// setSubMenus((prev) => prev.filter((item) => item.id !== id)); +// toast.success("Deleted submenu"); +// } catch (err) { +// toast.error("Delete failed"); +// console.error("Delete submenu error:", err); +// } +// }; + +// return ( +//
+//

Sub-Menu Maintenance

+ +//
+// +// setNewItem({ ...newItem, menuItemName: e.target.value }) +// } +// /> +// +// setNewItem({ ...newItem, sequence: e.target.value }) +// } +// /> +// +// setNewItem({ ...newItem, moduleName: e.target.value }) +// } +// /> +// +// setNewItem({ ...newItem, status: e.target.value }) +// } +// > +// +// +// +// +// +// setNewItem({ ...newItem, menuActionLink: e.target.value }) +// } +// /> +// +// + +// +// +// +// +// +// +// +// +// +// +// +// +// {Array.isArray(subMenus) && +// subMenus.map((item, idx) => ( +// +// +// +// +// +// +// +// +// ))} +// +//
Menu Item NameSequenceModule NameStatusMenu Action LinkActions
{item.menuItemName}{item.sequence}{item.moduleName}{item.status}{item.menuActionLink} +// +//
+//
+// ); +// }; + +// export default SubMenuMaintenance; + + + + +// import React, { useEffect, useState } from "react"; +// import { useParams } from "react-router-dom"; +// import { +// getSubmenuItems, +// addSubmenuItem, +// updateMenuItem, +// deleteMenuItem +// } from '../../APIRequestService/APIService'; +// import { Table, Button, Form } from "react-bootstrap"; +// import { toast } from "react-toastify"; + +// const SubMenuMaintenance = () => { +// const { menuItemId } = useParams(); +// const [subMenus, setSubMenus] = useState([]); +// const [newItem, setNewItem] = useState({ itemSeq: "", menuItemDesc: "" }); + +// useEffect(() => { +// const fetchData = async () => { +// try { +// const data = await getSubmenuItems(menuItemId); +// setSubMenus(data); +// } catch (err) { +// toast.error("Failed to fetch submenu items"); +// } +// }; + +// fetchData(); +// }, [menuItemId]); + +// const handleAdd = async () => { +// try { +// const added = await addSubmenuItem(menuItemId, newItem); +// setSubMenus((prev) => [...prev, added]); +// setNewItem({ itemSeq: "", menuItemDesc: "" }); +// toast.success("Submenu added"); +// } catch (err) { +// toast.error("Failed to add submenu"); +// } +// }; + +// const handleDelete = async (id) => { +// try { +// await deleteMenuItem(id); +// setSubMenus((prev) => prev.filter((item) => item.id !== id)); +// toast.success("Deleted submenu"); +// } catch (err) { +// toast.error("Delete failed"); +// } +// }; +// useEffect(() => { +// const fetchData = async () => { +// try { +// const data = await getSubmenuItems(menuItemId); +// console.log("Fetched submenu data from API:", data); // <-- This will print the API response + +// if (Array.isArray(data)) { +// setSubMenus(data); +// } else if (Array.isArray(data?.data)) { +// setSubMenus(data.data); +// } else { +// setSubMenus([]); +// toast.error("Invalid submenu data received from API"); +// console.error("Invalid submenu response:", data); +// } +// } catch (err) { +// toast.error("Failed to fetch submenu items"); +// console.error("Fetch submenu error:", err); +// } +// }; + +// fetchData(); +// }, [menuItemId]); + +// return ( +//
+//

Sub-Menu Maintenance

+ +//
+// setNewItem({ ...newItem, itemSeq: e.target.value })} +// /> +// setNewItem({ ...newItem, menuItemDesc: e.target.value })} +// /> +// +// + +// +// +// +// +// +// +// +// +// +// {subMenus.map((item, idx) => ( +// +// +// +// +// +// ))} +// +//
Item SeqDescriptionActions
{item.itemSeq}{item.menuItemDesc} +// +//
+//
+// ); +// }; + + +// import React, { useEffect, useState } from "react"; +// import { useParams } from "react-router-dom"; +// import { +// getSubmenuItems, +// addSubmenuItem, +// deleteMenuItem +// } from "../../APIRequestService/APIService"; +// import { Table, Button, Form } from "react-bootstrap"; +// import { toast } from "react-toastify"; + +// const SubMenuMaintenance = () => { +// const { menuItemId } = useParams(); + +// const [subMenus, setSubMenus] = useState([]); + +// const [newItem, setNewItem] = useState({ +// menuId: menuItemId, +// menuItemName: "", +// sequence: "", +// moduleName: "", +// status: "", +// menuActionLink: "" +// }); + +// useEffect(() => { +// const fetchData = async () => { +// try { +// const data = await getSubmenuItems(menuItemId); +// console.log("Fetched submenu data:", data); + +// if (Array.isArray(data)) { +// setSubMenus(data); +// } else if (Array.isArray(data?.data)) { +// setSubMenus(data.data); +// } else { +// setSubMenus([]); +// toast.error("Invalid submenu data received from API"); +// console.error("Invalid submenu response:", data); +// } +// } catch (err) { +// toast.error("Failed to fetch submenu items"); +// console.error("Fetch submenu error:", err); +// } +// }; + +// fetchData(); +// }, [menuItemId]); + +// const handleAdd = async () => { +// try { +// const added = await addSubmenuItem(menuItemId, newItem); +// setSubMenus((prev) => [...prev, added]); +// setNewItem({ +// menuId: menuItemId, +// menuItemName: "", +// sequence: "", +// moduleName: "", +// status: "", +// menuActionLink: "" +// }); +// toast.success("Submenu added"); +// } catch (err) { +// toast.error("Failed to add submenu"); +// console.error("Add submenu error:", err); +// } +// }; + +// const handleDelete = async (id) => { +// try { +// await deleteMenuItem(id); +// setSubMenus((prev) => prev.filter((item) => item.id !== id)); +// toast.success("Deleted submenu"); +// } catch (err) { +// toast.error("Delete failed"); +// console.error("Delete submenu error:", err); +// } +// }; + +// return ( +//
+//

Sub-Menu Maintenance

+ +//
+// +// setNewItem({ ...newItem, menuItemName: e.target.value }) +// } +// /> +// +// setNewItem({ ...newItem, sequence: e.target.value }) +// } +// /> +// +// setNewItem({ ...newItem, moduleName: e.target.value }) +// } +// /> +// +// setNewItem({ ...newItem, status: e.target.value }) +// } +// > +// +// +// +// +// +// setNewItem({ ...newItem, menuActionLink: e.target.value }) +// } +// /> +// +// + +// +// +// +// +// +// +// +// +// +// +// +// +// {Array.isArray(subMenus) && +// subMenus.map((item, idx) => ( +// +// +// +// +// +// +// +// +// ))} +// +//
Menu Item NameSequenceModule NameStatusMenu Action LinkActions
{item.menuItemName}{item.sequence}{item.moduleName}{item.status}{item.menuActionLink} +// +//
+//
+// ); +// }; + +// export default SubMenuMaintenance; + + + +// import React, { useEffect, useState } from "react"; +// import { useParams } from "react-router-dom"; +// import { +// getSubmenuItems, +// addSubmenuItem, +// updateMenuItem, +// deleteMenuItem +// } from '../../APIRequestService/APIService'; // ✅ must match where you exported them +// import { Table, Button, Form } from "react-bootstrap"; +// import { toast } from "react-toastify"; + +// const SubMenuMaintenance = () => { +// const { menuItemId } = useParams(); +// const [subMenus, setSubMenus] = useState([]); +// const [newItem, setNewItem] = useState({ itemSeq: "", menuItemDesc: "" }); + +// useEffect(() => { +// const fetchData = async () => { +// try { +// const data = await getSubmenuItems(menuItemId); +// setSubMenus(data); +// } catch (err) { +// toast.error("Failed to fetch submenu items"); +// } +// }; + +// fetchData(); +// }, [menuItemId]); + +// const handleAdd = async () => { +// try { +// const added = await addSubmenuItem(menuItemId, newItem); +// setSubMenus((prev) => [...prev, added]); +// setNewItem({ itemSeq: "", menuItemDesc: "" }); +// toast.success("Submenu added"); +// } catch (err) { +// toast.error("Failed to add submenu"); +// } +// }; + +// const handleDelete = async (id) => { +// try { +// await deleteMenuItem(id); +// setSubMenus((prev) => prev.filter((item) => item.id !== id)); +// toast.success("Deleted submenu"); +// } catch (err) { +// toast.error("Delete failed"); +// } +// }; + +// return ( +//
+//

Sub-Menu Maintenance

+ +//
+// setNewItem({ ...newItem, itemSeq: e.target.value })} +// /> +// setNewItem({ ...newItem, menuItemDesc: e.target.value })} +// /> +// +// + +// +// +// +// +// +// +// +// +// +// {subMenus.map((item, idx) => ( +// +// +// +// +// +// ))} +// +//
Item SeqDescriptionActions
{item.itemSeq}{item.menuItemDesc} +// +//
+//
+// ); +// }; + +// export default SubMenuMaintenance; + + + +// import React, { useEffect, useState } from "react"; +// import { useParams } from "react-router-dom"; +// import { +// getSubmenuItems, +// addSubmenuItem, +// updateMenuItem, +// deleteMenuItem +// } from '../../APIRequestService/APIService'; +// import { Table, Button, Form, Modal } from "react-bootstrap"; +// import { toast } from "react-toastify"; + +// const SubMenuMaintenance = () => { +// const { menuItemId } = useParams(); +// const [subMenus, setSubMenus] = useState([]); +// const [showAddModal, setShowAddModal] = useState(false); +// const [newItem, setNewItem] = useState({ +// itemSeq: "", +// menuItemDesc: "", +// menuItemPath: "", +// menuItemIcon: "" +// }); +// const [validationErrors, setValidationErrors] = useState({}); + +// useEffect(() => { +// const fetchData = async () => { +// try { +// const data = await getSubmenuItems(menuItemId); +// setSubMenus(data); +// } catch (err) { +// toast.error("Failed to fetch submenu items"); +// console.error("Fetch error:", err); +// } +// }; +// fetchData(); +// }, [menuItemId]); + +// const validateForm = () => { +// const errors = {}; +// if (!newItem.itemSeq) errors.itemSeq = "Sequence is required"; +// if (!newItem.menuItemDesc) errors.menuItemDesc = "Description is required"; +// setValidationErrors(errors); +// return Object.keys(errors).length === 0; +// }; + +// const handleAdd = async () => { +// if (!validateForm()) return; + +// try { +// const addedItem = await addSubmenuItem(menuItemId, newItem); +// setSubMenus([...subMenus, addedItem]); +// setNewItem({ itemSeq: "", menuItemDesc: "", menuItemPath: "", menuItemIcon: "" }); +// setShowAddModal(false); +// toast.success("Submenu added successfully"); +// } catch (err) { +// toast.error("Failed to add submenu"); +// console.error("Add error:", err.response?.data || err.message); +// } +// }; + +// const handleDelete = async (id) => { +// if (window.confirm("Are you sure you want to delete this submenu?")) { +// try { +// await deleteMenuItem(id); +// setSubMenus(subMenus.filter(item => item.id !== id)); +// toast.success("Submenu deleted successfully"); +// } catch (err) { +// toast.error("Failed to delete submenu"); +// console.error("Delete error:", err.response?.data || err.message); +// } +// } +// }; + +// return ( +//
+//
+//

Sub-Menu Maintenance

+// +//
+ +// +// +// +// +// +// +// +// +// +// +// +// {subMenus.map((item) => ( +// +// +// +// +// +// +// +// ))} +// +//
SequenceDescriptionPathIconActions
{item.itemSeq}{item.menuItemDesc}{item.menuItemPath}{item.menuItemIcon} +// +//
+ +// {/* Add Submenu Modal */} +// setShowAddModal(false)}> +// +// Add New Submenu +// +// +//
+// +// Sequence * +// setNewItem({...newItem, itemSeq: e.target.value})} +// isInvalid={!!validationErrors.itemSeq} +// /> +// +// {validationErrors.itemSeq} +// +// + +// +// Description * +// setNewItem({...newItem, menuItemDesc: e.target.value})} +// isInvalid={!!validationErrors.menuItemDesc} +// /> +// +// {validationErrors.menuItemDesc} +// +// + +// +// Path +// setNewItem({...newItem, menuItemPath: e.target.value})} +// /> +// + +// +// Icon +// setNewItem({...newItem, menuItemIcon: e.target.value})} +// placeholder="e.g., fa-home" +// /> +// +//
+//
+// +// +// +// +//
+//
+// ); +// }; + +// export default SubMenuMaintenance; + +// -------------------------------------------------------------------------------------- +// import React, { useEffect, useState } from "react"; +// import { useParams } from "react-router-dom"; +// import { +// getSubmenuItems, +// addSubmenuItem, +// updateMenuItem, +// deleteMenuItem +// } from '../../APIRequestService/APIService'; +// import { Table, Button, Form, Modal } from "react-bootstrap"; +// import { toast } from "react-toastify"; + +// const SubMenuMaintenance = () => { +// const { menuItemId } = useParams(); +// const [subMenus, setSubMenus] = useState([]); +// const [showAddModal, setShowAddModal] = useState(false); +// const [showEditModal, setShowEditModal] = useState(false); +// const [currentItem, setCurrentItem] = useState({ +// id: "", +// itemSeq: "", +// menuItemDesc: "", +// menuItemPath: "", +// menuItemIcon: "" +// }); +// const [validationErrors, setValidationErrors] = useState({}); +// const [isLoading, setIsLoading] = useState(false); + +// useEffect(() => { +// fetchSubMenus(); +// }, [menuItemId]); + +// const fetchSubMenus = async () => { +// setIsLoading(true); +// try { +// const data = await getSubmenuItems(menuItemId); +// setSubMenus(data); +// } catch (err) { +// toast.error("Failed to fetch submenu items"); +// console.error("Fetch error:", err); +// } finally { +// setIsLoading(false); +// } +// }; + +// const validateForm = () => { +// const errors = {}; +// if (!currentItem.itemSeq) errors.itemSeq = "Sequence is required"; +// if (!currentItem.menuItemDesc) errors.menuItemDesc = "Description is required"; +// setValidationErrors(errors); +// return Object.keys(errors).length === 0; +// }; + +// const handleInputChange = (e) => { +// const { name, value } = e.target; +// setCurrentItem({ +// ...currentItem, +// [name]: value +// }); +// }; + +// const handleAdd = async () => { +// if (!validateForm()) return; + +// try { +// const addedItem = await addSubmenuItem(menuItemId, currentItem); +// setSubMenus([...subMenus, addedItem]); +// resetForm(); +// setShowAddModal(false); +// toast.success("Submenu added successfully"); +// } catch (err) { +// toast.error(err.message || "Failed to add submenu"); +// console.error("Add error:", err); +// } +// }; + +// const handleEdit = (item) => { +// setCurrentItem(item); +// setShowEditModal(true); +// }; + +// const handleUpdate = async () => { +// if (!validateForm()) return; + +// try { +// await updateMenuItem(currentItem.id, currentItem); +// setSubMenus(subMenus.map(item => +// item.id === currentItem.id ? currentItem : item +// )); +// resetForm(); +// setShowEditModal(false); +// toast.success("Submenu updated successfully"); +// } catch (err) { +// toast.error(err.message || "Failed to update submenu"); +// console.error("Update error:", err); +// } +// }; + +// const handleDelete = async (id) => { +// if (window.confirm("Are you sure you want to delete this submenu?")) { +// try { +// await deleteMenuItem(id); +// setSubMenus(subMenus.filter(item => item.id !== id)); +// toast.success("Submenu deleted successfully"); +// } catch (err) { +// toast.error(err.message || "Failed to delete submenu"); +// console.error("Delete error:", err); +// } +// } +// }; + +// const resetForm = () => { +// setCurrentItem({ +// id: "", +// itemSeq: "", +// menuItemDesc: "", +// menuItemPath: "", +// menuItemIcon: "" +// }); +// setValidationErrors({}); +// }; + +// return ( +//
+//
+//

Sub-Menu Maintenance

+// +//
+ +// {isLoading ? ( +//
Loading submenus...
+// ) : ( +// +// +// +// +// +// +// +// +// +// +// +// {subMenus.length > 0 ? ( +// subMenus.map((item) => ( +// +// +// +// +// +// +// +// )) +// ) : ( +// +// +// +// )} +// +//
SequenceDescriptionPathIconActions
{item.itemSeq}{item.menuItemDesc}{item.menuItemPath}{item.menuItemIcon} +// +// +//
No submenus found
+// )} + +// {/* Add Submenu Modal */} +// setShowAddModal(false)}> +// +// Add New Submenu +// +// +//
+// +// Sequence * +// +// +// {validationErrors.itemSeq} +// +// + +// +// Description * +// +// +// {validationErrors.menuItemDesc} +// +// + +// +// Path +// +// + +// +// Icon +// +// +//
+//
+// +// +// +// +//
+ +// {/* Edit Submenu Modal */} +// setShowEditModal(false)}> +// +// Edit Submenu +// +// +//
+// +// Sequence * +// +// +// {validationErrors.itemSeq} +// +// + +// +// Description * +// +// +// {validationErrors.menuItemDesc} +// +// + +// +// Path +// +// + +// +// Icon +// +// +//
+//
+// +// +// +// +//
+//
+// ); +// }; + +// export default SubMenuMaintenance; + + + +// ----------------------------------------------------- + + + + + +// import React, { useEffect, useState } from "react"; +// import { useParams } from "react-router-dom"; +// import { +// getSubmenuItems, +// addSubmenuItem +// } from '../../APIServices/MenuMaintenanceAPI.js'; +// import { Table, Button, Form, Modal, Dropdown, Pagination } from "react-bootstrap"; +// import { toast } from "react-toastify"; + +// const SubMenuMaintenance = () => { +// const { menuItemId } = useParams(); +// const [subMenus, setSubMenus] = useState([]); +// const [showAddModal, setShowAddModal] = useState(false); +// const [currentItem, setCurrentItem] = useState({ +// menuItemDesc: "", +// menuItemId: "", +// itemSeq: "", +// moduleName: "", +// main_menu_action_name: "", +// status: "Enable", +// main_menu_icon_name: null, +// subMenus: [] +// }); +// const [validationErrors, setValidationErrors] = useState({}); +// const [isLoading, setIsLoading] = useState(false); +// const [itemsPerPage, setItemsPerPage] = useState(10); +// const [currentPage, setCurrentPage] = useState(1); + +// useEffect(() => { +// fetchSubMenus(); +// }, [menuItemId]); + +// const fetchSubMenus = async () => { +// setIsLoading(true); +// try { +// const data = await getSubmenuItems(menuItemId); +// setSubMenus(data); +// } catch (err) { +// toast.error("Failed to fetch submenu items"); +// console.error("Fetch error:", err); +// } finally { +// setIsLoading(false); +// } +// }; +// const validateForm = () => { +// const errors = {}; +// if (!currentItem.menuItemDesc) errors.menuItemDesc = "Menu Item Description is required"; +// if (!currentItem.menuItemId) errors.menuItemId = "Menu Item ID is required"; +// if (!currentItem.itemSeq) errors.itemSeq = "Item Sequence is required"; +// if (!currentItem.moduleName) errors.moduleName = "Module Name is required"; +// if (!currentItem.main_menu_action_name) errors.main_menu_action_name = "Main Menu Action Name is required"; +// setValidationErrors(errors); +// return Object.keys(errors).length === 0; +// }; + +// const handleInputChange = (e) => { +// const { name, value } = e.target; +// setCurrentItem({ +// ...currentItem, +// [name]: value +// }); +// }; + +// // Changes to the handleAdd function +// const handleAdd = async () => { +// if (!validateForm()) return; + +// try { +// const requestData = { +// menuItemDesc: currentItem.menuItemDesc, +// menuItemId: currentItem.menuItemId, +// itemSeq: currentItem.itemSeq, +// moduleName: currentItem.moduleName, +// main_menu_action_name: currentItem.main_menu_action_name, +// status: currentItem.status, +// main_menu_icon_name: currentItem.main_menu_icon_name || null, +// subMenus: [] +// }; + +// console.log("Submitting data:", requestData); + +// const addedItem = await addSubmenuItem(menuItemId, requestData); + +// // Handle both array and single object responses +// const newItems = Array.isArray(addedItem) ? addedItem : [addedItem]; +// setSubMenus([...subMenus, ...newItems]); + +// resetForm(); +// setShowAddModal(false); +// toast.success("Submenu added successfully"); +// } catch (err) { +// const errorMessage = err.response?.data?.message || "Failed to add submenu"; +// toast.error(errorMessage); +// console.error("Add error details:", err.response?.data); +// } +// }; + +// const resetForm = () => { +// setCurrentItem({ +// menuItemDesc: "", +// menuItemId: "", +// itemSeq: "", +// moduleName: "", +// main_menu_action_name: "", +// status: "Enable", +// main_menu_icon_name: null, +// subMenus: [] +// }); + +// setValidationErrors({}); +// }; + +// // Pagination logic +// const totalPages = Math.ceil(subMenus.length / itemsPerPage); +// const paginatedItems = subMenus.slice( +// (currentPage - 1) * itemsPerPage, +// currentPage * itemsPerPage +// ); + +// return ( +//
+//
+//

Sub-Menu Maintenance

+// +//
+ +//
+// +// +// Manage Columns +// +// +// Sub-Menu Item Name +// ID +// Sequence +// Module Name +// Menu Action Link +// Status +// +// + +//
+// Users per page +// setItemsPerPage(Number(e.target.value))} +// > +// +// +// +// +// +//
+//
+ +// {isLoading ? ( +//
Loading submenus...
+// ) : ( +// <> +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// {paginatedItems.length > 0 ? ( +// paginatedItems.map((item, index) => ( +// +// +// +// +// +// +// +// +// +// +// )) +// ) : ( +// +// +// +// )} +// +//
NOMenu Item DescriptionMenu Item IDItem SequenceModule NameMain Menu Action NameMain Menu Icon NameStatus
{(currentPage - 1) * itemsPerPage + index + 1}{item.menuItemDesc}{item.menuItemId}{item.itemSeq}{item.moduleName}{item.main_menu_action_name}{item.main_menu_icon_name || "null"} +// +//
No menu items found
+ +//
+//
+// Showing {(currentPage - 1) * itemsPerPage + 1} to{' '} +// {Math.min(currentPage * itemsPerPage, subMenus.length)} of{' '} +// {subMenus.length} entries +//
+// {/* +// setCurrentPage(1)} +// disabled={currentPage === 1} +// /> +// setCurrentPage(p => Math.max(p - 1, 1))} +// disabled={currentPage === 1} +// /> +// {Array.from({ length: totalPages }, (_, i) => ( +// setCurrentPage(i + 1)} +// > +// {i + 1} +// +// ))} +// setCurrentPage(p => Math.min(p + 1, totalPages))} +// disabled={currentPage === totalPages} +// /> +// setCurrentPage(totalPages)} +// disabled={currentPage === totalPages} +// /> +// */} +//
+// +// )} + +// {/* Add Submenu Modal */} +// setShowAddModal(false)}> +// +// Add New Submenu +// +// +//
+// +// Menu Item Description * +// +// +// {validationErrors.menuItemDesc} +// +// + +// +// Menu Item ID * +// +// +// {validationErrors.menuItemId} +// +// + +// +// Item Sequence * +// +// +// {validationErrors.itemSeq} +// +// + +// +// Module Name * +// +// +// {validationErrors.moduleName} +// +// + +// +// Main Menu Action Name * +// +// +// {validationErrors.main_menu_action_name} +// +// + +// +// Main Menu Icon Name +// +// + +// +// Status +// +// +// +// +// +//
+//
+// +// +// +// +//
+//
+// ); +// }; + +// export default SubMenuMaintenance; + + + + +// import React, { useEffect, useState } from "react"; +// import { useParams } from "react-router-dom"; +// import { getSubmenuItems, addSubmenuItem } from '../../APIServices/MenuMaintenanceAPI.js'; +// import { Table, Button, Form, Modal } from "react-bootstrap"; +// import { toast } from "react-toastify"; + +// const SubMenuMaintenance = () => { +// const { menuItemId } = useParams(); // This gets the parent ID from URL +// const [subMenus, setSubMenus] = useState([]); +// const [showAddModal, setShowAddModal] = useState(false); +// const [currentItem, setCurrentItem] = useState({ +// menuItemDesc: "", +// itemSeq: "", +// moduleName: "", +// main_menu_action_name: "#", // Default action +// status: "Enable", +// main_menu_icon_name: "fa-circle" // Default icon +// }); +// const [isLoading, setIsLoading] = useState(false); + +// useEffect(() => { +// fetchSubMenus(); +// }, [menuItemId]); + +// const fetchSubMenus = async () => { +// setIsLoading(true); +// try { +// const data = await getSubmenuItems(menuItemId); +// setSubMenus(data); +// } catch (err) { +// toast.error("Failed to fetch submenu items"); +// console.error(err); +// } finally { +// setIsLoading(false); +// } +// }; + +// const handleAdd = async () => { +// try { +// const addedItem = await addSubmenuItem(menuItemId, currentItem); + +// // Update state with new submenu +// setSubMenus([...subMenus, addedItem]); + +// // Reset form and close modal +// setCurrentItem({ +// menuItemDesc: "", +// itemSeq: "", +// moduleName: "", +// main_menu_action_name: "#", +// status: "Enable", +// main_menu_icon_name: "fa-circle" +// }); +// setShowAddModal(false); +// toast.success("Submenu added successfully!"); +// } catch (err) { +// toast.error(err.message || "Failed to add submenu"); +// } +// }; + +// return ( +//
+//
+//

Sub-Menus for Menu ID: {menuItemId}

+// +//
+ +// {/* Submenu Table */} +// +// +// +// +// +// +// +// +// +// +// +// {subMenus.map((item) => ( +// +// +// +// +// +// +// +// ))} +// +//
NameSequenceModuleActionStatus
{item.menuItemDesc}{item.itemSeq}{item.moduleName}{item.main_menu_action_name}{item.status ? "Enabled" : "Disabled"}
+ +// {/* Add Submenu Modal */} +// setShowAddModal(false)}> +// +// Add Submenu to Menu {menuItemId} +// +// +//
+// +// Submenu Name* +// setCurrentItem({...currentItem, menuItemDesc: e.target.value})} +// required +// /> +// + +// +// Sequence* +// setCurrentItem({...currentItem, itemSeq: e.target.value})} +// required +// /> +// + +// +// Module Name +// setCurrentItem({...currentItem, moduleName: e.target.value})} +// /> +// + +// +// Action Link +// setCurrentItem({...currentItem, main_menu_action_name: e.target.value})} +// /> +// + +// +// Icon Name +// setCurrentItem({...currentItem, main_menu_icon_name: e.target.value})} +// placeholder="fa-icon-name" +// /> +// + +// +// Status +// setCurrentItem({...currentItem, status: e.target.value})} +// > +// +// +// +// +//
+//
+// +// +// +// +//
+//
+// ); +// }; + +// export default SubMenuMaintenance; + + + + + + + + + + + +// ----- + + + + + +import React, { useEffect, useState } from "react"; +import { useParams } from "react-router-dom"; +import { + getSubmenuItems, + addSubmenuItem, + updateSubmenuItem, + deleteSubmenuItem +} from '../../APIServices/MenuMaintenanceAPI.js'; +import { Table, Button, Form, Modal, Dropdown } from "react-bootstrap"; +import { toast } from "react-toastify"; + +const SubMenuMaintenance = () => { + const { menuItemId } = useParams(); + const [subMenus, setSubMenus] = useState([]); + const [showAddModal, setShowAddModal] = useState(false); + const [showEditModal, setShowEditModal] = useState(false); + const [currentItem, setCurrentItem] = useState({ + menuItemId: "", menuItemDesc: "", itemSeq: "", moduleName: "", + main_menu_action_name: "#", status: "Enable", - main_menu_action_name: "", + main_menu_icon_name: "fa-circle" }); - const [data, setData] = useState([]); - - const [visibleColumns, setVisibleColumns] = useState({ - menu_id: true, - menuItemDesc: true, - itemSeq: true, - moduleName: true, - main_menu_action_name: true, - status: true, - }); - - const [isSubMenu, setIsSubMenu] = useState(false); - const [searchQuery, setSearchQuery] = useState(""); - const [menuItems, setMenuItems] = useState([]); - const [slicedSubMenus, setSlicedSubMenus] = useState([]); - const [currentMenuItem, setCurrentMenuItem] = useState({}); - const [subMenuItems, setSubMenuItems] = useState([]); + const [isLoading, setIsLoading] = useState(false); useEffect(() => { - // Simulate loading data - setTimeout(() => { - setLoading(false); - }, 3000); // Simulated 3 seconds loading - }, []); - - useEffect(() => { - if (selectedMainMenuId) { - setEntryForm((prev) => ({ ...prev, menuId: selectedMainMenuId })); - } - }, [selectedMainMenuId]); - - useEffect(() => { - const filteredSubMenus = subMenu - .filter( - (submenu) => - submenu.menuItemDesc && - submenu.menuItemDesc.toLowerCase().includes(searchQuery.toLowerCase()) - ) - .slice((currentPage - 1) * recordsPerPage, currentPage * recordsPerPage); - - setSlicedSubMenus(filteredSubMenus); - }, [subMenu, searchQuery, currentPage, recordsPerPage]); - - const handleInputChange = (e) => { - const { name, value } = e.target; - setEntryForm((prev) => ({ ...prev, [name]: value })); - }; - - const handleRowChange = (e) => { - const { name, value } = e.target; - setRowSelected((prev) => ({ ...prev, [name]: value })); - }; - - const handleSearch = (query) => { - setSearchQuery(query); - }; - - // const goToAdd = () => { - // setEntryForm((prev) => ({ - // ...prev, - // menuId: selectedMainMenuId, // Set the main menu ID - // })); - // setModalAdd(true); - // }; - - const goToAdd = () => { - console.log("selectedMainMenuId:", selectedMainMenuId); // Debugging line - if (!selectedMainMenuId) { - toast.error("Please select a main menu item first."); - return; - } - setEntryForm((prev) => ({ - ...prev, - menuId: selectedMainMenuId, - })); - setModalAdd(true); - }; - - - const onSubmit = async (event) => { - event.preventDefault(); - - // Include menuId in the form data - const formData = { - menuItemDesc: entryForm.menuItemDesc, - }; + fetchSubMenus(); + }, [menuItemId]); + const fetchSubMenus = async () => { + setIsLoading(true); try { - // Pass menuId as a string - const data = await addSubmenuItem( - selectedMainMenuId.toString(), - formData - ); - toast.success("Submenu item added successfully!"); - console.log("Submenu item added successfully:", data); - // Handle successful submission, e.g., close modal, refresh data, etc. - setModalAdd(false); - } catch (error) { - console.error("Error adding submenu item:", error); - toast.error( - "Unexpected error: " + - (error.message || "Server error occurred. Please try again.") - ); - // Handle error, e.g., show a message to the user + const data = await getSubmenuItems(menuItemId); + setSubMenus(data); + } catch (err) { + toast.error("Failed to fetch submenu items"); + console.error(err); + } finally { + setIsLoading(false); } }; - const goToEdit = (user) => { - setRowSelected(user); - setEntryForm({ - menuId: user.menuId, - menuItemDesc: user.menuItemDesc, + const handleAdd = async () => { + try { + const addedItem = await addSubmenuItem(menuItemId, currentItem); + setSubMenus([...subMenus, addedItem]); + resetForm(); + setShowAddModal(false); + toast.success("Submenu added successfully!"); + } catch (err) { + toast.error(err.message || "Failed to add submenu"); + } + }; + + const handleEdit = (item) => { + setCurrentItem({ + ...item, + status: item.status ? "Enable" : "Disable" }); - setModalEdit(true); + setShowEditModal(true); }; - const onUpdate = (e) => { - e.preventDefault(); - - // Prepare the updated entry from the form - const updatedEntry = { - menuId: entryForm.menuId, - menuItemDesc: entryForm.menuItemDesc, - // Add other fields as needed - }; - - // Find the index of the subMenu to update - const index = slicedSubMenus.findIndex( - (subMenu) => subMenu.menuId === updatedEntry.menuId - ); - - if (index !== -1) { - // Update the subMenu in the state - const updatedSubMenus = [...slicedSubMenus]; - updatedSubMenus[index] = updatedEntry; - - // Update the state with the new subMenus list - setSlicedSubMenus(updatedSubMenus); - - // Close the modal after updating - setModalEdit(false); + const handleUpdate = async () => { + try { + const updatedItem = await updateSubmenuItem(currentItem.menuItemId, currentItem); + setSubMenus(subMenus.map(item => + item.menuItemId === updatedItem.menuItemId ? updatedItem : item + )); + resetForm(); + setShowEditModal(false); + toast.success("Submenu updated successfully!"); + } catch (err) { + toast.error(err.message || "Failed to update submenu"); } }; - const onDelete = (user) => { - setRowSelected(user); - setModalDelete(true); + const handleDelete = async (id) => { + if (window.confirm("Are you sure you want to delete this submenu?")) { + try { + await deleteSubmenuItem(id); + setSubMenus(subMenus.filter(item => item.menuItemId !== id)); + toast.success("Submenu deleted successfully!"); + } catch (err) { + toast.error(err.message || "Failed to delete submenu"); + } + } }; - const confirmDelete = () => { - // Logic to delete - console.log("Deleted:", rowSelected); - setModalDelete(false); + const resetForm = () => { + setCurrentItem({ + menuItemId: "", + menuItemDesc: "", + itemSeq: "", + moduleName: "", + main_menu_action_name: "#", + status: "Enable", + main_menu_icon_name: "fa-circle" + }); }; - // pagination - const toggleColumn = (column) => { - setVisibleColumns((prev) => ({ - ...prev, - [column]: !prev[column], - })); - }; - - const totalPages = Math.ceil(subMenu.length / recordsPerPage); - const handlePageChange = (pageNumber) => { - setCurrentPage(pageNumber); - }; - const handleRecordsPerPageChange = (number) => { - setRecordsPerPage(number); - }; return ( -
- {loading ? ( - - ) : ( -
- {/* Header */} -
-
-

Sub-Menu Maintenance

- Sub Menu -
-
+
+
+

Sub-Menus for Menu ID: {menuItemId}

+ +
- - {/* Left: Search Bar */} - - + + + No. + Sub-Menu Item Name + ID + Sequence + Module Name + Menu Action Link + Status + Actions + + + + {subMenus.map((item, index) => ( + + {index + 1} + {item.menuItemDesc} + {item.menuItemId} + {item.itemSeq} + {item.moduleName} + {item.main_menu_action_name} + {item.status ? "Enable" : "Disable"} + + + + + + + handleEdit(item)}> + Edit + + handleDelete(item.menuItemId)}> + Delete + + + + + + ))} + + + + {/* Add Submenu Modal */} + setShowAddModal(false)}> + + Add Submenu + + +
+ + Sub-Menu Item Name* + setCurrentItem({...currentItem, menuItemDesc: e.target.value})} + required + /> + + + Sequence* + setCurrentItem({...currentItem, itemSeq: e.target.value})} + required + /> + + + Module Name + setCurrentItem({...currentItem, moduleName: e.target.value})} + /> + + + Menu Action Link + setCurrentItem({...currentItem, main_menu_action_name: e.target.value})} + /> + +
+
+ + + + +
+ + {/* Edit Submenu Modal */} + setShowEditModal(false)}> + + Update Sub Menu Maintenance + + +
+ + Menu ID + + + + Menu Item Name* + setCurrentItem({...currentItem, menuItemDesc: e.target.value})} + required + /> + + + Sequence* + setCurrentItem({...currentItem, itemSeq: e.target.value})} + required + /> + + + Module Name + setCurrentItem({...currentItem, moduleName: e.target.value})} + /> + + + Menu Action Link + setCurrentItem({...currentItem, main_menu_action_name: e.target.value})} + /> + + + Status + setCurrentItem({...currentItem, status: e.target.value})} > - - - - handleSearch(e.target.value)} - style={{ - padding: "10px", - border: "none", - paddingRight: "5px", // More space on the right side of input field - }} - /> - - - -
- -
- - - -
- - - - - {Object.entries(visibleColumns).map( - ([key, visible]) => - visible && ( - - ) - )} - - - - - {slicedSubMenus.length === 0 ? ( - - - - ) : ( - slicedSubMenus.map((subMenu, index) => ( - - - {Object.keys(visibleColumns).map( - (key) => - visibleColumns[key] && ( - - ) - )} - - - )) - )} - -
No - {key.charAt(0).toUpperCase() + key.slice(1)} - Actions
visibleColumns[key] - ).length + - (isSubMenu ? 1 : 2) - } - className="text-center" - > - No menu items found. Please add new items. -
{index + 1} - {key === "status" ? ( - - {subMenu.status ? "Enabled" : "Disabled"} - - ) : ( - subMenu[key] - )} - - goToEdit(subMenu)} - style={{ - cursor: "pointer", - fontSize: "1rem", - color: "green", - marginRight: "15px", - }} - /> - onDelete(subMenu)} - style={{ - cursor: "pointer", - fontSize: "1rem", - color: "#dc3545", - }} - /> -
-
- - {/* Manage Columns & Records Per Page */} - - - - - Manage Columns - - - {Object.keys(visibleColumns).map((column) => ( - toggleColumn(column)} - > - - - ))} - - - - - - - - - - - {[1, 5, 10, 20, 50].map((number) => ( - handleRecordsPerPageChange(number)} - className="text-dark d-flex justify-content-between align-items-center" - > - {number} - - - ))} - - - - - - - - handlePageChange(currentPage - 1)} - /> - - {[...Array(totalPages)].map((_, index) => ( - - handlePageChange(index + 1)} - style={{ color: "#0b6592" }} - > - {index + 1} - - - ))} - - handlePageChange(currentPage + 1)} - /> - - - - {/* Modals */} - {modalAdd && ( -
-
-
-
-
Add Sub-Menu
- -
-
- - - - - - -
-
-
-
- )} - - {modalEdit && ( -
-
-
-
-
Edit Sub-Menu
- -
-
-
- - - -
-
-
-
-
- )} -
- )} + + + + + + + + + + +
); }; -export default SubMenuMaintenance; +export default SubMenuMaintenance; \ No newline at end of file diff --git a/src/components/Dashboard/SystemParameter.js b/src/components/Dashboard/SystemParameter.js index c50f886..efae38d 100644 --- a/src/components/Dashboard/SystemParameter.js +++ b/src/components/Dashboard/SystemParameter.js @@ -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 ( +//
+// {loading ? ( +// +// ) : ( +// +//

+// System Parameter Settings +//

+//
+// +// +//
Setup Code
+// +// +//
Value
+// +//
+ +// {Object.keys(formData).map((key, index) => +// key !== "upload_Logo" ? ( +// +// +// +// {key +// .split(/(?=[A-Z])/) +// .join(" ") +// .replace(/\b\w/g, (l) => l.toUpperCase())} +// +// +// +// +// +// +// ) : ( +// +// +// Upload Logo +// +// +// +// +// +// ) +// )} + +//
+// +// +//
+//
+//
+// )} +//
+// ); +// }; + +// 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 ? ( ) : ( - +

{ System Parameter Settings

- +
Setup Code
@@ -303,7 +507,7 @@ const SystemParameterForm = () => { { { - 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 ( -
+
{loading ? ( - - ):( + + ) : (
- -
-

Token Registry

-
+ {/* Token Generation Card */} + + + Token Management + + + +

Manage your API tokens here. Generate new tokens or delete existing ones.

+
+
- - {/* Left: Search Bar */} - - - - - - handleSearch(e.target.value)} - style={{ - padding: "10px", - border: "none", - paddingRight: "5px", // More space on the right side of input field - }} - /> - - +
+

Token Registry

+
- {/*Add Icons */} - - <> - {/* Add Icon */} - openModal(true)} - style={{ - cursor: "pointer", - fontSize: "1.5rem", - color: "#747264", - marginRight: "20px", - }} - /> - - - -
- - -
- - - - {Object.keys(visibleColumns).filter(key => visibleColumns[key]).map(key => ( - - ))} - - - - {slicedTokens.length === 0 ? ( - - - - ) : ( - slicedTokens.map((token, index) => ( - - {Object.keys(visibleColumns).filter(key => visibleColumns[key]).map(key => ( - + - {token.isActive ? "Active" : "Inactive"} - - ) : ( - token[key] - )} - - ))} - - )) - )} - + + + + handleSearch(e.target.value)} + style={{ padding: "10px", border: "none" }} + /> + + -
{key.charAt(0).toUpperCase() + key.slice(1)}
visibleColumns[key] - ).length - } - className="text-center" - > - No Data Available -
- {key === "actions" ? ( - <> - openModal(token)} - className="me-2" - style={{ - cursor: "pointer", - fontSize: "1rem", - color: "green", - marginRight: "15px", - }} - /> - handleDelete(token.tokenId)} - style={{ - cursor: "pointer", - fontSize: "1rem", - color: "#dc3545", - }} - /> - - ) : key === "isActive" ? ( - +
-
+ + openModal()} + style={{ + cursor: "pointer", + fontSize: "1.5rem", + color: "#747264", + marginRight: "20px", + }} + /> + + + - {/* Manage Columns & Records Per Page */} - - - - - Manage Columns - - - {Object.keys(visibleColumns).map((column) => ( - toggleColumn(column)} +
+ + + + {Object.keys(visibleColumns).filter(key => visibleColumns[key]).map(key => ( + + ))} + + + + {slicedTokens.length === 0 ? ( + + + + ) : ( + slicedTokens.map((token, index) => ( + + {Object.keys(visibleColumns).filter(key => visibleColumns[key]).map(key => ( + + ))} + + )) + )} + +
{key.charAt(0).toUpperCase() + key.slice(1)}
visibleColumns[key]).length} + className="text-center" + > + No Data Available +
+ {key === "actions" ? ( + <> + openModal(token)} + className="me-2" + style={{ + cursor: "pointer", + fontSize: "1rem", + color: "green", + marginRight: "15px", + }} + /> + handleDelete(token.id)} + style={{ + cursor: "pointer", + fontSize: "1rem", + color: "#dc3545", + }} + /> + + ) : key === "isActive" ? ( + + {token.isActive ? "Active" : "Inactive"} + + ) : ( + token[key] + )} +
+
+ + {/* Manage Columns & Records Per Page */} + + + + + Manage Columns + + + {Object.keys(visibleColumns).map((column) => ( + toggleColumn(column)}> + + + ))} + + + + + + + - -
- ))} -
-
- + + + + {[1, 5, 10, 20, 50].map((number) => ( + handleRecordsPerPageChange(number)} + className="text-dark d-flex justify-content-between align-items-center" + > + {number} + + + ))} + + + +
- - - - - - - {[1, 5, 10, 20, 50].map((number) => ( - handleRecordsPerPageChange(number)} - className="text-dark d-flex justify-content-between align-items-center" - > - {number} - - - ))} - - - - + + + handlePageChange(currentPage - 1)} /> + + {[...Array(totalPages)].map((_, index) => ( + + handlePageChange(index + 1)} style={{ color: "#0b6592" }}> + {index + 1} + + + ))} + + handlePageChange(currentPage + 1)} /> + + - - - handlePageChange(currentPage - 1)} + {/* Add/Edit Token Modal */} + + + Generate New Token + + + + + + Token Name + setNewTokenName(e.target.value)} + required + className="custom-hover-border" + placeholder="Enter a name for the new token" + /> + + + + Token Scopes + { + 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 => ( + + ))} + + + Select the permissions this token should have (hold Ctrl/Cmd to select multiple) + + + + {generatedToken && ( + + Generated Token + - - {[...Array(totalPages)].map((_, index) => ( - - handlePageChange(index + 1)} - style={{ color: "#0b6592" }} - > - {index + 1} - - - ))} - - handlePageChange(currentPage + 1)} - /> - - - - - - setShowAddEditModal(false)}> - - {isEditing ? "Edit Token" : "Add Token"} - - - - - - Token Name - - - - Token Value - - - - - - - - - - - - -
+ + Copy this token and store it securely. You won't be able to see it again. + + + )} + + + + + + + + +
)}
- ); } -export default TOKENRegistry; +export default TOKENRegistry; \ No newline at end of file diff --git a/src/components/Dashboard/UserGroupMaintenance.js b/src/components/Dashboard/UserGroupMaintenance.js index d8e2616..5095c6e 100644 --- a/src/components/Dashboard/UserGroupMaintenance.js +++ b/src/components/Dashboard/UserGroupMaintenance.js @@ -313,7 +313,7 @@ export function UserGroupMaintenance() { ) .slice((currentPage - 1) * recordsPerPage, currentPage * recordsPerPage); return ( -
+
{loading ? ( ) : ( @@ -366,11 +366,11 @@ export function UserGroupMaintenance() { {/*Add Icons */} <> - Add Group} - > - */} + {/* handleAddItem(true)} style={{ @@ -379,8 +379,8 @@ export function UserGroupMaintenance() { color: "#747264", marginRight: "20px", }} - /> - + /> */} + {/* */} Download template} @@ -426,7 +426,7 @@ export function UserGroupMaintenance() { }} /> - Menu} > @@ -438,7 +438,7 @@ export function UserGroupMaintenance() { color: "#747264", }} /> - + */} {/* Add Icon */} diff --git a/src/components/Dashboard/UserMaintenanceView.js b/src/components/Dashboard/UserMaintenanceView.js index 7adf1a7..531d06c 100644 --- a/src/components/Dashboard/UserMaintenanceView.js +++ b/src/components/Dashboard/UserMaintenanceView.js @@ -579,7 +579,7 @@ function UserMaintenanceView() { .slice((currentPage - 1) * recordsPerPage, currentPage * recordsPerPage); return ( -
+
{loading ? ( ):( @@ -634,7 +634,7 @@ function UserMaintenanceView() { <> {/* Add Icon */} - Add Items}> + {/* Add Items}> handleAddItem(true)} @@ -649,7 +649,7 @@ function UserMaintenanceView() { title="Add Item" /> - + */} Download template}> - Menu Items}> + {/* Menu Items}> - + */} diff --git a/src/components/Dashboard/dashboardnew/EditNewDash/EditNewDash.js b/src/components/Dashboard/dashboardnew/EditNewDash/EditNewDash.js index 328f2b3..bc4bb22 100644 --- a/src/components/Dashboard/dashboardnew/EditNewDash/EditNewDash.js +++ b/src/components/Dashboard/dashboardnew/EditNewDash/EditNewDash.js @@ -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 = () => { > ({ i: widget.i, @@ -458,17 +462,23 @@ const EditNewDash = () => { {widget.name} - + + - - - + } + label="Show Legend" + /> + + setCurrentEditWidget((prev) => ({ ...prev, showLabel: e.target.checked })) + } + /> + } + label="Show Labels" + /> + + + + + + + + ); }; diff --git a/src/components/Dashboard/sequencegenerator.js b/src/components/Dashboard/sequencegenerator.js new file mode 100644 index 0000000..4f60ff5 --- /dev/null +++ b/src/components/Dashboard/sequencegenerator.js @@ -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) => ( + , + onClick: () => handleEdit(record) + }, + { + key: 'delete', + label: 'Delete', + icon: , + danger: true, + onClick: () => handleDelete(record.id) + } + ] + }} + trigger={['click']} + > + +
+ + `Total ${total} sequences`, + }} + /> + + Update Sequence Generator} + open={visible} + onOk={handleSubmit} + onCancel={() => setVisible(false)} + confirmLoading={loading} + width={700} + > + {currentSequence && ( +
+
+ + + + + + + + + + +
Sequence ID{currentSequence.id}
Demonstration +
+ {currentSequence.demonstration} +
+
+
+ )} + +
+ Name*} + rules={[{ required: true, message: 'Please input the sequence name!' }]} + > + + + + Sequence Code} + > + + + + Prefix*} + rules={[{ required: true, message: 'Please input the prefix!' }]} + > + + + + Suffix} + > + + + + Separator} + > + + + + Starting No} + > + + + + Current No} + > + + +
+ +
+ ); +}; + +export default SequenceGenerator; \ No newline at end of file diff --git a/src/components/Dashboard/sequencegeneratorapi.js b/src/components/Dashboard/sequencegeneratorapi.js new file mode 100644 index 0000000..c4a9180 --- /dev/null +++ b/src/components/Dashboard/sequencegeneratorapi.js @@ -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; \ No newline at end of file diff --git a/src/components/Dashboard/tokenregistryapi.js b/src/components/Dashboard/tokenregistryapi.js new file mode 100644 index 0000000..497f0b7 --- /dev/null +++ b/src/components/Dashboard/tokenregistryapi.js @@ -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; + } +}; \ No newline at end of file diff --git a/src/components/Headers/Header.js b/src/components/Headers/Header.js index 7e92d6f..496dae1 100644 --- a/src/components/Headers/Header.js +++ b/src/components/Headers/Header.js @@ -157,7 +157,7 @@ const Header = () => { return ( <>
{" "} diff --git a/src/components/Headers/UserHeader.js b/src/components/Headers/UserHeader.js index 8b79d13..a4e1fec 100644 --- a/src/components/Headers/UserHeader.js +++ b/src/components/Headers/UserHeader.js @@ -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 ( - <> -
- {/* Mask */} - - {/* Header container */} - - - -

Hello Jesse

-

- This is your profile page. You can see the progress you've made - with your work and manage your projects or assigned tasks -

- - -
-
-
- +
+ {/* Mask */} + + {/* Header container */} + + + +

+ Hello {user?.firstName || "User"} +

+

+ Welcome back, {user?.role || "team member"}! Manage your profile and activity here. +

+ +
+
+
); }; diff --git a/src/components/Navbars/AdminNavbar.css b/src/components/Navbars/AdminNavbar.css index 895d474..7f05f14 100644 --- a/src/components/Navbars/AdminNavbar.css +++ b/src/components/Navbars/AdminNavbar.css @@ -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; - } -} \ No newline at end of file + +} diff --git a/src/components/Navbars/AdminNavbar.js b/src/components/Navbars/AdminNavbar.js index 343ef61..4f64fae 100644 --- a/src/components/Navbars/AdminNavbar.js +++ b/src/components/Navbars/AdminNavbar.js @@ -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 ( - -
- {/* Brand */} - - {brandText} - + <> + + +
+ {/* Toggle sidebar on small screens */} + - {/* Navigation Icons */} -
- - + + {brandText} - - - - - - - - - - - - -
- {/* Search and Profile */} -
-
- {/* - - - - - - - - - */} - +
+ + + + + + + + + + + + + + + +
- +
+ + + + { /* Mobile Right Sidebar */} +
+ +
-
-
+ + + {/* Mobile Sidebar */} +
+ + + + + + + + + + + + + + + +
+ + + ); + 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; \ No newline at end of file + +export default AdminNavbar; diff --git a/src/components/Sidebar/Sidebar.css b/src/components/Sidebar/Sidebar.css index 6b64608..1b37712 100644 --- a/src/components/Sidebar/Sidebar.css +++ b/src/components/Sidebar/Sidebar.css @@ -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; } \ No newline at end of file diff --git a/src/components/Sidebar/Sidebar.js b/src/components/Sidebar/Sidebar.js index aec5c3f..bc78fa8 100644 --- a/src/components/Sidebar/Sidebar.js +++ b/src/components/Sidebar/Sidebar.js @@ -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 ( - } - > - {route.submenu.map((submenu, subKey) => ( - } - icon={} - > - {submenu.name} - - ))} - - ); - } - - return ( - } - icon={} - > - {route.name} - - ); - }); - }; - - const { logo } = props; - return (
-
- {/* {logo && ( - - {logo.imgAlt} - - )} */} +
- {renderMenuItems()} + }> + navigate("/admin/regform")}> + Regform + + navigate("/admin/error404")}> + Additional container + + + + } + onClick={() => navigate("/admin/error404")} + > + Masters +
@@ -137,4 +71,4 @@ Sidebar.propTypes = { onSidebarToggle: PropTypes.func, }; -export default Sidebar; \ No newline at end of file +export default Sidebar; diff --git a/src/layouts/Admin.js b/src/layouts/Admin.js index 4f62cad..d957292 100644 --- a/src/layouts/Admin.js +++ b/src/layouts/Admin.js @@ -70,7 +70,7 @@ const Admin = (props) => { > {/* This is where the nested routes will render */} -
+
diff --git a/src/routes.js b/src/routes.js index 5dfdb9b..fdf3dd5 100644 --- a/src/routes.js +++ b/src/routes.js @@ -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: , // should be a component function or class +// component: , // 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: , // should be a component function or class + component: , // should be a component function or class layout: "/admin", showInSidebar: false }, diff --git a/src/views/Index.js b/src/views/Index.js index 254fe4b..cc2de0e 100644 --- a/src/views/Index.js +++ b/src/views/Index.js @@ -81,285 +81,285 @@ const Index = (props) => { setChartExample1Data("data" + index); }; return ( - <>Home Page - //
+ // <>Home Page +
- //
- // +
+ - // {/* Page content */} - // - // - // - // - // - // - //
- //
- // Overview - //
- //

Sales value

- //
- //
- // - //
- //
- //
- // - // {/* Chart */} - //
- // {chartExample1[chartExample1Data] ? ( - // - // ) : ( - //

Loading chart...

- // )} + {/* Page content */} + + + + + + +
+
+ Overview +
+

Sales value

+
+
+ +
+
+
+ + {/* Chart */} +
+ {chartExample1[chartExample1Data] ? ( + + ) : ( +

Loading chart...

+ )} - //
- //
- //
- // - // - // - // - // - //
- //
- // Performance - //
- //

Total orders

- //
- //
- //
- // - // {/* Chart */} - //
- // - //
- //
- //
- // - //
- // - // - // - // - // - //
- //

Page visits

- //
- //
- // - //
- //
- //
- // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - //
Page nameVisitorsUnique usersBounce rate
/argon/4,569340 - // 46,53% - //
/argon/index.html3,985319 - // {" "} - // 46,53% - //
/argon/charts.html3,513294 - // {" "} - // 36,49% - //
/argon/tables.html2,050147 - // 50,87% - //
/argon/profile.html1,795190 - // {" "} - // 46,53% - //
- //
- // - // - // - // - // - //
- //

Social traffic

- //
- //
- // - //
- //
- //
- // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - // - //
ReferralVisitors - //
Facebook1,480 - //
- // 60% - //
- // - //
- //
- //
Facebook5,480 - //
- // 70% - //
- // - //
- //
- //
Google4,807 - //
- // 80% - //
- // - //
- //
- //
Instagram3,678 - //
- // 75% - //
- // - //
- //
- //
twitter2,645 - //
- // 30% - //
- // - //
- //
- //
- //
- // - //
- //
- //
+
+ + + + + + + +
+
+ Performance +
+

Total orders

+
+
+
+ + {/* Chart */} +
+ +
+
+
+ + + + + + + +
+

Page visits

+
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Page nameVisitorsUnique usersBounce rate
/argon/4,569340 + 46,53% +
/argon/index.html3,985319 + {" "} + 46,53% +
/argon/charts.html3,513294 + {" "} + 36,49% +
/argon/tables.html2,050147 + 50,87% +
/argon/profile.html1,795190 + {" "} + 46,53% +
+
+ + + + + +
+

Social traffic

+
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReferralVisitors +
Facebook1,480 +
+ 60% +
+ +
+
+
Facebook5,480 +
+ 70% +
+ +
+
+
Google4,807 +
+ 80% +
+ +
+
+
Instagram3,678 +
+ 75% +
+ +
+
+
twitter2,645 +
+ 30% +
+ +
+
+
+
+ +
+ +
); }; diff --git a/src/views/examples/Error404.js b/src/views/examples/Error404.js new file mode 100644 index 0000000..1b9cb72 --- /dev/null +++ b/src/views/examples/Error404.js @@ -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 ( +
+
+
+ 🛡️❌ +
+

error 404

+

+ Not found your page requested. +

+ + +
+
+ ); +}; + +export default Error404; diff --git a/src/views/examples/Profile.js b/src/views/examples/Profile.js index a1154c4..4ce9f87 100644 --- a/src/views/examples/Profile.js +++ b/src/views/examples/Profile.js @@ -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 ( +// // <> +// // +// // {/* Page content */} +// // {/* +// // +// // +// // +// // +// // +// // +// //

My Profile Settings

+// // +// //
+// //
+// // +// //
+// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// // +// //
+// //
+// //
+// // +// //
+// //
*/} +// // +// // ); +// // }; -* 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 ( +//
+//

My Profile Settings

-// reactstrap components -import { - Button, - Card, - CardHeader, - CardBody, - FormGroup, - Form, - Input, - Container, - Row, - Col, -} from "reactstrap"; -// core components -import UserHeader from "components/Headers/UserHeader.js"; +//
+// +// +//
+ +//
+// +// +//
+ +//
+// +// +//
+ +//
+// +// +//
+ +//
+// +// +//
+ +//
+// +// +//
+ +// + +//
+ +//

Password: Change Password for your account Change password

+ +//
+ +//

Security: Logout of all sessions except this current browser Logout other sessions

+ +//
+ +//

Deactivation: Remove access to all organizations and workspace in CloudnSure Deactivate account

+//
+// ); +// }; + +// 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 ( - <> - - {/* Page content */} - - - - - - -
- - - -
- - -
-
- - -
-
-
- 22 - Friends -
-
- 10 - Photos -
-
- 89 - Comments -
-
-
-
-
- - - - - - - - -

My account

- - - - -
-
- -
-
- User information -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- {/* Address */} -
- Contact information -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- {/* Description */} -
About me
-
- - - - -
-
-
-
- - - - +
+

My Profile Settings

+ + {/* Simple Image Upload Section */} +
+
PROFILE PHOTO
+
+
+ {preview ? ( + Profile Preview + ) : ( +
+ )} +
+
+ + +
+
+ + {/* Action buttons - shown only when an image is selected */} + {preview && ( +
+ + +
+ )} +
+ + {/* Rest of the profile form */} +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + + +
+ +

Password: Change Password for your account Change password

+ +
+ +

Security: Logout of all sessions except this current browser Logout other sessions

+ +
+ +

Deactivation: Remove access to all organizations and workspace in CloudnSure Deactivate account

+
); }; -export default Profile; +export default Profile; \ No newline at end of file diff --git a/src/views/examples/about.js b/src/views/examples/about.js new file mode 100644 index 0000000..4a16f2d --- /dev/null +++ b/src/views/examples/about.js @@ -0,0 +1,23 @@ +// src/views/examples/about.js +import React from "react"; + +const About = () => ( +
+ About Us { + e.target.onerror = null; + e.target.src = "https://via.placeholder.com/300x200?text=About+Image"; + }} + style={{ width: "300px", height: "200px", objectFit: "cover" }} +/> + +

About Us

+

+ Create new project for new users if you have access. If you don't have access, please contact the admin. +

+
+); + +export default About; diff --git a/src/views/examples/regform.js b/src/views/examples/regform.js new file mode 100644 index 0000000..1ccb98b --- /dev/null +++ b/src/views/examples/regform.js @@ -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 ( +
+

Registration Records

+ + {loading ? ( +
Loading...
+ ) : ( + <> + {data.length === 0 ? ( +
No data available
+ ) : ( + + + + + + + + + + + + {data.map((entry, index) => ( + + + + + + + + ))} + +
+ + + Name + + Roll Number + + Date Field + Email Field
+ + {entry.name}{entry.rollNumber}{entry.date}{entry.email}
+ )} + + )} + + +
+ ); +}; + +export default Regform; diff --git a/src/views/examples/resetPassword.js b/src/views/examples/resetPassword.js index f4fca59..714a48b 100644 --- a/src/views/examples/resetPassword.js +++ b/src/views/examples/resetPassword.js @@ -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 ( - //
- //
- //
Forgot My Username and Password
- //

- // By signing up, I agree to the CloudnSure Privacy Policy and Terms of Service. - //

- //
- //
- // - // - //
- // - //
- // {message &&

{message}

} - // {error &&

{error}

} - //
- //
+ const toggleShowPassword = () => { + setShowPassword(!showPassword); + }; -
-
+ const handleSubmit = (e) => { + e.preventDefault(); + navigate('/error404'); // Assuming your route path is /error404 + }; + + return (
-
Forgot My Username and Password
-

- By signing up, I agree to the CloudnSure{' '} - - Privacy Policy - {' '} - and{' '} - - Terms of Service - . -

-
-
- - -
- -
- {message &&

{message}

} - {error &&

{error}

} -
-
-
+
+

Please Reset Your Password

+

you're signed in as sysadmin

- - ); -} +
+ {[ + { 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) => ( +
+ + setter(e.target.value)} + /> + + {showPassword ? : } + +
+ ))} + + + +
+
+ + + +
+
+
+ ); +}; export default ResetPassword;