diff --git a/public/assets/css/style.css b/public/assets/css/style.css
index d59ed0c..5be8e39 100644
--- a/public/assets/css/style.css
+++ b/public/assets/css/style.css
@@ -13179,12 +13179,12 @@ select option {
left: 50%;
bottom: -1px;
transform: translateX(-50%);
- background-color: var(--primary-600);
+ background-color: var(--theme-color);
transition: 0.2s linear;
}
.bordered-tab .nav-link.active {
- color: var(--primary-600);
+ color: var(--theme-color);
}
.bordered-tab .nav-link.active::before {
@@ -13194,7 +13194,7 @@ select option {
/* Bordered Tab Css End */
/* Pill Tab Css Start */
.pill-tab .nav-link.active {
- background-color: var(--primary-600);
+ background-color: var(--theme-color);
}
.pill-tab.style-three {
diff --git a/src/app/admin/(pos-system)/pos/sides-category/page.jsx b/src/app/admin/(pos-system)/pos/sides-category/page.jsx
new file mode 100644
index 0000000..ecf656f
--- /dev/null
+++ b/src/app/admin/(pos-system)/pos/sides-category/page.jsx
@@ -0,0 +1,67 @@
+"use client"
+import MasterLayout from "@/masterLayout/MasterLayout";
+import { useEffect, useState } from "react";
+import client from "@auth";
+import PageLoader from "@/components/common-component/PageLoader";
+import Breadcrumb from "@/components/Breadcrumb";
+import SidesCategoryComponent from "@/components/admin/SidesCategoryComponent";
+
+// export const metadata = {
+// title: "WowDash NEXT JS - Admin Dashboard Multipurpose Bootstrap 5 Template",
+// description:
+// "Wowdash NEXT JS is a developer-friendly, ready-to-use admin template designed for building attractive, scalable, and high-performing web applications.",
+// };
+
+const SidesCategoryPage = () => {
+
+ const [sidesCategoryData, setSidesCategoryData] = useState(null);
+ const [error, setError] = useState(null);
+ const [loading, setLoading] = useState(true);
+ const [restaruntBranch, setRestaruntBranch] = useState("")
+
+ useEffect(() => {
+ const restarunt = localStorage.getItem("restaurantbranch")
+ setRestaruntBranch(restarunt)
+ }, [])
+
+
+ useEffect(() => {
+ if (restaruntBranch && restaruntBranch !== "")
+ getSidesCategory();
+ }, [restaruntBranch]);
+
+
+
+ const getSidesCategory = async () => {
+ try {
+ setLoading(true);
+ // const res = await client?.get(`/Dine360 Floor?fields=[\"*\"]&limit_page_length=100`);
+ const res = await client?.get(`/Dine360%20Food%20Sides%20Category?fields=[%22*%22]&limit_page_length=100&filters=[["restaurantbranch","=","${restaruntBranch}"]]`);
+ setSidesCategoryData(res?.data?.data);
+ } catch (error) {
+ console.error("Error fetching floor data:", error);
+ setError(error?.message || "Failed to fetch floor data");
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ console.log("")
+ return (
+ <>
+
+
+
+
+ {loading ? (
+
+ ) : (
+
+ )
+ }
+
+ >
+ );
+};
+
+export default SidesCategoryPage;
diff --git a/src/app/admin/(pos-system)/pos/sides/page.jsx b/src/app/admin/(pos-system)/pos/sides/page.jsx
new file mode 100644
index 0000000..16e0653
--- /dev/null
+++ b/src/app/admin/(pos-system)/pos/sides/page.jsx
@@ -0,0 +1,416 @@
+"use client";
+import React, { Suspense, useEffect, useState } from "react";
+import { useRouter, useSearchParams } from "next/navigation";
+import Link from "next/link";
+import MasterLayout from "@/masterLayout/MasterLayout";
+import client from "@auth";
+import { gradientClasses } from "@utils/constant.utils";
+import PageLoader from "@/components/common-component/PageLoader";
+import PageNoData from "@/components/common-component/PageNoData";
+import Breadcrumb from "@/components/Breadcrumb";
+import { Icon } from "@iconify/react";
+
+const SidesPageInner = () => {
+ const router = useRouter();
+ const searchParams = useSearchParams();
+ const sidesCategoryName = decodeURIComponent(searchParams.get("sidescategoryname"));
+
+ const [showModal, setShowModal] = useState(false);
+ const [editMode, setEditMode] = useState(false);
+ const [editingRoomId, setEditingRoomId] = useState(null);
+ const [roomData, setRoomData] = useState(null);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
+ const [formData, setFormData] = useState({
+ sidename: "",
+ description: "",
+ price: "",
+ item_image: null,
+ });
+ const [errors, setErrors] = useState({});
+ const [deleteConfirm, setDeleteConfirm] = useState({ show: false, id: null });
+ const [restaruntBranch, setRestaruntBranch] = useState("");
+
+ useEffect(() => {
+ const restarunt = localStorage.getItem("restaurantbranch");
+ setRestaruntBranch(restarunt);
+ }, []);
+
+ useEffect(() => {
+ const isLogin = JSON.parse(localStorage.getItem("isLogin"));
+ if (!isLogin) {
+ router.push(`/admin?restaurantbranch=${restaruntBranch}`);
+ }
+ }, [router]);
+
+ useEffect(() => {
+ if (sidesCategoryName) {
+ getSideData();
+ }
+ }, [sidesCategoryName]);
+
+ const getSideData = async () => {
+ try {
+ setLoading(true);
+ setError(null);
+ const roomRes = await client.get(
+ `/Dine360%20Food%20Sides?fields=[%22*%22]&limit_page_length=100&filters=[["sidecategoryid","=","${sidesCategoryName}"]]`
+ );
+ setRoomData(roomRes?.data?.data || []);
+ } catch (error) {
+ console.error("Error fetching data:", error);
+ setError(error?.message || "Failed to fetch side data");
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const handleChange = (e) => {
+ const { name, value } = e.target;
+ setFormData((prev) => ({ ...prev, [name]: value }));
+ };
+
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+ const newErrors = {};
+
+ if (!formData.sidename.trim()) newErrors.sidename = "Side Name is required";
+ if (!formData.description.trim()) newErrors.description = "Description is required";
+ if (!formData.price) newErrors.price = "Price is required";
+ if (!formData.item_image) newErrors.item_image = "Item image is required";
+
+ setErrors(newErrors);
+ if (Object.keys(newErrors).length > 0) return;
+
+ const body = {
+ sidename: formData.sidename,
+ description: formData.description,
+ price: parseFloat(formData.price),
+ item_image: formData.item_image,
+ sidecategoryid: sidesCategoryName,
+ restaurantbranch: restaruntBranch,
+ };
+
+ try {
+ if (editMode) {
+ await client.put(`/Dine360%20Food%20Sides/${editingRoomId}`, body);
+ } else {
+ await client.post(`/Dine360%20Food%20Sides`, body);
+ }
+ getSideData();
+ resetForm();
+ } catch (error) {
+ console.error("❌ Submission error:", error);
+
+ // Backend MySQL error handling
+ const backendError = error?.response?.data?.exception || "";
+
+ if (backendError.includes("Data too long for column 'item_image'")) {
+ setErrors((prev) => ({
+ ...prev,
+ item_image: "Data too long for column 'item_image'",
+ }));
+ } else if (error?.response?.status === 500) {
+ alert("Server error occurred. Please try again later or contact support.");
+ } else {
+ alert("Submission failed. Please check your input and try again.");
+ }
+ }
+
+ };
+
+
+ const handleEdit = (room) => {
+ setFormData({
+ sidename: room.sidename || "",
+ description: room.description || "",
+ price: room.price || "",
+ item_image: room.item_image || null,
+ });
+ setEditingRoomId(room.name);
+ setEditMode(true);
+ setShowModal(true);
+ };
+
+ const handleDelete = async () => {
+ try {
+ await client.delete(`/Dine360%20Food%20Sides/${deleteConfirm?.id}`);
+ setDeleteConfirm({ show: false, id: null });
+ getSideData();
+ } catch (error) {
+ alert("Error deleting. It might be linked to other data.");
+ }
+ };
+
+ const resetForm = () => {
+ setFormData({
+ sidename: "",
+ description: "",
+ price: "",
+ item_image: null,
+ });
+ setErrors({});
+ setEditMode(false);
+ setEditingRoomId(null);
+ setShowModal(false);
+ };
+
+ return (
+
+
+
+
+
Sides
+
+
+
+
+ {loading ? (
+
+ ) : roomData?.length === 0 ? (
+
+ ) : (
+ roomData?.map((room, index) => {
+ const gradientClass = gradientClasses[index % gradientClasses.length];
+ return (
+
+
+
+
+
+
+ -
+ {
+ e.preventDefault();
+ handleEdit(room);
+ }}
+ >
+
+ Edit
+
+
+ -
+ {
+ e.preventDefault();
+ setDeleteConfirm({ show: true, id: room.name });
+ }}
+ >
+
+ Delete
+
+
+
+
+
+
+
+
{room?.sidename}
+
{room?.description}
+
+
+
+ );
+ })
+ )}
+
+
+
+
+ {/* Modal */}
+ {showModal && (
+
+
+
+
+
{editMode ? "Edit Side" : "Create Side"}
+
+
+
+
+
+
+ )}
+
+ {/* Delete Confirmation */}
+ {deleteConfirm.show && (
+
+
+
+
+
+
Confirm Delete
+
+
+
Are you sure you want to delete this item?
+
+
+
+
+
+
+
+
+ )}
+
+ );
+};
+
+const SidesPage = () => {
+ return (
+
+
+ }>
+
+
+
+ );
+};
+
+export default SidesPage;
diff --git a/src/app/waiter/menu-items/page.jsx b/src/app/waiter/menu-items/page.jsx
index 63528a1..80038dd 100644
--- a/src/app/waiter/menu-items/page.jsx
+++ b/src/app/waiter/menu-items/page.jsx
@@ -33,73 +33,155 @@ const MenuItemsCategory = () => {
const [orderStatus, setOrderStatus] = useState('pending');
const HST_TAX_RATE = 0.13; // 13% HST tax rate
+ const [catMenu, setCatMenu] = useState(null);
+ const [catMenuActive, setCatMenuActive] = useState(null)
+ const [selectedItem, setSelectedItem] = useState(null);
+ const [showItemModal, setShowItemModal] = useState(false);
+ const [selectedExtras, setSelectedExtras] = useState([]);
+ const [selectedDrink, setSelectedDrink] = useState(null);
+ const [orderItems, setOrderItems] = useState([])
useEffect(() => {
+ getMenuItem();
+ }, []);
- if (menuName) {
- getMenuItems();
+ const getMenuItem = async () => {
+ try {
+ const res = await client?.get(`/Dine360 Menu?fields=["*"]&limit_page_length=100`);
+ setCatMenu(res?.data?.data || []);
+ setCatMenuActive(res?.data?.data[0]?.name || [])
+ } catch (error) {
+ console.error("Error fetching menu list:", error);
}
- }, [menuName]);
+ };
useEffect(() => {
- if (menuData) {
- getMenuFoodItems(menuData)
- setActiveCategory(menuData[0]?.name)
+ if (catMenu?.length > 0) {
+ getMenuItems(catMenu[0]?.menuname); // auto-load first menu's categories
}
- }, [menuData])
+ }, [catMenu]);
- const getMenuItems = async () => {
+
+ useEffect(() => {
+ if (menuData?.length > 0) {
+ getMenuFoodItems(menuData[0]);
+ setActiveCategory(menuData[0]?.name);
+ }
+ }, [menuData]);
+
+ const getMenuItems = async (menuname) => {
try {
setLoading(true);
setError(null);
- // Fetch floor data using name
- const menuRes = await client.get(`/Dine360%20Menu%20Category%20Link?fields=[\"*\"]&limit_page_length=100&filters=[["menu","=","${menuName}"]]`);
- console.log("menuRes", menuRes?.data?.data);
+ const menuRes = await client.get(
+ `/Dine360%20Menu%20Category%20Link?fields=["*"]&limit_page_length=100&filters=[["menu","=","${menuname}"]]`
+ );
- // Get menu categories based on the menucategory from menuRes
- const menuCategories = menuRes?.data?.data || [];
- const menuCategoryPromises = menuCategories.map(async (menuItem) => {
- const menuCategoryRes = await client.get(`/Dine360%20Menu%20Category?fields=[\"*\"]&limit_page_length=100&filters=[["name","=","${menuItem.menucategory}"]]`);
- console.log("menuCategoryRes", menuCategoryRes?.data?.data);
- return menuCategoryRes?.data?.data?.[0] || null;
+ const menuLinks = menuRes?.data?.data || [];
+
+ const menuCategoryPromises = menuLinks.map(async (menuItem) => {
+ const res = await client.get(
+ `/Dine360%20Menu%20Category?fields=["*"]&limit_page_length=100&filters=[["name","=","${menuItem.menucategory}"]]`
+ );
+ return res?.data?.data?.[0] || null;
});
- const menuCategoryResults = await Promise.all(menuCategoryPromises);
- const filteredMenuCategories = menuCategoryResults.filter(category => category !== null);
+ const categories = await Promise.all(menuCategoryPromises);
+ const validCategories = categories.filter(Boolean);
- setMenuData(filteredMenuCategories);
+ setMenuData(validCategories);
} catch (error) {
- console.error("Error fetching data:", error);
- setError(error?.message || "Failed to fetch floor data");
+ console.error("Error fetching menu categories:", error);
+ setError(error?.message || "Failed to fetch menu categories");
} finally {
setLoading(false);
}
};
- const getMenuFoodItems = (async (menuData) => {
- console.log("menuDataaaa", menuData)
+ const getMenuFoodItems = async (category) => {
+ if (!category?.name) return;
try {
- const res = await client.get(`/Dine360%20Menu%20Category/${menuData[0].name}?fields=[\"*\"]&limit_page_length=100`);
- console.log("res", res)
- setMenuItems(res?.data?.data)
+ const res = await client.get(
+ `/Dine360%20Menu%20Category/${category.name}?fields=["*"]&limit_page_length=100`
+ );
+ setMenuItems(res?.data?.data || []);
} catch (error) {
- console.log("error", error)
- }
- })
-
- const handleMenuClick = async (menu) => {
- try {
- const menuItemsRes = await client.get(`/Dine360%20Menu%20Category/${menu.name}?fields=[\"*\"]&limit_page_length=100`);
- console.log("menuItemsRes", menuItemsRes?.data?.data);
- setMenuItems(menuItemsRes?.data?.data);
- setActiveCategory(menu?.name);
- } catch (error) {
- console.error("Error fetching data:", error);
- setError(error?.message || "Failed to fetch floor data");
+ console.error("Error fetching menu items:", error);
}
};
+
+ // Fetch sides linked to a specific food item
+ const getLinkedSides = async (foodItemName) => {
+ try {
+ const res = await client.get(
+ `/Dine360 FoodItem Sides Link?fields=["*"]&filters=[["menuitemname","=","${foodItemName}"]]`
+ );
+ return res.data.data; // Sides linked to this menu item
+ } catch (error) {
+ console.error(`Error fetching linked sides for item: ${foodItemName}`, error);
+ return [];
+ }
+ };
+
+ // Fetch and group all sides by their category
+ const getAllSidesGroupedByCategory = async (foodItemName) => {
+ try {
+ const res = await client.get(`/Dine360 FoodItem Sides Link?fields=["*"]&filters=[["menuitemname","=","${foodItemName}"]]`);
+ console.log("Grouped Sides:", res.data.data);
+
+ const SliderLink = res?.data?.data || [];
+
+ const SidesList = SliderLink.map(async (sideItem) => {
+ const res = await client.get(
+ `/Dine360 Food Sides?fields=["*"]&filters=[["name","=","${sideItem.menucategory}"]]`
+ );
+ return res?.data?.data?.[0] || null;
+ });
+ const categories = await Promise.all(SidesList);
+ const validSides = categories.filter(Boolean);
+ console.log("validSides", validSides)
+
+ } catch (err) {
+ console.error("Error fetching grouped sides:", err);
+ return [];
+ }
+ };
+
+ const handleAddToOrder = () => {
+ const cartItem = cart.find(item => item.name === selectedItem.name);
+
+ if (!cartItem) {
+ alert("Please add the item to cart before adding to order.");
+ return;
+ }
+
+ setOrderItems(cart);
+ setShowItemModal(false);
+ };
+
+ // For user clicking category from catMenu
+ const handleCatMenuClick = async (menuname) => {
+ await getMenuItems(menuname);
+ setCatMenuActive(menuname)
+ };
+
+ // For user clicking individual menu category
+ const handleMenuClick = async (menu) => {
+ try {
+ const res = await client.get(
+ `/Dine360%20Menu%20Category/${menu.name}?fields=["*"]&limit_page_length=100`
+ );
+ setMenuItems(res?.data?.data || []);
+ setActiveCategory(menu?.name);
+ } catch (error) {
+ console.error("Error fetching menu data:", error);
+ setError(error?.message || "Failed to fetch menu data");
+ }
+ };
+
+
console.log("menuItems", menuItems);
const addToCart = (item) => {
const existingItem = cart.find(cartItem => cartItem.name === item.name);
@@ -112,24 +194,40 @@ const MenuItemsCategory = () => {
} else {
setCart([...cart, { ...item, quantity: 1 }]);
}
+
};
const removeFromCart = (itemName) => {
- setCart(cart.filter(item => item.name !== itemName));
+ setCart(prev => prev.filter(item => item.name !== itemName));
+ setOrderItems(prev => prev.filter(item => item.name !== itemName));
};
const updateQuantity = (itemName, newQuantity) => {
if (newQuantity < 1) {
- removeFromCart(itemName);
+ removeItem(itemName);
return;
}
- setCart(cart.map(item =>
- item.name === itemName
- ? { ...item, quantity: newQuantity }
- : item
- ));
+
+ // Update cart
+ setCart(prev =>
+ prev.map(item =>
+ item.name === itemName
+ ? { ...item, quantity: newQuantity }
+ : item
+ )
+ );
+
+ // Update orderItems
+ setOrderItems(prev =>
+ prev.map(item =>
+ item.name === itemName
+ ? { ...item, quantity: newQuantity }
+ : item
+ )
+ );
};
+
const calculateSubtotal = () => {
return cart.reduce((total, item) => total + (item.price * item.quantity), 0);
};
@@ -146,7 +244,19 @@ const MenuItemsCategory = () => {
setShowOrderModal(true);
};
- console.log
+ // Toggle extras like checkbox buttons
+ const toggleExtra = (extra) => {
+ setSelectedExtras(prev =>
+ prev.includes(extra)
+ ? prev.filter(item => item !== extra)
+ : [...prev, extra]
+ );
+ };
+
+ // Select one drink at a time
+ const selectDrink = (drink) => {
+ setSelectedDrink(drink === selectedDrink ? null : drink);
+ };
const confirmOrder = async () => {
// Get current time in YYYY-MM-DD HH:mm:ss format (Canada Eastern Time)
@@ -164,7 +274,7 @@ const MenuItemsCategory = () => {
console.log(orderStartTime);
// Prepare formatted order data
- const formattedOrder = cart.map((item) => ({
+ const formattedOrder = orderItems.map((item) => ({
menuitem: item.name,
quantity: item.quantity,
rate: item.price,
@@ -212,44 +322,60 @@ const MenuItemsCategory = () => {
const renderMenuItem = (menu) => {
+ console.log("menu", menu)
const cartItem = cart.find(item => item.name === menu.name);
const isInCart = !!cartItem;
return (
-
-
-

-
{menu.menuitemname}
-
${menu.price.toFixed(2)}
- {isInCart ? (
-
-
-
{cartItem.quantity}
-
+
+
{
+ setSelectedItem(menu);
+ getAllSidesGroupedByCategory(menu?.name)
+ setShowItemModal(true);
+ }}
+ >
+
+

+ {/*
+

+
*/}
+
+
{menu.menuitemname}
+ {menu.parent}
+ ${menu.price.toFixed(2)}
- ) : (
-
- )}
+
+
+ {/* {isInCart ? (
+
+
+ {cartItem.quantity}
+
+
+ ) : (
+
+ )} */}
+
@@ -257,12 +383,18 @@ const MenuItemsCategory = () => {
};
+ const cartItem = cart.find(item => item.name === selectedItem.name);
+ const isInCart = !!cartItem;
+ const quantity = cartItem?.quantity || 1;
+
+ console.log("catMenuActive", catMenuActive)
+ console.log("cartItem?.quantity", cartItem)
return (
-
+
{
loading ? (
@@ -273,12 +405,42 @@ const MenuItemsCategory = () => {
{/* Menu Category - Always col-xxl-2 */}
-
+
+
+
+
+
+ {catMenu.map((menu) => (
+ - handleCatMenuClick(menu?.name)}
+ style={{ cursor: "pointer" }}
+ >
+
+ {menu?.menuname}
+
+ ))}
+
+
+
+
+
+
+ {/* Menu Items - col-xxl-10 if cart is empty, else col-xxl-7 */}
+
+
-
+
{menuData.map((menu) => (
- {
-
-
- {/* Menu Items - col-xxl-10 if cart is empty, else col-xxl-7 */}
-
-
-
-
- {menuItems?.menuitems_child?.map(renderMenuItem)}
-
-
+
+ {menuItems?.menuitems_child?.map(renderMenuItem)}
+
{/* Cart - Show only if cart has items */}
- {cart.length > 0 && (
-
-
-
-
Order Details
- {cart.map((item) => (
-
-
-
-
-

-
-
-
-
-
- {item.menuitemname}
-
-
${item.price.toFixed(2)}
-
-
-
-
+ {/* {cart.length > 0 && ( */}
+
+
+
+
POS Dine-in
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+

+ Contact Number
+
+ Show
+
+
+ -
+
+

+ Customer Info
+
+ Show
+
+
+
+
+
+
+ {orderItems.length === 0 ? (
+
Your cart is empty.
+ ) : (
+ <>
+ {orderItems.map((item) => (
+
+
+
+
+

+
+
+
+
+
+ {item.menuitemname}
+
+
${item.price.toFixed(2)}
-
-
-
{item.quantity}
-
+
+
+
+
+
+
+ {item.quantity}
+
+
-
- ))}
+ ))}
-
-
-
-
+
+
+
+ >
+ )}
- )}
+
+
+ {/* )} */}
)
}
+ {showItemModal && selectedItem && (
+
+ <>
+
setShowItemModal(false)}
+ />
+
+
+
+
+
{selectedItem.menuitemname}
+
+
+
+ {/* Col 1 - Image */}
+
+

+
+
+ {/* Col 2 - Size + Quantity */}
+
+
Choose Size
+
+
+
Quantity
+ {isInCart ? (
+
+
+ {cartItem.quantity}
+
+
+ ) : (
+
+ )}
+
+
+ {/* Col 3 - Extras */}
+ {/* Col 3 - Extras + Order Button + Total */}
+
+
+
Add Extras
+
+
+
+
+
+
Drinks
+
+
+
+
+
+
+
+
Total: $12.99
+
+
+
+
+
+
+
+ {/*
+
+
+
*/}
+
+
+
+ >
+ )}
+
+
{/* Order Confirmation Modal */}
{
showOrderModal && (
diff --git a/src/app/waiter/table-order/page.jsx b/src/app/waiter/table-order/page.jsx
index a1a0f7b..761c05d 100644
--- a/src/app/waiter/table-order/page.jsx
+++ b/src/app/waiter/table-order/page.jsx
@@ -158,7 +158,7 @@ const TableOrderInner = () => {
// Push the route with formatted timestamp
router.push(
- `/waiter/menu-category?restaurantbranch=${restaruntBranch}&table=${encodeURIComponent(selectedTable.name)}&seats=${seatCount}&time=${encodeURIComponent(formattedTime)}`
+ `/waiter/menu-items?restaurantbranch=${restaruntBranch}&table=${encodeURIComponent(selectedTable.name)}&seats=${seatCount}&time=${encodeURIComponent(formattedTime)}`
);
}
};
@@ -525,7 +525,7 @@ const TableOrderInner = () => {
-
Enter Seat Count
+ Enter Seat Count - {selectedTable.tablename}
@@ -552,8 +552,8 @@ const TableOrderInner = () => {
-
-
+
+
diff --git a/src/components/admin/SidesCategoryComponent.jsx b/src/components/admin/SidesCategoryComponent.jsx
new file mode 100644
index 0000000..16126a4
--- /dev/null
+++ b/src/components/admin/SidesCategoryComponent.jsx
@@ -0,0 +1,323 @@
+"use client";
+import Link from "next/link";
+import React, { useEffect, useState } from "react";
+import { gradientClasses } from "../../../utils/constant.utils";
+import client from "../../../Auth";
+import { Icon } from "@iconify/react";
+import PageNoData from "../common-component/PageNoData";
+import { useParams, useRouter } from "next/navigation";
+
+const SidesCategoryComponent = ({ sidesCategoryData, getSidesCategory }) => {
+
+ const router = useRouter()
+ const params = useParams();
+ const [showModal, setShowModal] = useState(false);
+ const [isEditMode, setIsEditMode] = useState(false);
+ const [selectedSidesCategoryId, setSelectedSidesCategoryId] = useState(null);
+ const [formData, setFormData] = useState({
+ sidesCategoryname: "",
+ description: "",
+ });
+ const [errors, setErrors] = useState({});
+ const [deleteConfirm, setDeleteConfirm] = useState({ show: false, id: null });
+ const [restaruntBranch, setRestaruntBranch] = useState("")
+
+ useEffect(() => {
+ const restarunt = localStorage.getItem("restaurantbranch")
+ setRestaruntBranch(restarunt)
+ }, [])
+
+ useEffect(() => {
+ const isLogin = JSON.parse(localStorage.getItem("isLogin"));
+ if (!isLogin) {
+ router.push(`/admin?restaurantbranch=${restaruntBranch}`);
+ }
+ }, [router]);
+
+ const handleChange = (e) => {
+ const { name, value } = e.target;
+ setFormData((prev) => ({ ...prev, [name]: value }));
+ };
+
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+
+ const newErrors = {};
+ Object.entries(formData).forEach(([key, value]) => {
+ if (!value.trim()) newErrors[key] = `${key} is required`;
+ });
+ setErrors(newErrors);
+ if (Object.keys(newErrors).length > 0) return;
+
+ const body = {
+ // ...(isEditMode && { name: selectedFloorId }), // only adds `name` if editing
+ sidecategoryname: formData?.sidesCategoryname,
+ description: formData?.description,
+ restaurantbranch: restaruntBranch
+ };
+ try {
+ if (isEditMode) {
+ await client.put(`/Dine360%20Food%20Sides%20Category/${selectedSidesCategoryId}`, body);
+ } else {
+ await client.post(`/Dine360%20Food%20Sides%20Category`, body);
+ }
+ getSidesCategory();
+ resetForm();
+ } catch (error) {
+ if (
+ error?.response?.data?.exception?.includes("DuplicateEntryError") ||
+ error?.response?.data?.message?.includes("Duplicate entry")
+ ) {
+ alert("SidesCategory with this name already exists. Please use a different name.");
+ } else if (
+ error?.response?.data?.exception?.includes("UniqueValidationError") ||
+ error?.response?.data?.message?.includes("UniqueValidationError entry")
+ ) {
+ alert("SidesCategory with this name already exists. Please use a different name.");
+ } else {
+ alert("An error occurred. Please try again.");
+ }
+ }
+ };
+
+ const resetForm = () => {
+ setFormData({
+ sidesCategoryname: "", description: "",
+ });
+ setShowModal(false);
+ setIsEditMode(false);
+ setSelectedSidesCategoryId(null);
+ setErrors({});
+ };
+
+ const handleEdit = (sidesCategory) => {
+ setIsEditMode(true);
+ setSelectedSidesCategoryId(sidesCategory.name);
+ setFormData({
+ sidesCategoryname: sidesCategory.sidesCategoryname || "",
+ description: sidesCategory.description || "",
+ });
+ setShowModal(true);
+ };
+
+ const handleDelete = async () => {
+ try {
+ await client.delete(`/Dine360%20Food%20Sides%20Category/${deleteConfirm.id}`);
+ setDeleteConfirm({ show: false, id: null });
+ getSidesCategory();
+ } catch (error) {
+ if (
+ error?.response?.data?.exception?.includes("DuplicateEntryError") ||
+ error?.response?.data?.message?.includes("Duplicate entry")
+ ) {
+ alert("SidesCategory with this name already exists. Please use a different name.");
+ } else if (error?.response?.data?.exception?.includes("LinkExistsError") ||
+ error?.response?.data?.message?.includes("LinkExistsError")) {
+ alert(" Cannot delete or cancel because Dine360 SidesCategory three is linked with Dine360 Room ");
+ }
+ }
+ };
+
+ return (
+
+
+
+
+
SidesCategory
+
+
+
+
+ {
+ sidesCategoryData?.lenght === 0 ? (
+
+ ) : (
+ <>
+ {sidesCategoryData.map((sidesCategory, index) => {
+ const gradientClass = gradientClasses[index % gradientClasses.length];
+ return (
+
+
+
+ {/* Top-right action buttons */}
+
+
+
+
+ -
+ {
+ e.preventDefault();
+ handleEdit(sidesCategory);
+ }}
+ >
+ Edit
+
+
+ -
+ {
+ e.preventDefault();
+ setDeleteConfirm({ show: true, id: sidesCategory.name });
+ }}
+ >
+
+ Delete
+
+
+
+
+
+
+
+
+ {/* Centered content */}
+
+
+
{sidesCategory.sidecategoryname}
+
{sidesCategory.description}
+
+
+
+
+ );
+ })}
+ >
+ )
+ }
+
+
+
+
+
+
+ {/* Create/Edit Modal */}
+ {showModal && (
+
+
+
+
+
+ {isEditMode ? "Edit SidesCategory" : "Create SidesCategory"}
+
+
+
+
+
+
+
+
+
+ )}
+
+ {/* Delete Confirmation Modal */}
+ {deleteConfirm.show && (
+
+
+
+
+
+
+
Confirm Delete
+
+
+
Are you sure you want to delete this sidesCategory?
+
+
+
+
+
+
+
+
+ )}
+
+ );
+};
+
+export default SidesCategoryComponent;