1053 lines
37 KiB
JavaScript
1053 lines
37 KiB
JavaScript
// import React, { useState, useEffect } from 'react';
|
|
// import { Button, Dropdown, Table, Modal, Form } from 'react-bootstrap';
|
|
// import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
// import { faEdit, faTrashAlt, faPlus, faBars } from '@fortawesome/free-solid-svg-icons';
|
|
// import 'bootstrap/dist/css/bootstrap.min.css';
|
|
// import '../Dashboard/MenuMaitenance.css';
|
|
|
|
// function MenuMaintenance() {
|
|
// const [menuItems, setMenuItems] = useState([]);
|
|
// const [subMenuItems, setSubMenuItems] = useState([]);
|
|
// const [showAddEditPopup, setShowAddEditPopup] = useState(false);
|
|
// const [currentMenuItem, setCurrentMenuItem] = useState({});
|
|
// const [isEditing, setIsEditing] = useState(false);
|
|
// const [recordsPerPage, setRecordsPerPage] = useState(10);
|
|
// const [visibleColumns, setVisibleColumns] = useState({
|
|
// menuItemId: true,
|
|
// menuItemDesc: true,
|
|
// main_menu_action_name: true,
|
|
// status: true
|
|
// });
|
|
// const [isSubMenu, setIsSubMenu] = useState(false);
|
|
// const [parentMenuItemId, setParentMenuItemId] = useState(null);
|
|
|
|
// useEffect(() => {
|
|
// const apiUrl = `${process.env.REACT_APP_API_URL}/api1/submenu1`;
|
|
// const token = localStorage.getItem("authToken");
|
|
|
|
// 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(`Error: ${response.status}`);
|
|
// }
|
|
|
|
// const data = await response.json();
|
|
// setMenuItems(data);
|
|
// } catch (error) {
|
|
// console.error('Fetching error:', error);
|
|
// }
|
|
// };
|
|
|
|
// fetchMenuItems();
|
|
// }, []);
|
|
|
|
// const toggleColumn = (column) => {
|
|
// setVisibleColumns(prev => ({
|
|
// ...prev,
|
|
// [column]: !prev[column]
|
|
// }));
|
|
// };
|
|
|
|
// const openAddEditPopup = (menuItem = {}) => {
|
|
// setIsEditing(!!menuItem.menuItemId);
|
|
// setCurrentMenuItem(menuItem);
|
|
// setShowAddEditPopup(true);
|
|
// };
|
|
|
|
// const handleInputChange = (event) => {
|
|
// const { name, value } = event.target;
|
|
// setCurrentMenuItem(prev => ({ ...prev, [name]: value }));
|
|
// };
|
|
|
|
// const handleSubmit = (event) => {
|
|
// event.preventDefault();
|
|
// if (isEditing) {
|
|
// if (isSubMenu) {
|
|
// setSubMenuItems(subMenuItems.map(item =>
|
|
// item.menuItemId === currentMenuItem.menuItemId ? currentMenuItem : item
|
|
// ));
|
|
// } else {
|
|
// setMenuItems(menuItems.map(item =>
|
|
// item.menuItemId === currentMenuItem.menuItemId ? currentMenuItem : item
|
|
// ));
|
|
// }
|
|
// } else {
|
|
// if (isSubMenu) {
|
|
// setSubMenuItems([...subMenuItems, { ...currentMenuItem, menuItemId: `ID-${subMenuItems.length + 1}` }]);
|
|
// } else {
|
|
// setMenuItems([...menuItems, { ...currentMenuItem, menuItemId: `ID-${menuItems.length + 1}` }]);
|
|
// }
|
|
// }
|
|
// setShowAddEditPopup(false);
|
|
// };
|
|
|
|
// const handleDelete = (menuItemId) => {
|
|
// if (isSubMenu) {
|
|
// setSubMenuItems(subMenuItems.filter(item => item.menuItemId !== menuItemId));
|
|
// } else {
|
|
// setMenuItems(menuItems.filter(item => item.menuItemId !== menuItemId));
|
|
// }
|
|
// };
|
|
|
|
// const handleRecordsPerPageChange = (number) => {
|
|
// setRecordsPerPage(number);
|
|
// };
|
|
|
|
// const handleSubMenuClick = async (menuItemId) => {
|
|
// try {
|
|
<<<<<<< HEAD
|
|
// const apiUrl = `http://localhost:9292/api1/submenu1/${menuItemId}`;
|
|
=======
|
|
// const apiUrl = `http://157.66.191.31:33266/api1/submenu1/${menuItemId}`;
|
|
>>>>>>> 1c0592d (commit new code)
|
|
// const response = await fetch(apiUrl, {
|
|
// method: 'GET',
|
|
// headers: {
|
|
// 'Content-Type': 'application/json',
|
|
// Authorization: 'Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzeXNhZG1pbiIsInNjb3BlcyI6IlJPTEVfQURNSU4sUk9MRV9EZXZlbG9wZXIiLCJpYXQiOjE3MTU1ODc1ODEsImV4cCI6MTcxODE3OTU4MX0.hJ9heWuagVZB0WRbPNcIiCvMuQ4ASmth2mdSkGrkGXs',
|
|
// }
|
|
// });
|
|
// if (!response.ok) {
|
|
// throw new Error(`Error: ${response.status}`);
|
|
// }
|
|
// const data = await response.json();
|
|
// setSubMenuItems(data);
|
|
// setParentMenuItemId(menuItemId);
|
|
// setIsSubMenu(true);
|
|
// } catch (error) {
|
|
// console.error('Fetching sub-menu error:', error);
|
|
// }
|
|
// };
|
|
|
|
// const handleBackToMainMenu = () => {
|
|
// setIsSubMenu(false);
|
|
// setSubMenuItems([]);
|
|
// setParentMenuItemId(null);
|
|
// };
|
|
|
|
// return (
|
|
// <div className="container mt-5">
|
|
// <div className="d-flex justify-content-end mb-2">
|
|
// <button onClick={() => openAddEditPopup()} className="btn btn-success">
|
|
// <FontAwesomeIcon icon={faPlus} /> ADD
|
|
// </button>
|
|
// {isSubMenu && (
|
|
// <button onClick={handleBackToMainMenu} className="btn btn-success ms-2">
|
|
// Back to Main Menu
|
|
// </button>
|
|
// )}
|
|
// </div>
|
|
|
|
// <div className='table-responsive'>
|
|
// <Table striped bordered hover>
|
|
// <thead>
|
|
// <tr>
|
|
// {Object.keys(visibleColumns).map(key => visibleColumns[key] && (
|
|
// <th key={key}>{key.charAt(0).toUpperCase() + key.slice(1)}</th>
|
|
// ))}
|
|
// <th>Actions</th>
|
|
// {!isSubMenu && <th>Sub-Menu</th>} {/* Add sub-menu column for main menu */}
|
|
// </tr>
|
|
// </thead>
|
|
// <tbody>
|
|
// {(isSubMenu ? subMenuItems : menuItems).slice(0, recordsPerPage).map((menuItem, index) => (
|
|
// <tr key={index}>
|
|
// {Object.keys(visibleColumns).map(key => visibleColumns[key] && (
|
|
// <td key={key}>{menuItem[key]}</td>
|
|
// ))}
|
|
// <td>
|
|
// <Button onClick={() => openAddEditPopup(menuItem)} className="btn btn-sm btn-success me-2">
|
|
// <FontAwesomeIcon icon={faEdit} />
|
|
// </Button>
|
|
// <Button onClick={() => handleDelete(menuItem.menuItemId)} className="btn btn-sm btn-danger">
|
|
// <FontAwesomeIcon icon={faTrashAlt} />
|
|
// </Button>
|
|
// </td>
|
|
// {!isSubMenu && (
|
|
// <td>
|
|
// <Button onClick={() => handleSubMenuClick(menuItem.menuItemId)} className="btn btn-sm btn-success">
|
|
// <FontAwesomeIcon icon={faBars} /> {/* Three-lines icon */}
|
|
// </Button>
|
|
// </td>
|
|
// )}
|
|
// </tr>
|
|
// ))}
|
|
// {(isSubMenu ? subMenuItems : menuItems).length === 0 && (
|
|
// <tr>
|
|
// <td colSpan={Object.keys(visibleColumns).filter(key => visibleColumns[key]).length + (isSubMenu ? 1 : 2)} className="text-center">
|
|
// No menu items found. Please add new items.
|
|
// </td>
|
|
// </tr>
|
|
// )}
|
|
// </tbody>
|
|
// </Table>
|
|
// </div>
|
|
// <div className="d-flex justify-content-between">
|
|
// <Dropdown className="mt-2">
|
|
// <Dropdown.Toggle variant="btn btn-success btn-sm" id="dropdown-manage-columns">
|
|
// Manage Columns
|
|
// </Dropdown.Toggle>
|
|
// <Dropdown.Menu>
|
|
// {Object.keys(visibleColumns).map(column => (
|
|
// <Dropdown.Item key={column} onClick={() => toggleColumn(column)}>
|
|
// <Form.Check
|
|
// type="checkbox"
|
|
// label={column.charAt(0).toUpperCase() + column.slice(1).toLowerCase()}
|
|
// checked={visibleColumns[column]}
|
|
// readOnly
|
|
// />
|
|
// </Dropdown.Item>
|
|
// ))}
|
|
// </Dropdown.Menu>
|
|
// </Dropdown>
|
|
|
|
// <Dropdown className="mt-2">
|
|
// <Dropdown.Toggle variant="btn btn-success btn-sm" id="dropdown-records-per-page">
|
|
// Records Per Page
|
|
// </Dropdown.Toggle>
|
|
// <Dropdown.Menu>
|
|
// {[5, 10, 20, 50].map(number => (
|
|
// <Dropdown.Item key={number} onClick={() => handleRecordsPerPageChange(number)}>
|
|
// {number}
|
|
// </Dropdown.Item>
|
|
// ))}
|
|
// </Dropdown.Menu>
|
|
// </Dropdown>
|
|
// </div>
|
|
|
|
// {showAddEditPopup && (
|
|
// <Modal show={showAddEditPopup} onHide={() => setShowAddEditPopup(false)}>
|
|
// <Modal.Header closeButton>
|
|
// <Modal.Title>{isEditing ? 'Edit Menu Item' : 'Add New Menu Item'}</Modal.Title>
|
|
// </Modal.Header>
|
|
// <Modal.Body>
|
|
// <Form onSubmit={handleSubmit}>
|
|
// <Form.Group controlId="menuItemDesc">
|
|
// <Form.Label>Title</Form.Label>
|
|
// <Form.Control type="text" name="menuItemDesc" value={currentMenuItem.menuItemDesc || ''} onChange={handleInputChange} required />
|
|
// </Form.Group>
|
|
// <Form.Group controlId="main_menu_action_name">
|
|
// <Form.Label>Link</Form.Label>
|
|
// <Form.Control type="text" name="main_menu_action_name" value={currentMenuItem.main_menu_action_name || ''} onChange={handleInputChange} required />
|
|
// </Form.Group>
|
|
// <Form.Group controlId="status">
|
|
// <Form.Label>Status</Form.Label>
|
|
// <Form.Control as="select" name="status" value={currentMenuItem.status || ''} onChange={handleInputChange} required>
|
|
// <option value="">Select Status</option>
|
|
// <option value="Enable">Enable</option>
|
|
// <option value="Disable">Disable</option>
|
|
// </Form.Control>
|
|
// </Form.Group>
|
|
// <Modal.Footer>
|
|
// <Button variant="secondary" onClick={() => setShowAddEditPopup(false)}>Close</Button>
|
|
// <Button type="submit" variant="secondary">{isEditing ? 'Update Item' : 'Add Item'}</Button>
|
|
// </Modal.Footer>
|
|
// </Form>
|
|
// </Modal.Body>
|
|
// </Modal>
|
|
// )}
|
|
// </div>
|
|
// );
|
|
// }
|
|
|
|
// export default MenuMaintenance;
|
|
|
|
import React, { useState, useEffect } from "react";
|
|
import {
|
|
Button,
|
|
Dropdown,
|
|
Modal,
|
|
Form,
|
|
Row,
|
|
Col,
|
|
InputGroup,
|
|
FormControl,
|
|
OverlayTrigger,
|
|
Tooltip,
|
|
} from "react-bootstrap";
|
|
import { Table, Pagination, PaginationItem, PaginationLink } from "reactstrap";
|
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
import {
|
|
faEdit,
|
|
faTrashAlt,
|
|
faPlus,
|
|
faBars,
|
|
faArrowLeft,
|
|
faTimes,
|
|
faDownload,
|
|
faUpload,
|
|
faFileExcel,
|
|
} from "@fortawesome/free-solid-svg-icons";
|
|
import "bootstrap/dist/css/bootstrap.min.css";
|
|
import "../Dashboard/CSS/CSS/MenuMaitenance.css";
|
|
import { FaSearch, FaTimes } from "react-icons/fa";
|
|
import { BsJournals } from "react-icons/bs";
|
|
import { toast } from "react-toastify";
|
|
import Spinner from "../../UIComponants/Spinner";
|
|
import { useNavigate } from "react-router-dom";
|
|
import * as XLSX from "xlsx";
|
|
import {
|
|
fetchMenuItems,
|
|
addMenuItem,
|
|
updateMenuItem,
|
|
deleteMenuItem,
|
|
getSubmenuItems,
|
|
addSubmenuItem,
|
|
} from "../../APIServices/MenuMaintenanceAPI";
|
|
|
|
|
|
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,
|
|
});
|
|
const [isEditing, setIsEditing] = useState(false);
|
|
const [recordsPerPage, setRecordsPerPage] = useState(10);
|
|
const [selectedMainMenuId, setSelectedMainMenuId] = useState("");
|
|
const [visibleColumns, setVisibleColumns] = useState({
|
|
menuItemDesc: true,
|
|
menu_id: true,
|
|
itemSeq: true,
|
|
moduleName: true,
|
|
main_menu_action_name: true,
|
|
main_menu_icon_name: true,
|
|
status: true,
|
|
});
|
|
const [isSubMenu, setIsSubMenu] = useState(false);
|
|
const [parentMenuItemId, setParentMenuItemId] = useState(null);
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
const [searchQuery, setSearchQuery] = useState("");
|
|
const [newItemData, setNewItemData] = useState({
|
|
menuItemDesc: "",
|
|
menu_id: "",
|
|
itemSeq: "",
|
|
moduleName: "",
|
|
main_menu_action_name: "",
|
|
main_menu_icon_name: "",
|
|
status: true,
|
|
});
|
|
const [loading, setLoading] = useState(true);
|
|
const [showModal, setShowModal] = useState(false);
|
|
const [error, setError] = useState(null);
|
|
const navigate = useNavigate();
|
|
|
|
useEffect(() => {
|
|
// Simulate loading data
|
|
setTimeout(() => {
|
|
setLoading(false);
|
|
}, 3000); // Simulated 3 seconds loading
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const fetchData = async () => {
|
|
try {
|
|
console.log("Fetching Menu Items...");
|
|
const data = await fetchMenuItems(); // Fetch data using the imported function
|
|
setMenuItems(data);
|
|
console.log("Fetched Menu Items:", data);
|
|
toast.success("Menu items fetched successfully!");
|
|
} catch (error) {
|
|
console.error("Fetching error:", error);
|
|
setError(error.message); // Set error message to display in the UI
|
|
toast.error("Error fetching menu items.");
|
|
}
|
|
};
|
|
|
|
fetchData();
|
|
}, []);
|
|
|
|
const toggleColumn = (column) => {
|
|
setVisibleColumns((prev) => ({
|
|
...prev,
|
|
[column]: !prev[column],
|
|
}));
|
|
};
|
|
|
|
const openAddEditPopup = (menuItem = {}) => {
|
|
setIsEditing(!!menuItem.menuItemId);
|
|
setCurrentMenuItem(menuItem);
|
|
setParentMenuItemId(isSubMenu ? menuItem.menuItemId : null);
|
|
setShowAddEditPopup(true);
|
|
};
|
|
|
|
const handleOpenModal = () => setShowModal(true);
|
|
const handleCloseModal = () => setShowModal(false);
|
|
const handleFileChange = (event) => {
|
|
const file = event.target.files[0];
|
|
if (file) {
|
|
console.log("Selected file:", file.name); // For debugging or processing
|
|
}
|
|
};
|
|
|
|
const exportToExcel = () => {
|
|
const worksheet = XLSX.utils.json_to_sheet([]);
|
|
const workbook = XLSX.utils.book_new();
|
|
XLSX.utils.book_append_sheet(workbook, worksheet, "UserDetails");
|
|
XLSX.writeFile(workbook, "MenuMaintenance.xlsx");
|
|
};
|
|
|
|
// const handleInputChange = (event) => {
|
|
// const { name, value } = event.target;
|
|
|
|
// // Process status as a boolean
|
|
// const processedValue = name === "status" ? value === "true" : value;
|
|
|
|
// // Update state accordingly
|
|
// setCurrentMenuItem((prev) => ({ ...prev, [name]: processedValue }));
|
|
// };
|
|
|
|
const handleInputChange = (event) => {
|
|
const { name, value } = event.target;
|
|
|
|
// Convert status to boolean
|
|
const processedValue = name === "status" ? value === "true" : value;
|
|
|
|
setCurrentMenuItem((prev) => ({ ...prev, [name]: processedValue }));
|
|
};
|
|
|
|
const handleSearch = (query) => {
|
|
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
|
|
};
|
|
|
|
// 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);
|
|
|
|
// 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
|
|
}
|
|
};
|
|
|
|
const handleDelete = async (menuItemId) => {
|
|
if (isSubMenu) {
|
|
setSubMenuItems(
|
|
subMenuItems.filter((item) => item.menuItemId !== menuItemId)
|
|
);
|
|
} else {
|
|
await deleteMenuItem(menuItemId);
|
|
setMenuItems(menuItems.filter((item) => item.menuItemId !== menuItemId));
|
|
}
|
|
toast.success("Menu item deleted successfully!");
|
|
};
|
|
|
|
const handleRecordsPerPageChange = (number) => {
|
|
setRecordsPerPage(number);
|
|
};
|
|
|
|
const handleSubMenuClick = (menuItemId) => {
|
|
// Pehle navigate karke page open karein
|
|
navigate(`/admin/sub-menu-maintenance/:menuItemId`);
|
|
|
|
// Phir API logic handle karein
|
|
fetchSubMenuItems(menuItemId);
|
|
};
|
|
|
|
const fetchSubMenuItems = async (menuItemId) => {
|
|
try {
|
|
// Call the API function to fetch submenu items
|
|
const data = await getSubmenuItems(menuItemId);
|
|
|
|
console.log("Fetched Sub-Menu Items:", data);
|
|
|
|
// Update the submenu state with the fetched data
|
|
setSubMenuItems(data);
|
|
|
|
// Optional: Update additional state if required
|
|
setIsSubMenu(true);
|
|
setParentMenuItemId(menuItemId);
|
|
toast.success("Sub-menu items fetched successfully!");
|
|
} catch (error) {
|
|
console.error("Error fetching sub-menu items:", error);
|
|
toast.error("Failed to fetch sub-menu items.");
|
|
}
|
|
};
|
|
|
|
const handleMainMenuClick = (menuId) => {
|
|
console.log("Selected Menu ID:", menuId);
|
|
// Aap yaha routing ya state update kar sakte hain
|
|
};
|
|
|
|
const handleBackToMainMenu = () => {
|
|
setIsSubMenu(false);
|
|
setSubMenuItems([]);
|
|
setParentMenuItemId(null);
|
|
};
|
|
|
|
const totalPages = Math.ceil(menuItems.length / recordsPerPage);
|
|
const handlePageChange = (pageNumber) => {
|
|
setCurrentPage(pageNumber);
|
|
};
|
|
|
|
const handleClose = () => {
|
|
setShowAddEditPopup(false); // Close the modal by setting the state to false
|
|
};
|
|
|
|
const slicedMenus = (isSubMenu ? subMenuItems : menuItems)
|
|
.filter(
|
|
(menuItem) =>
|
|
menuItem.menuItemDesc &&
|
|
menuItem.menuItemDesc.toLowerCase().includes(searchQuery.toLowerCase())
|
|
)
|
|
.slice((currentPage - 1) * recordsPerPage, currentPage * recordsPerPage);
|
|
|
|
console.log("sliced menu", slicedMenus); // Verify the data in slicedMenus
|
|
|
|
return (
|
|
<div style={{ marginTop: "-20px" }}>
|
|
{loading ? (
|
|
<Spinner />
|
|
) : (
|
|
<div className="container-fluid mt-5">
|
|
{/* Header and Add Button */}
|
|
|
|
<div className="d-flex justify-content-between align-items-center mb-4">
|
|
<h1 className="title_main">Menu Maintenance</h1>
|
|
{/* <span className="badge bg-primary ms-3">Main Menu</span> */}
|
|
</div>
|
|
|
|
<Row className="align-items-center my-3">
|
|
{/* Left: Search Bar */}
|
|
<Col
|
|
xs={12}
|
|
md={8}
|
|
lg={6}
|
|
className="d-flex justify-content-center my-3"
|
|
>
|
|
<InputGroup
|
|
className="search-bar"
|
|
style={{
|
|
borderRadius: "10px",
|
|
overflow: "hidden",
|
|
boxShadow: "0px 4px 12px rgba(0, 0, 0, 0.1)",
|
|
width: "100%",
|
|
maxWidth: "528px", // Set max-width to limit overall width
|
|
paddingRight: "-15px", // Increase padding on the right side
|
|
}}
|
|
>
|
|
<InputGroup.Text
|
|
style={{
|
|
backgroundColor: "#0E6591",
|
|
color: "#fff",
|
|
padding: "10px 15px",
|
|
}}
|
|
>
|
|
<FaSearch />
|
|
</InputGroup.Text>
|
|
<FormControl
|
|
placeholder="Search"
|
|
value={searchQuery}
|
|
onChange={(e) => handleSearch(e.target.value)}
|
|
style={{
|
|
padding: "10px",
|
|
border: "none",
|
|
paddingRight: "5px", // More space on the right side of input field
|
|
}}
|
|
/>
|
|
</InputGroup>
|
|
</Col>
|
|
|
|
{/*Add Icons */}
|
|
<Col xs={12} md={4} lg={6} className="d-flex justify-content-end">
|
|
<>
|
|
{/* Add Icon */}
|
|
{isSubMenu && (
|
|
<FontAwesomeIcon
|
|
icon={faArrowLeft}
|
|
onClick={handleBackToMainMenu}
|
|
className="me-2"
|
|
style={{
|
|
cursor: "pointer",
|
|
fontSize: "1.5rem",
|
|
color: "#747264",
|
|
marginRight: "20px",
|
|
}} // Adjust size and color as needed
|
|
/>
|
|
)}
|
|
|
|
<OverlayTrigger
|
|
placement="bottom"
|
|
overlay={<Tooltip>Add Menu</Tooltip>}
|
|
>
|
|
<FontAwesomeIcon
|
|
icon={faPlus}
|
|
onClick={() => openAddEditPopup(true)}
|
|
style={{
|
|
cursor: "pointer",
|
|
fontSize: "1.5rem",
|
|
color: "#747264",
|
|
marginRight: "20px",
|
|
}}
|
|
/>
|
|
</OverlayTrigger>
|
|
|
|
<OverlayTrigger
|
|
placement="bottom"
|
|
overlay={<Tooltip>Download template</Tooltip>}
|
|
>
|
|
<FontAwesomeIcon
|
|
icon={faDownload}
|
|
style={{
|
|
cursor: "pointer",
|
|
fontSize: "1.5rem",
|
|
color: "#747264",
|
|
marginRight: "20px",
|
|
}}
|
|
/>
|
|
</OverlayTrigger>
|
|
|
|
<OverlayTrigger
|
|
placement="bottom"
|
|
overlay={<Tooltip>Import</Tooltip>}
|
|
>
|
|
<FontAwesomeIcon
|
|
icon={faUpload}
|
|
onClick={() => handleOpenModal(true)}
|
|
style={{
|
|
cursor: "pointer",
|
|
fontSize: "1.5rem",
|
|
color: "#747264",
|
|
marginRight: "20px",
|
|
}}
|
|
/>
|
|
</OverlayTrigger>
|
|
|
|
<OverlayTrigger
|
|
placement="bottom"
|
|
overlay={<Tooltip>XLSX</Tooltip>}
|
|
>
|
|
<FontAwesomeIcon
|
|
icon={faFileExcel}
|
|
onClick={() => exportToExcel(true)}
|
|
style={{
|
|
cursor: "pointer",
|
|
fontSize: "1.5rem",
|
|
color: "#747264",
|
|
marginRight: "20px",
|
|
}}
|
|
/>
|
|
</OverlayTrigger>
|
|
|
|
<OverlayTrigger
|
|
placement="bottom"
|
|
overlay={<Tooltip>Menu Items</Tooltip>}
|
|
>
|
|
<FontAwesomeIcon
|
|
icon={faBars}
|
|
style={{
|
|
cursor: "pointer",
|
|
fontSize: "1.5rem",
|
|
color: "#747264",
|
|
}}
|
|
/>
|
|
</OverlayTrigger>
|
|
</>
|
|
</Col>
|
|
</Row>
|
|
|
|
<Modal show={showModal} onHide={handleCloseModal} centered>
|
|
<Modal.Header closeButton>
|
|
<Modal.Title>Import File</Modal.Title>
|
|
</Modal.Header>
|
|
<Modal.Body>
|
|
<Form>
|
|
<Form.Group controlId="formFile" className="mb-3">
|
|
<Form.Label>Select a file to import:</Form.Label>
|
|
<Form.Control
|
|
type="file"
|
|
accept=".xlsx, .xls, .csv" // Restrict file types
|
|
onChange={handleFileChange} // Handle file selection
|
|
/>
|
|
</Form.Group>
|
|
</Form>
|
|
</Modal.Body>
|
|
<Modal.Footer>
|
|
<Button variant="secondary" onClick={handleCloseModal}>
|
|
Cancel
|
|
</Button>
|
|
<Button variant="primary" onClick={handleCloseModal}>
|
|
Upload
|
|
</Button>
|
|
</Modal.Footer>
|
|
</Modal>
|
|
|
|
{/* Table */}
|
|
<div className="table-responsive">
|
|
<Table
|
|
striped
|
|
responsive
|
|
hover
|
|
align="middle"
|
|
className="table-flush shadow-sm"
|
|
>
|
|
<thead className="custom_header">
|
|
<tr>
|
|
<th>No</th> {/* Add the No column */}
|
|
{Object.entries(visibleColumns).map(
|
|
([key, visible]) =>
|
|
visible && (
|
|
<th key={key}>
|
|
{key.charAt(0).toUpperCase() + key.slice(1)}
|
|
</th>
|
|
)
|
|
)}
|
|
<th>Actions</th>
|
|
{!isSubMenu && <th>Sub-Menu</th>}
|
|
</tr>
|
|
</thead>
|
|
|
|
<tbody className="tbody">
|
|
{slicedMenus.length === 0 ? (
|
|
<tr>
|
|
<td
|
|
colSpan={
|
|
1 + // For the "No" column
|
|
Object.keys(visibleColumns).filter(
|
|
(key) => visibleColumns[key]
|
|
).length +
|
|
(isSubMenu ? 1 : 2)
|
|
}
|
|
className="text-center"
|
|
>
|
|
No menu items found. Please add new items.
|
|
</td>
|
|
</tr>
|
|
) : (
|
|
slicedMenus.map((menuItem, index) => (
|
|
<tr
|
|
key={`${menuItem.menuItemId}-${index}`} // Combined key
|
|
onClick={() => handleMainMenuClick(menuItem.menuItemId)} // onClick added
|
|
>
|
|
<td>{index + 1}</td> {/* Incrementing number column */}
|
|
{Object.keys(visibleColumns).map(
|
|
(key) =>
|
|
visibleColumns[key] && (
|
|
<td key={key}>
|
|
{key === "status" ? (
|
|
<span
|
|
className="status"
|
|
style={{
|
|
color: menuItem.status ? "green" : "red",
|
|
backgroundColor: menuItem.status
|
|
? "#d4f7d4"
|
|
: "#f7d4d4",
|
|
padding: "4px 8px",
|
|
borderRadius: "4px",
|
|
display: "inline-block",
|
|
}}
|
|
>
|
|
{menuItem.status ? "Enabled" : "Disabled"}
|
|
</span>
|
|
) : (
|
|
menuItem[key]
|
|
)}
|
|
</td>
|
|
)
|
|
)}
|
|
<td className="text-center">
|
|
<FontAwesomeIcon
|
|
icon={faEdit}
|
|
onClick={() => openAddEditPopup(menuItem)}
|
|
style={{
|
|
cursor: "pointer",
|
|
fontSize: "1rem",
|
|
color: "green",
|
|
marginRight: "15px",
|
|
}}
|
|
/>
|
|
<FontAwesomeIcon
|
|
icon={faTrashAlt}
|
|
onClick={() => handleDelete(menuItem.menuItemId)}
|
|
style={{
|
|
cursor: "pointer",
|
|
fontSize: "1rem",
|
|
color: "#dc3545",
|
|
}}
|
|
/>
|
|
</td>
|
|
{!isSubMenu && (
|
|
<td className="text-center">
|
|
<FontAwesomeIcon
|
|
icon={faBars}
|
|
onClick={() =>
|
|
handleSubMenuClick(menuItem.menuItemId)
|
|
}
|
|
style={{
|
|
cursor: "pointer",
|
|
fontSize: "1rem",
|
|
color: "#0B4C6A",
|
|
}}
|
|
/>
|
|
</td>
|
|
)}
|
|
</tr>
|
|
))
|
|
)}
|
|
</tbody>
|
|
</Table>
|
|
</div>
|
|
|
|
|
|
|
|
{/* Manage Columns & Records Per Page */}
|
|
<Row className="mt-4">
|
|
<Col md={6} className="d-flex justify-content-start">
|
|
<Dropdown>
|
|
<Dropdown.Toggle
|
|
variant="outline-primary"
|
|
className="custom_manage_column_button"
|
|
>
|
|
Manage Columns
|
|
</Dropdown.Toggle>
|
|
<Dropdown.Menu>
|
|
{Object.keys(visibleColumns).map((column) => (
|
|
<Dropdown.Item
|
|
key={column}
|
|
onClick={() => toggleColumn(column)}
|
|
>
|
|
<Form.Check
|
|
type="checkbox"
|
|
label={
|
|
column.charAt(0).toUpperCase() +
|
|
column.slice(1).toLowerCase()
|
|
}
|
|
checked={visibleColumns[column]}
|
|
readOnly
|
|
className="custom-checkbox"
|
|
/>
|
|
</Dropdown.Item>
|
|
))}
|
|
</Dropdown.Menu>
|
|
</Dropdown>
|
|
</Col>
|
|
|
|
<Col md={6} className="d-flex justify-content-end">
|
|
<Dropdown>
|
|
<Dropdown.Toggle
|
|
variant="outline-primary"
|
|
className="custom_manage_column_button px-4 py-2 border-2 rounded-3 shadow-sm"
|
|
id="dropdown-custom-components"
|
|
>
|
|
<BsJournals />
|
|
</Dropdown.Toggle>
|
|
<Dropdown.Menu
|
|
className="border-0 rounded-3 shadow-lg"
|
|
align="end"
|
|
>
|
|
{[1, 5, 10, 20, 50].map((number) => (
|
|
<Dropdown.Item
|
|
key={number}
|
|
onClick={() => handleRecordsPerPageChange(number)}
|
|
className="text-dark d-flex justify-content-between align-items-center"
|
|
>
|
|
<span>{number}</span>
|
|
<i
|
|
className="fa fa-check-circle"
|
|
style={{
|
|
display:
|
|
recordsPerPage === number ? "inline" : "none",
|
|
}}
|
|
/>
|
|
</Dropdown.Item>
|
|
))}
|
|
</Dropdown.Menu>
|
|
</Dropdown>
|
|
</Col>
|
|
</Row>
|
|
|
|
<Pagination className="pagination">
|
|
<PaginationItem disabled={currentPage === 1}>
|
|
<PaginationLink
|
|
previous
|
|
onClick={() => handlePageChange(currentPage - 1)}
|
|
/>
|
|
</PaginationItem>
|
|
{[...Array(totalPages)].map((_, index) => (
|
|
<PaginationItem key={index} active={index + 1 === currentPage}>
|
|
<PaginationLink
|
|
onClick={() => handlePageChange(index + 1)}
|
|
style={{ color: "#0b6592" }}
|
|
>
|
|
{index + 1}
|
|
</PaginationLink>
|
|
</PaginationItem>
|
|
))}
|
|
<PaginationItem disabled={currentPage === totalPages}>
|
|
<PaginationLink
|
|
next
|
|
onClick={() => handlePageChange(currentPage + 1)}
|
|
/>
|
|
</PaginationItem>
|
|
</Pagination>
|
|
|
|
{/* Add/Edit Modal */}
|
|
{showAddEditPopup && (
|
|
<Modal
|
|
show={showAddEditPopup}
|
|
onHide={() => setShowAddEditPopup(false)}
|
|
centered
|
|
>
|
|
<Modal.Header>
|
|
<Modal.Title>
|
|
{isEditing ? "Edit Menu Item" : "Add New Menu Item"}
|
|
</Modal.Title>
|
|
<FontAwesomeIcon
|
|
icon={faTimes}
|
|
size="lg"
|
|
onClick={handleClose}
|
|
style={{
|
|
position: "absolute",
|
|
top: "25px",
|
|
right: "25px",
|
|
cursor: "pointer",
|
|
}}
|
|
/>
|
|
</Modal.Header>
|
|
<Modal.Body>
|
|
<Form onSubmit={handleSubmit}>
|
|
<Form.Group controlId="menuId" className="mb-3">
|
|
<Form.Label>menuId</Form.Label>
|
|
<Form.Control
|
|
type="number"
|
|
name="menu_id" // Updated to match the state
|
|
value={currentMenuItem.menu_id || ""}
|
|
onChange={handleInputChange}
|
|
required
|
|
className="custom-hover-border"
|
|
/>
|
|
</Form.Group>
|
|
<Form.Group controlId="menuItemDesc" className="mb-3">
|
|
<Form.Label>Title</Form.Label>
|
|
<Form.Control
|
|
type="text"
|
|
name="menuItemDesc"
|
|
value={currentMenuItem.menuItemDesc || ""}
|
|
onChange={handleInputChange}
|
|
required
|
|
className="custom-hover-border"
|
|
/>
|
|
</Form.Group>
|
|
<Form.Group
|
|
controlId="main_menu_action_name"
|
|
className="mb-3"
|
|
>
|
|
<Form.Label>Link</Form.Label>
|
|
<Form.Control
|
|
type="text"
|
|
name="main_menu_action_name"
|
|
value={currentMenuItem.main_menu_action_name || ""}
|
|
onChange={handleInputChange}
|
|
required
|
|
className="custom-hover-border"
|
|
/>
|
|
</Form.Group>
|
|
<Form.Group controlId="status" className="mb-3">
|
|
<Form.Label>Status</Form.Label>
|
|
<Form.Select
|
|
name="status"
|
|
value={currentMenuItem.status ? "true" : "false"}
|
|
onChange={handleInputChange}
|
|
required
|
|
className="custom-checkbox:checked"
|
|
>
|
|
<option value="">Select Status</option>
|
|
<option value="true">Enable</option>
|
|
<option value="false">Disable</option>
|
|
</Form.Select>
|
|
</Form.Group>
|
|
<Modal.Footer>
|
|
<Button
|
|
variant="primary"
|
|
onClick={() => setShowAddEditPopup(false)}
|
|
className="custom_button"
|
|
>
|
|
Close
|
|
</Button>
|
|
<Button
|
|
type="submit"
|
|
variant="primary"
|
|
className="custom_button"
|
|
>
|
|
{isEditing ? "Update Item" : "Add Item"}
|
|
</Button>
|
|
</Modal.Footer>
|
|
</Form>
|
|
</Modal.Body>
|
|
</Modal>
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
export default MenuMaintenance;
|