From 0bb44da74f4151457638500527b006a00d5ed807 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 6 Feb 2026 15:16:14 +0530 Subject: [PATCH] Offer Page Design --- .../Offer/CodeBase/CodeBaseListList.scss | 249 +- .../Offer/LoyaltyBased/LoyaltiPointList.scss | 4 +- src/Pages/Offer/Offer/OfferFormNew.jsx | 2584 ++++++++++------- src/Pages/Offer/Offer/OfferList.scss | 7 +- 4 files changed, 1633 insertions(+), 1211 deletions(-) diff --git a/src/Pages/Offer/CodeBase/CodeBaseListList.scss b/src/Pages/Offer/CodeBase/CodeBaseListList.scss index 86b82f6..4d819cb 100644 --- a/src/Pages/Offer/CodeBase/CodeBaseListList.scss +++ b/src/Pages/Offer/CodeBase/CodeBaseListList.scss @@ -8,6 +8,12 @@ padding-bottom: 5rem !important; border-radius: 12px; height: 85vh; + .ant-table-thead .ant-table-cell { + background-color: #2c88ee !important; + &:hover { + background-color: #2c88ee !important; + } + } @media (max-width: 768px) { margin: 10px 0 0 0; @@ -60,7 +66,7 @@ font-size: 13px; border-radius: 8px; cursor: pointer; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; @media (max-width: 600px) { padding: 8px 12px; @@ -104,7 +110,7 @@ font-size: 24px; font-weight: 500; color: #000000; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; line-height: 1.2; letter-spacing: -0.5px; } @@ -114,7 +120,7 @@ font-size: 14px; font-weight: 500; color: #6c6c6c; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; line-height: 1.4; letter-spacing: -0.5px; margin-top: 2px; @@ -177,14 +183,14 @@ font-weight: 500; color: #6c6c6c; // Gray text for inactive state font-family: - 'Poppins', + "Poppins", -apple-system, BlinkMacSystemFont, - 'Segoe UI', - 'Roboto', - 'Oxygen', - 'Ubuntu', - 'Cantarell', + "Segoe UI", + "Roboto", + "Oxygen", + "Ubuntu", + "Cantarell", sans-serif; transition: all 0.2s ease; } @@ -209,14 +215,14 @@ font-size: 20px; font-weight: 600; color: #1f2937; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } p { // margin: 0 0 16px 0; font-size: 13px; color: #000000; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; line-height: 1.5; } @@ -228,14 +234,14 @@ font-size: 14px; color: #6c6c6c; font-family: - 'Poppins', + "Poppins", -apple-system, BlinkMacSystemFont, - 'Segoe UI', - 'Roboto', - 'Oxygen', - 'Ubuntu', - 'Cantarell', + "Segoe UI", + "Roboto", + "Oxygen", + "Ubuntu", + "Cantarell", sans-serif; line-height: 1.6; margin-bottom: 8px; @@ -291,7 +297,7 @@ padding: 4px 4px !important; font-size: 12.5px; font-weight: 500; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } .ant-select { @@ -327,7 +333,7 @@ border: none; border-radius: 6px; cursor: pointer; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; transition: all 0.2s ease; flex-shrink: 0; font-size: 24px; @@ -365,7 +371,7 @@ font-size: 13px; letter-spacing: -0.3px; color: #000000; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } } @@ -379,14 +385,14 @@ cursor: pointer; transition: all 0.2s ease; font-family: - 'Poppins', + "Poppins", -apple-system, BlinkMacSystemFont, - 'Segoe UI', - 'Roboto', - 'Oxygen', - 'Ubuntu', - 'Cantarell', + "Segoe UI", + "Roboto", + "Oxygen", + "Ubuntu", + "Cantarell", sans-serif; &:hover { @@ -401,7 +407,7 @@ border-radius: 6px; font-size: 14px; color: #374151; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; width: 190px; &:focus { @@ -436,7 +442,7 @@ background-color: #2563ea !important; height: 42px !important; padding: 10px !important; - font-family: 'Poppins', sans-serif !important; + font-family: "Poppins", sans-serif !important; } button:nth-child(1) { @@ -455,7 +461,7 @@ cursor: pointer; border-radius: 8px; font-size: 14px; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; display: flex; align-items: center; gap: 6px; @@ -476,10 +482,13 @@ width: max-content; .offercount { - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; font-size: 14px; color: #878787; } + .ant-input { + padding: 2px 14px 6px 11px !important; + } } // Table Styles @@ -487,8 +496,6 @@ margin-top: 10px; grid-column: 1 / -1; background-color: #fff; - border: 1px solid #bbbbbb80; - padding: 10px 10px; border-radius: 10px; width: 100%; .ant-table-thead { @@ -512,7 +519,7 @@ cursor: pointer; font-size: 11px; font-weight: 400; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; transition: all 0.2s ease; &:hover { @@ -583,14 +590,14 @@ color: #374151; border-bottom: 1px solid #e2e8f0; font-family: - 'Poppins', + "Poppins", -apple-system, BlinkMacSystemFont, - 'Segoe UI', - 'Roboto', - 'Oxygen', - 'Ubuntu', - 'Cantarell', + "Segoe UI", + "Roboto", + "Oxygen", + "Ubuntu", + "Cantarell", sans-serif; } @@ -600,14 +607,14 @@ color: #374151; border-bottom: 1px solid #e2e8f0; font-family: - 'Poppins', + "Poppins", -apple-system, BlinkMacSystemFont, - 'Segoe UI', - 'Roboto', - 'Oxygen', - 'Ubuntu', - 'Cantarell', + "Segoe UI", + "Roboto", + "Oxygen", + "Ubuntu", + "Cantarell", sans-serif; } @@ -709,7 +716,7 @@ border: 1px solid #565656 !important; border-radius: 8px; font-size: 13px; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; &:focus { outline: none; @@ -731,7 +738,7 @@ border: 1px solid #565656 !important; border-radius: 8px; font-size: 13px; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; &:focus { outline: none; @@ -752,7 +759,7 @@ border-radius: 8px; cursor: pointer; font-size: 13px; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; svg { width: 16px; @@ -777,7 +784,7 @@ border-radius: 10px; font-size: 12px; font-weight: 500; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; .chip-remove { background: none; @@ -801,7 +808,7 @@ color: #6b7280; margin-top: 6px; margin-bottom: 0; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } .modal-button-group { @@ -818,7 +825,7 @@ color: #6b7280; font-size: 14px; cursor: pointer; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } .modal-submit-button { @@ -829,7 +836,7 @@ font-size: 13px; border-radius: 8px; cursor: pointer; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } .modal-title { @@ -838,7 +845,7 @@ color: #1f2937; margin: 0 0 8px 0; -webkit-text-stroke-width: 0.1px; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } .modal-label { @@ -847,7 +854,7 @@ font-weight: 500; color: #374151; margin-bottom: 8px; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } .modal-input-row { @@ -887,7 +894,7 @@ font-weight: 500; border-radius: 6px; cursor: pointer; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } .radio-options { @@ -906,14 +913,14 @@ gap: 10px; font-size: 14px; font-weight: 500; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; background-color: #2563ea1a; border: 1px solid #2563ea40; padding: 4px 8px; border-radius: 6px; color: #000000; font-weight: 400; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; // -webkit-text-stroke-width: 0.2px; } @@ -930,10 +937,10 @@ cursor: pointer; font-size: 14px; color: #374151; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } -.radio-option input[type='radio'] { +.radio-option input[type="radio"] { width: 16px; height: 16px; accent-color: #2563ea; @@ -948,7 +955,7 @@ font-weight: 500; border-radius: 6px; cursor: pointer; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } // Days Section Styles @@ -966,14 +973,14 @@ font-weight: 500; color: #374151; font-family: - 'Poppins', + "Poppins", -apple-system, BlinkMacSystemFont, - 'Segoe UI', - 'Roboto', - 'Oxygen', - 'Ubuntu', - 'Cantarell', + "Segoe UI", + "Roboto", + "Oxygen", + "Ubuntu", + "Cantarell", sans-serif; } @@ -987,14 +994,14 @@ cursor: pointer; transition: all 0.2s ease; font-family: - 'Poppins', + "Poppins", -apple-system, BlinkMacSystemFont, - 'Segoe UI', - 'Roboto', - 'Oxygen', - 'Ubuntu', - 'Cantarell', + "Segoe UI", + "Roboto", + "Oxygen", + "Ubuntu", + "Cantarell", sans-serif; &:hover { @@ -1024,17 +1031,17 @@ font-size: 14px; color: #374151; font-family: - 'Poppins', + "Poppins", -apple-system, BlinkMacSystemFont, - 'Segoe UI', - 'Roboto', - 'Oxygen', - 'Ubuntu', - 'Cantarell', + "Segoe UI", + "Roboto", + "Oxygen", + "Ubuntu", + "Cantarell", sans-serif; - input[type='checkbox'] { + input[type="checkbox"] { width: 16px; height: 16px; accent-color: #3b82f6; @@ -1056,14 +1063,14 @@ font-size: 12px; color: #6b7280; font-family: - 'Poppins', + "Poppins", -apple-system, BlinkMacSystemFont, - 'Segoe UI', - 'Roboto', - 'Oxygen', - 'Ubuntu', - 'Cantarell', + "Segoe UI", + "Roboto", + "Oxygen", + "Ubuntu", + "Cantarell", sans-serif; } } @@ -1076,14 +1083,14 @@ color: #374151; background: #ffffff; font-family: - 'Poppins', + "Poppins", -apple-system, BlinkMacSystemFont, - 'Segoe UI', - 'Roboto', - 'Oxygen', - 'Ubuntu', - 'Cantarell', + "Segoe UI", + "Roboto", + "Oxygen", + "Ubuntu", + "Cantarell", sans-serif; &:focus { @@ -1101,14 +1108,14 @@ font-weight: 500; color: #2563ea; font-family: - 'Poppins', + "Poppins", -apple-system, BlinkMacSystemFont, - 'Segoe UI', - 'Roboto', - 'Oxygen', - 'Ubuntu', - 'Cantarell', + "Segoe UI", + "Roboto", + "Oxygen", + "Ubuntu", + "Cantarell", sans-serif; margin-top: 8px; } @@ -1116,11 +1123,11 @@ .days-selected { font-size: 14px; color: #6b7280; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; background-color: rgba(37, 99, 234, 0.1019607843); padding: 8px 8px; color: #2563ea; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; border-radius: 8px; line-height: 1.5; border: rgba(37, 99, 234, 0.4431372549) 1px solid; @@ -1157,7 +1164,7 @@ font-size: 13px; font-weight: 400; -webkit-text-stroke-width: 0.2px; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; position: relative; bottom: 6px; } @@ -1173,7 +1180,7 @@ background: rgba(37, 99, 234, 0.1019607843); border: rgba(37, 99, 234, 0.4431372549) 1px solid; border-radius: 6px; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } .applied-label { @@ -1265,7 +1272,7 @@ color: #000000; -webkit-text-stroke-width: 0.2px; margin-bottom: 0; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; display: flex; align-items: center; gap: 4px; @@ -1294,7 +1301,7 @@ padding: 4px 4px !important; font-size: 12.5px; font-weight: 500; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } } @@ -1302,7 +1309,7 @@ font-size: 14px; color: #6b7280; margin: 0; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } .mapping-label { @@ -1310,7 +1317,7 @@ font-size: 13px; font-weight: 400; color: #374151; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } .product-list { @@ -1327,7 +1334,7 @@ border-radius: 4px; font-size: 14px; color: #374151; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; display: flex; align-items: center; justify-content: space-between; @@ -1386,7 +1393,7 @@ font-weight: 400; cursor: pointer; transition: all 0.2s ease; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; &:hover { background: #1d4ed8; @@ -1431,7 +1438,7 @@ background: #f3f4f6; padding: 2px 8px; border-radius: 12px; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } .OfferBreadcrumbs { @@ -1450,7 +1457,7 @@ gap: 2px; font-size: 10px; font-weight: 400; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; cursor: pointer; color: #676767; @@ -1480,7 +1487,7 @@ font-weight: 400; // -webkit-text-stroke-width: 0.1px; transition: all 0.2s ease; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; &.active { background: #2563ea; @@ -1539,7 +1546,7 @@ color: #1e1e1e; margin: 17px 6px; font-weight: 500; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; -webkit-text-stroke-width: 0.1px; } @@ -1645,7 +1652,7 @@ cursor: pointer; font-size: 12px; font-weight: 400; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; transition: all 0.2s ease; } } @@ -1665,7 +1672,7 @@ border-radius: 6px; transition: all 0.2s ease; - input[type='checkbox'] { + input[type="checkbox"] { width: 16px; height: 16px; accent-color: #2563ea; @@ -1695,7 +1702,7 @@ font-size: 12px; -webkit-text-stroke-width: 0.1px; font-weight: 500; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } .edit-days-button { @@ -1724,7 +1731,7 @@ font-size: 13px; font-weight: 400; -webkit-text-stroke-width: 0.2px; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; position: relative; bottom: 6px; } @@ -1739,7 +1746,7 @@ gap: 8px; cursor: pointer; - input[type='radio'] { + input[type="radio"] { width: 16px; height: 16px; accent-color: #2563ea; @@ -1749,7 +1756,7 @@ font-size: 12px; color: #000000; font-weight: 500; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } } } @@ -1773,11 +1780,11 @@ .date-picker { width: 100%; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; .ant-picker-input { font-size: 14px; - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; &:focus { outline: none; @@ -1792,11 +1799,11 @@ // Override Ant Design default styles .ant-picker { - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } .ant-picker-input > input { - font-family: 'Poppins', sans-serif; + font-family: "Poppins", sans-serif; } } } diff --git a/src/Pages/Offer/LoyaltyBased/LoyaltiPointList.scss b/src/Pages/Offer/LoyaltyBased/LoyaltiPointList.scss index 52a3dd6..2d67257 100644 --- a/src/Pages/Offer/LoyaltyBased/LoyaltiPointList.scss +++ b/src/Pages/Offer/LoyaltyBased/LoyaltiPointList.scss @@ -484,9 +484,7 @@ margin-top: 10px; grid-column: 1 / -1; background-color: #fff; - border: 1px solid #bbbbbb80; - padding: 10px 10px; - border-radius: 10px; + border-radius: 10px; width: 100%; .ant-table-thead { position: unset !important; diff --git a/src/Pages/Offer/Offer/OfferFormNew.jsx b/src/Pages/Offer/Offer/OfferFormNew.jsx index 3908265..7c7692d 100644 --- a/src/Pages/Offer/Offer/OfferFormNew.jsx +++ b/src/Pages/Offer/Offer/OfferFormNew.jsx @@ -1,14 +1,21 @@ -import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react'; +import React, { + useCallback, + useEffect, + useMemo, + useReducer, + useRef, + useState, +} from 'react'; import dayjs from 'dayjs'; import { useLocation, useNavigate } from 'react-router-dom'; -import { LuGift } from "react-icons/lu"; -import { IoAdd, IoClose } from "react-icons/io5"; -import { IoRefresh } from "react-icons/io5"; -import { FiEdit } from "react-icons/fi"; +import { LuGift } from 'react-icons/lu'; +import { IoAdd, IoClose } from 'react-icons/io5'; +import { IoRefresh } from 'react-icons/io5'; +import { FiEdit } from 'react-icons/fi'; import { useDispatch } from 'react-redux'; import { AutoComplete, DatePicker, Input, Space, Tooltip } from 'antd'; import { Form, message } from 'antd'; -import { debounce } from "lodash"; +import { debounce } from 'lodash'; import { EditFilled, DeleteFilled, @@ -19,39 +26,54 @@ import { InputField } from '../../../Components/Forms/InputField.jsx'; import { DropDowns } from '../../../Components/Forms/DropDown.jsx'; import { Tables } from '../../../Components/Tables/Table.jsx'; import { DefaultModal } from '../../../Components/Modal/DefaultModal.jsx'; -import "./OfferList.scss"; +import './OfferList.scss'; import { getSession } from '../../../Services/Others.js'; -import { PostOfferNew, PutOfferNew, getProdDatas, getLayoutCategories } from '../../../Features/Offer/Offernew/Offernew.js'; +import { + PostOfferNew, + PutOfferNew, + getProdDatas, + getLayoutCategories, +} from '../../../Features/Offer/Offernew/Offernew.js'; import { changeBreadCrumb } from '../../../Features/AppPage/CenterPage.js'; import { BuyXGetXOffer } from '../../BookingScreen/Components/UtillComponents/BSNavBarOffer/BSNavBarOffer_ReusableComponents.jsx'; import FloatLabel from '../../../Components/Forms/FloatLabel/index.jsx'; -import { GiBoxUnpacking } from "react-icons/gi"; +import { GiBoxUnpacking } from 'react-icons/gi'; import { BsUpcScan } from 'react-icons/bs'; const subDirectory = import.meta.env.ENV_BASE_URL; const OfferList = ({ formType }) => { // BOGO state - const [productSearchText, setProductSearchText] = useState(""); - const [bogoBuyProduct, setBogoBuyProduct] = useState({ label: null, prodId: null }); + const [productSearchText, setProductSearchText] = useState(''); + const [bogoBuyProduct, setBogoBuyProduct] = useState({ + label: null, + prodId: null, + }); - - const [bogoFreeProduct, setBogoFreeProduct] = useState({ label: null, prodId: null }); - console.log(bogoBuyProduct, "bogoBuyProduct") + const [bogoFreeProduct, setBogoFreeProduct] = useState({ + label: null, + prodId: null, + }); + console.log(bogoBuyProduct, 'bogoBuyProduct'); // State for toggling stock info in product table const [showStockInfo, setShowStockInfo] = useState(true); - const [productSearch, setProductSearch] = useState(""); + const [productSearch, setProductSearch] = useState(''); const navigate = useNavigate(); const dispatch = useDispatch(); const location = useLocation(); const formRef = useRef(null); const state = location?.state; const editstate = state?.editstate; - const [scanner, setScanner] = useState({ "BUY": false, "FREE": false }); - const [active, setActive] = useState("all"); + const [scanner, setScanner] = useState({ BUY: false, FREE: false }); + const [active, setActive] = useState('all'); const [editStateInside, seteditStateInside] = useState(false); - const [BuyXGETX, dispatchBuyXGETX] = useReducer(BUYXGETXreducer, { modal: false, Prodvariant: [], ProdId: null, type: null }); + const [BuyXGETX, dispatchBuyXGETX] = useReducer(BUYXGETXreducer, { + modal: false, + Prodvariant: [], + ProdId: null, + type: null, + }); // - const AppId = getSession("AppId") + const AppId = getSession('AppId'); const CompId = getSession('CompId'); const BranchId = getSession('BranchId'); const UserId = getSession('UserId'); @@ -59,17 +81,17 @@ const OfferList = ({ formType }) => { // General Offer states const [generalOfferName, setGeneralOfferName] = useState(''); const [generalOfferType, setGeneralOfferType] = useState('Item'); - const [generalDiscountType, setGeneralDiscountType] = useState("fixed"); + const [generalDiscountType, setGeneralDiscountType] = useState('fixed'); const [generalOfferSchedule, setGeneralOfferSchedule] = useState('date'); const [generalDateRange, setGeneralDateRange] = useState(null); - const [limitUsage, setLimitUsage] = useState(""); - const [generalDiscountValue, setGeneralDiscountValue] = useState(""); - const [applyFirstValue, setApplyFirstValue] = useState(""); - const [applySecondValue, setApplySecondValue] = useState(""); + const [limitUsage, setLimitUsage] = useState(''); + const [generalDiscountValue, setGeneralDiscountValue] = useState(''); + const [applyFirstValue, setApplyFirstValue] = useState(''); + const [applySecondValue, setApplySecondValue] = useState(''); const [MappingModalOpen, setMappingModalOpen] = useState(false); const [selectedProductsNew, setSelectedProductsNew] = useState([]); - console.log(selectedProductsNew, "selectedProductsNew") + console.log(selectedProductsNew, 'selectedProductsNew'); //buyxGeTX const [bogoBuyQuantity, setBogoBuyQuantity] = useState(1); @@ -77,7 +99,7 @@ const OfferList = ({ formType }) => { const [BUYXGetTX, setBUYXGetTX] = useState([]); // Offer mapping states - const [mappingType, setMappingType] = useState("all"); + const [mappingType, setMappingType] = useState('all'); const [selectedCategories, setSelectedCategories] = useState([]); const [selectedProducts, setSelectedProducts] = useState([]); @@ -98,24 +120,23 @@ const OfferList = ({ formType }) => { link: `${subDirectory}setting/productBased-offer`, }, { - name: formType === "edit" ? "update" : "new", + name: formType === 'edit' ? 'update' : 'new', link: `${subDirectory}setting/productBased-offer/create`, - } + }, ]; function BUYXGETXreducer(state, action) { - switch (action.type) { - case "modal": + case 'modal': return { ...state, modal: action.payload }; - case "Prodvariant": + case 'Prodvariant': return { ...state, Prodvariant: action.payload }; - case "ProdId": + case 'ProdId': return { ...state, ProdId: action.payload }; - case "type": - return { ...state, type: action.payload } - case "TOGGLE_ACTIVE_STATUS": { + case 'type': + return { ...state, type: action.payload }; + case 'TOGGLE_ACTIVE_STATUS': { const { prodVariantIndex, stockIndex, checked } = action.payload; return { @@ -123,26 +144,26 @@ const OfferList = ({ formType }) => { Prodvariant: state.Prodvariant.map((pv, i) => i === prodVariantIndex ? { - ...pv, - StockDetails: pv.StockDetails.map((sd, j) => - j === stockIndex - ? { ...sd, ActiveStatus: checked ? "A" : "D" } - : sd - ), - } + ...pv, + StockDetails: pv.StockDetails.map((sd, j) => + j === stockIndex + ? { ...sd, ActiveStatus: checked ? 'A' : 'D' } + : sd + ), + } : pv ), }; } - case "Reset": + case 'Reset': return { ...state, ProdId: null, Prodvariant: [], modal: false, - type: null - } + type: null, + }; default: return state; @@ -153,33 +174,34 @@ const OfferList = ({ formType }) => { CategoryFn(); getPrdtsFn(); - if (formType === "edit" && editstate?.ProdOffers[0]?.OfferType == "B") { + if (formType === 'edit' && editstate?.ProdOffers[0]?.OfferType == 'B') { setGeneralOfferName(editstate.OfferName || ''); - setLimitUsage(editstate.LimitUsage !== undefined ? String(editstate.LimitUsage) : ''); + setLimitUsage( + editstate.LimitUsage !== undefined ? String(editstate.LimitUsage) : '' + ); setGeneralOfferType('bogo'); let dateRange = null; if (editstate.OfferFrom && editstate.OfferTo) { dateRange = [ editstate.OfferFrom.substring(0, 10), - editstate.OfferTo.substring(0, 10) + editstate.OfferTo.substring(0, 10), ]; setGeneralDateRange(dateRange); } - setSelectedDays(Array.isArray(editstate.WeekWiseOffer) ? editstate.WeekWiseOffer : []); - setGeneralOfferSchedule(editstate.WeekWiseOffer?.length > 0 ? 'days' : 'date'); + setSelectedDays( + Array.isArray(editstate.WeekWiseOffer) ? editstate.WeekWiseOffer : [] + ); + setGeneralOfferSchedule( + editstate.WeekWiseOffer?.length > 0 ? 'days' : 'date' + ); formRef.current?.setFieldsValue({ OfferName: editstate.OfferName || '', - OfferType: "bogo", + OfferType: 'bogo', generalDateRange: dateRange, }); - - - setBUYXGetTX(editstate?.ProdOffers || []) - - } - else if (formType === "edit" && editstate) { - + setBUYXGetTX(editstate?.ProdOffers || []); + } else if (formType === 'edit' && editstate) { // if (editstate?.ProdOffers?.length && category?.length && editstate?.ProdOffers[0]?.OfferType !== "S") { // let selectedCats = []; @@ -196,24 +218,30 @@ const OfferList = ({ formType }) => { // setMappingType(editstate?.MappingType =="C"? "category":editstate?.MappingType =="P"? "product":"all"); // setSelectedCategories(selectedCats); // } - setActive("product") - setMappingType("product"); + setActive('product'); + setMappingType('product'); setGeneralOfferName(editstate.OfferName || ''); - setGeneralDiscountValue(editstate.OfferAmt !== undefined ? String(editstate.OfferAmt) : ''); - setGeneralDiscountType(editstate.ValueType === 'F' ? 'fixed' : 'percentage'); - setLimitUsage(editstate.LimitUsage !== undefined ? String(editstate.LimitUsage) : ''); + setGeneralDiscountValue( + editstate.OfferAmt !== undefined ? String(editstate.OfferAmt) : '' + ); + setGeneralDiscountType( + editstate.ValueType === 'F' ? 'fixed' : 'percentage' + ); + setLimitUsage( + editstate.LimitUsage !== undefined ? String(editstate.LimitUsage) : '' + ); let offerTypeValue = 'Item'; let applyFirst = ''; let applySecond = ''; - const preSelectedProducts = (editstate?.ProdOffers || []).map(prod => ({ + const preSelectedProducts = (editstate?.ProdOffers || []).map((prod) => ({ ...prod, - checked: prod.ActiveStatus === "A", - ProdVariantDetails: (prod.ProdVariantDetails || []).map(variant => ({ + checked: prod.ActiveStatus === 'A', + ProdVariantDetails: (prod.ProdVariantDetails || []).map((variant) => ({ ...variant, - StockDetails: (variant.StockDetails || []).map(stock => ({ + StockDetails: (variant.StockDetails || []).map((stock) => ({ ...stock, - checked: stock.ActiveStatus === "A" - })) + checked: stock.ActiveStatus === 'A', + })), })), })); @@ -226,30 +254,42 @@ const OfferList = ({ formType }) => { else if (offerTypeCode === 'bogo') offerTypeValue = 'bogo'; setGeneralOfferType(offerTypeValue); if (offerTypeValue === 'Item') { - applyFirst = prodOffer.MinQty !== undefined ? String(prodOffer.MinQty) : ''; - applySecond = prodOffer.MinPurchase !== undefined ? String(prodOffer.MinPurchase) : ''; + applyFirst = + prodOffer.MinQty !== undefined ? String(prodOffer.MinQty) : ''; + applySecond = + prodOffer.MinPurchase !== undefined + ? String(prodOffer.MinPurchase) + : ''; } else if (offerTypeValue === 'Sales') { - applyFirst = prodOffer.AmountFrom !== undefined ? String(prodOffer.AmountFrom) : ''; - applySecond = prodOffer.AmountTo !== undefined ? String(prodOffer.AmountTo) : ''; + applyFirst = + prodOffer.AmountFrom !== undefined + ? String(prodOffer.AmountFrom) + : ''; + applySecond = + prodOffer.AmountTo !== undefined ? String(prodOffer.AmountTo) : ''; } else if (offerTypeValue === 'Quantity') { - applyFirst = prodOffer.FromQty !== undefined ? String(prodOffer.FromQty) : ''; - applySecond = prodOffer.ToQty !== undefined ? String(prodOffer.ToQty) : ''; + applyFirst = + prodOffer.FromQty !== undefined ? String(prodOffer.FromQty) : ''; + applySecond = + prodOffer.ToQty !== undefined ? String(prodOffer.ToQty) : ''; } setApplyFirstValue(applyFirst); setApplySecondValue(applySecond); - - let dateRange = null; if (editstate.OfferFrom && editstate.OfferTo) { dateRange = [ editstate.OfferFrom.substring(0, 10), - editstate.OfferTo.substring(0, 10) + editstate.OfferTo.substring(0, 10), ]; setGeneralDateRange(dateRange); } - setSelectedDays(Array.isArray(editstate.WeekWiseOffer) ? editstate.WeekWiseOffer : []); - setGeneralOfferSchedule(editstate.WeekWiseOffer?.length > 0 ? 'days' : 'date'); + setSelectedDays( + Array.isArray(editstate.WeekWiseOffer) ? editstate.WeekWiseOffer : [] + ); + setGeneralOfferSchedule( + editstate.WeekWiseOffer?.length > 0 ? 'days' : 'date' + ); formRef.current?.setFieldsValue({ OfferName: editstate.OfferName || '', OfferType: offerTypeValue, @@ -261,7 +301,6 @@ const OfferList = ({ formType }) => { } }, []); const debouncedScannerSearch = useCallback( - debounce((value, type) => { const qr = value?.trim(); const matchedProduct = Prods.find( @@ -269,7 +308,7 @@ const OfferList = ({ formType }) => { ); if (matchedProduct) { let productName = {}; - productName.label = `${matchedProduct?.ProdName}` + productName.label = `${matchedProduct?.ProdName}`; ProductDropDownChange(matchedProduct.ProdId, productName, type); if (matchedProduct?.ProdVariantPriceDetails?.length < 2) { // setSelectedProductName(""); @@ -278,79 +317,61 @@ const OfferList = ({ formType }) => { } else { // setMessageType("error"); // setMessageData("The Scanned Product not Available in Product List") - message.error("The Scanned Product not Available in Product List") + message.error('The Scanned Product not Available in Product List'); } }, 300), [Prods] ); const getPrdtsFn = async () => { - const Prods = await dispatch(getProdDatas({ - CompId: CompId, - BranchId: BranchId, - AppId: AppId, - }) + const Prods = await dispatch( + getProdDatas({ + CompId: CompId, + BranchId: BranchId, + AppId: AppId, + }) ).unwrap(); if (Prods?.data?.statusCode == 1) { - const cleanedData = Prods.data?.data - .map(product => ({ + .map((product) => ({ ...product, ProdVariantDetails: product.ProdVariantDetails.filter( - v => Array.isArray(v.StockDetails) && v.StockDetails.length > 0 - ) + (v) => Array.isArray(v.StockDetails) && v.StockDetails.length > 0 + ), })) - .filter(product => product.ProdVariantDetails.length > 0); + .filter((product) => product.ProdVariantDetails.length > 0); setProds([...cleanedData]); } - - - - - }; - const CategoryFn = async () => { - const Category = await dispatch(getLayoutCategories({ - CompId: CompId, - BranchId: BranchId, - AppId: AppId, - }) + const Category = await dispatch( + getLayoutCategories({ + CompId: CompId, + BranchId: BranchId, + AppId: AppId, + }) ).unwrap(); if (Category?.data?.statusCode == 1) { setcategory(Category.data?.data); } - - - } - + }; // useEffect(() => { // if (mappingType !== 'category') return; - // const productIds = (Prods || []) // .filter((p) => (selectedCategories || []).includes(p?.ProdCat)) // .map((p) => p?.ProdId); - - - // setSelectedProducts(productIds); // }, [mappingType, Prods]); - - - - - const BogoFreeAddFn = (bogoBuyProduct, bogoFreeProduct) => { - if ( - !bogoBuyProduct.startsWith(`P${getSession("AppId")}`) || - !bogoFreeProduct.startsWith(`P${getSession("AppId")}`) + !bogoBuyProduct.startsWith(`P${getSession('AppId')}`) || + !bogoFreeProduct.startsWith(`P${getSession('AppId')}`) ) { - message.error("Please select both Buy and Free products"); + message.error('Please select both Buy and Free products'); return; } @@ -358,17 +379,20 @@ const OfferList = ({ formType }) => { let Freeprdt = Prods?.filter((e) => e?.ProdId == bogoFreeProduct); // const existingOfferId = BUYXGetTX?.find(e => e?.OfferId)?.ProdVariantDetails?.[0]?.StockDetails[0]?.ProdOfferId || null // Check if editing (editStateInside is true and entry exists) - if (editStateInside && BUYXGetTX?.some(e => e?.ProdId === bogoBuyProduct)) { + if ( + editStateInside && + BUYXGetTX?.some((e) => e?.ProdId === bogoBuyProduct) + ) { // Update only the Buy Qty and Free Qty for the existing entry - const updated = BUYXGetTX.map(item => { + const updated = BUYXGetTX.map((item) => { if (item.ProdId === bogoBuyProduct) { return { ...item, MinQty: bogoBuyQuantity, - FreeProductDetails: item.FreeProductDetails?.map(free => ({ + FreeProductDetails: item.FreeProductDetails?.map((free) => ({ ...free, - FreeQty: bogoFreeQuantity - })) + FreeQty: bogoFreeQuantity, + })), }; } return item; @@ -378,8 +402,12 @@ const OfferList = ({ formType }) => { } else { // Prevent duplicate add - if (BUYXGetTX?.some(e => e?.FreeProductDetails?.[0]?.FreeProdId === bogoFreeProduct)) { - message.error("This Free Product is already added"); + if ( + BUYXGetTX?.some( + (e) => e?.FreeProductDetails?.[0]?.FreeProdId === bogoFreeProduct + ) + ) { + message.error('This Free Product is already added'); return; } let data = { @@ -390,32 +418,32 @@ const OfferList = ({ formType }) => { ProdVariantName: v?.ProdVariantName, StockDetails: v?.StockDetails?.map((s) => ({ InwardDtlId: s?.InwardDtlId, - ActiveStatus: "A", + ActiveStatus: 'A', // ProdOfferId: existingOfferId || "" - - })), })), MinQty: bogoBuyQuantity, OfferType: 'B', - ActiveStatus: "A", + ActiveStatus: 'A', BuyNGetName: `BUY ${bogoBuyQuantity} GET ${bogoFreeQuantity} `, - HalfPrice: "N", - FreeProductDetails: [{ - FreeProdId: Freeprdt?.[0]?.ProdId, - FreeProdName: Freeprdt?.[0]?.ProdName, - FreeQty: bogoFreeQuantity, - ActiveStatus: "A", - ProdVariantDetails: Freeprdt?.[0]?.ProdVariantDetails?.map((v) => ({ - FreeProdVariantName: v?.ProdVariantName, + HalfPrice: 'N', + FreeProductDetails: [ + { + FreeProdId: Freeprdt?.[0]?.ProdId, + FreeProdName: Freeprdt?.[0]?.ProdName, + FreeQty: bogoFreeQuantity, + ActiveStatus: 'A', + ProdVariantDetails: Freeprdt?.[0]?.ProdVariantDetails?.map((v) => ({ + FreeProdVariantName: v?.ProdVariantName, - StockDetails: v?.StockDetails?.map((s) => ({ - FreeProdInwardDtlId: s?.InwardDtlId, - ActiveStatus: "A", - // ProdOfferId: existingOfferId || "" + StockDetails: v?.StockDetails?.map((s) => ({ + FreeProdInwardDtlId: s?.InwardDtlId, + ActiveStatus: 'A', + // ProdOfferId: existingOfferId || "" + })), })), - })), - }], + }, + ], }; setBUYXGetTX((prev) => [...prev, data]); @@ -424,7 +452,7 @@ const OfferList = ({ formType }) => { setBogoFreeProduct({ label: null, prodId: null }); setBogoBuyQuantity(1); setBogoFreeQuantity(1); - } + }; const handleChange = (pagination, filters, sorter) => { setSortedInfo(sorter); }; @@ -433,100 +461,93 @@ const OfferList = ({ formType }) => { setpage(current); }; - const handleDelete = (record) => { const recordData = record?.FreeProductDetails; if (record.OfferId) { - const updatedBUYXGetTX = BUYXGetTX.map(item => { + const updatedBUYXGetTX = BUYXGetTX.map((item) => { if (item.ProdId === record.ProdId) { - return { ...item, ActiveStatus: "D" }; // mark whole item inactive + return { ...item, ActiveStatus: 'D' }; // mark whole item inactive } return item; }); setBUYXGetTX(updatedBUYXGetTX); } else { - const updatedBUYXGetTX = BUYXGetTX.filter(item => + const updatedBUYXGetTX = BUYXGetTX.filter((item) => item.FreeProductDetails.every( - freeItem => freeItem.FreeProdId !== recordData?.[0]?.FreeProdId + (freeItem) => freeItem.FreeProdId !== recordData?.[0]?.FreeProdId ) ); setBUYXGetTX(updatedBUYXGetTX); } }; - - - const statusFormatter = (record) => { - - if (record.ActiveStatus === "A") { + if (record.ActiveStatus === 'A') { handleDelete(record); } else { - const updatedBUYXGetTX = BUYXGetTX?.map(item => { + const updatedBUYXGetTX = BUYXGetTX?.map((item) => { if (item.ProdId === record.ProdId) { return { ...item, - ActiveStatus: "A", - ProdVariantDetails: item.ProdVariantDetails?.map(variant => ({ + ActiveStatus: 'A', + ProdVariantDetails: item.ProdVariantDetails?.map((variant) => ({ ...variant, - StockDetails: variant.StockDetails?.map(stock => ({ + StockDetails: variant.StockDetails?.map((stock) => ({ ...stock, - ActiveStatus: "A" - })) + ActiveStatus: 'A', + })), })), - FreeProductDetails: item.FreeProductDetails?.map(free => ({ + FreeProductDetails: item.FreeProductDetails?.map((free) => ({ ...free, - ActiveStatus: "A", - ProdVariantDetails: free.ProdVariantDetails?.map(freeVar => ({ + ActiveStatus: 'A', + ProdVariantDetails: free.ProdVariantDetails?.map((freeVar) => ({ ...freeVar, - StockDetails: freeVar.StockDetails?.map(freeStock => ({ + StockDetails: freeVar.StockDetails?.map((freeStock) => ({ ...freeStock, - ActiveStatus: "A" - })) - })) - })) + ActiveStatus: 'A', + })), + })), + })), }; } return item; }); setBUYXGetTX(updatedBUYXGetTX); } - - - - } + }; const actionsFormatter = (record, index) => { seteditStateInside(true); setBogoBuyProduct({ label: record?.ProdName, prodId: record?.ProdId }); - setBogoFreeProduct({ label: record?.FreeProductDetails[0]?.FreeProdName, prodId: record?.FreeProductDetails[0]?.FreeProdId }) + setBogoFreeProduct({ + label: record?.FreeProductDetails[0]?.FreeProdName, + prodId: record?.FreeProductDetails[0]?.FreeProdId, + }); setBogoBuyQuantity(record.MinQty || 1); setBogoFreeQuantity(record?.FreeProductDetails?.[0]?.FreeQty); - } + }; function validate50PercentageOffer(buyDetails, getDetails) { - if (!buyDetails?.length || !getDetails?.length) return false; // Collect active stock IDs for buy products const buyStockIds = new Set( - buyDetails.flatMap(variant => + buyDetails.flatMap((variant) => (variant.StockDetails || []) - .filter(stock => stock.ActiveStatus === "A") - .map(stock => stock.InwardDtlId) + .filter((stock) => stock.ActiveStatus === 'A') + .map((stock) => stock.InwardDtlId) ) ); // Collect active stock IDs for free products const getStockIds = new Set( - getDetails.flatMap(variant => + getDetails.flatMap((variant) => (variant.StockDetails || []) - .filter(stock => stock.ActiveStatus === "A") - .map(stock => stock.FreeProdInwardDtlId) + .filter((stock) => stock.ActiveStatus === 'A') + .map((stock) => stock.FreeProdInwardDtlId) ) ); - // If counts differ, no need to check further if (buyStockIds.size !== getStockIds.size) return false; @@ -538,258 +559,247 @@ const OfferList = ({ formType }) => { return true; } + const Columns = useMemo( + () => [ + { + title: 'Name', + dataIndex: 'BuyNGetName', + key: 'BuyNGetName', + // render: (_, record, index) => ( + // <> + // BUY + // {record?.MinQty} + // GET + // {record?.FreeProductDetails?.[0]?.FreeQty || "-"} - const Columns = useMemo(() => [ - { - title: "Name", - dataIndex: "BuyNGetName", - key: "BuyNGetName", - // render: (_, record, index) => ( - // <> - // BUY - // {record?.MinQty} - // GET - // {record?.FreeProductDetails?.[0]?.FreeQty || "-"} + // - - - // - - // ) - }, - - { - title: "BUY PRODUCT", - dataIndex: "ProdName", - key: "ProdName", - render: (_, record, index) => { - - - const hasMultipleStock = - (record?.ProdVariantDetails?.length || 0) > 1 || // multiple variants - record?.ProdVariantDetails?.some( - (variant) => (variant?.StockDetails?.length || 0) > 1 // multiple stocks in a variant - ); - - - return ( - <> - {record?.ProdName} - - {hasMultipleStock && ( - { - dispatchBuyXGETX({ - type: "Prodvariant", - payload: record?.ProdVariantDetails, - }); - dispatchBuyXGETX({ type: "modal", payload: true }); - dispatchBuyXGETX({ type: "ProdId", payload: record?.ProdId }); - dispatchBuyXGETX({ type: "type", payload: "BUY" }); - }} - > - - - )} - - ); + // ) }, - }, - { - title: "QTY", - dataIndex: "MinQty", - key: "MinQty", - align: "right", - }, - { - title: "FREE PRODUCT", - key: "FreeProduct", - align: "right", - render: (_, record) => { + { + title: 'BUY PRODUCT', + dataIndex: 'ProdName', + key: 'ProdName', + render: (_, record, index) => { + const hasMultipleStock = + (record?.ProdVariantDetails?.length || 0) > 1 || // multiple variants + record?.ProdVariantDetails?.some( + (variant) => (variant?.StockDetails?.length || 0) > 1 // multiple stocks in a variant + ); - const hasMultipleStock = - (record?.ProdVariantDetails?.length || 0) > 1 || // multiple variants - record?.ProdVariantDetails?.some( - (variant) => (variant?.StockDetails?.length || 0) > 1 // multiple stocks in a variant - ); - return ( - - {record?.FreeProductDetails?.[0]?.FreeProdName || "-"} - {hasMultipleStock && ( - { - dispatchBuyXGETX({ - type: "Prodvariant", - payload: record?.FreeProductDetails[0]?.ProdVariantDetails, - }); - dispatchBuyXGETX({ type: "modal", payload: true }); - dispatchBuyXGETX({ type: "ProdId", payload: record?.FreeProductDetails[0]?.FreeProdId }); - dispatchBuyXGETX({ type: "type", payload: "FREE" }); - - }} - > - - - )} - - ); - }, - }, - - - - { - title: "FREE QTY", - key: "FreeQty", - align: "center", - render: (_, record) => ( - {record?.FreeProductDetails?.[0]?.FreeQty || "-"} - ), - }, - { - title: "ACTIONS", - key: "actions", - align: "center", - render: (_, record, index) => { - // if (!BUYXGetTX.length) return null; - - // Check if Buy and Free stocks match - const isValid = validate50PercentageOffer( - [record.ProdVariantDetails]?.[0], // Buy Product details - record?.FreeProductDetails?.[0]?.ProdVariantDetails || [] // Free Product details - ); - console.log(isValid, 'isValid') - - - return ( - - {/* Show checkbox if valid */} - {isValid && record.MinQty == record?.FreeProductDetails?.[0]?.FreeQty && ( - - 50% off  - { - setBUYXGetTX((prev) => - prev.map((item, index1) => index === index1 ? - { ...item, HalfPrice: item?.HalfPrice == "Y" ? "N" : "Y" } : item - )) + return ( + <> + {record?.ProdName} + {hasMultipleStock && ( + { + dispatchBuyXGETX({ + type: 'Prodvariant', + payload: record?.ProdVariantDetails, + }); + dispatchBuyXGETX({ type: 'modal', payload: true }); + dispatchBuyXGETX({ + type: 'ProdId', + payload: record?.ProdId, + }); + dispatchBuyXGETX({ type: 'type', payload: 'BUY' }); }} - /> - - - )} - - {/* Edit */} - {record.ActiveStatus === "A" && ( - actionsFormatter(record, index)} - /> - )} - - {record.ActiveStatus === "A" ? ( - statusFormatter(record)} - /> - ) : ( - statusFormatter(record)} - /> - )} - - ); + > + + + )} + + ); + }, }, - } - ], [BUYXGetTX, editStateInside]); + { + title: 'QTY', + dataIndex: 'MinQty', + key: 'MinQty', + align: 'right', + }, + { + title: 'FREE PRODUCT', + key: 'FreeProduct', + align: 'right', + render: (_, record) => { + const hasMultipleStock = + (record?.ProdVariantDetails?.length || 0) > 1 || // multiple variants + record?.ProdVariantDetails?.some( + (variant) => (variant?.StockDetails?.length || 0) > 1 // multiple stocks in a variant + ); + return ( + + {record?.FreeProductDetails?.[0]?.FreeProdName || '-'} + {hasMultipleStock && ( + { + dispatchBuyXGETX({ + type: 'Prodvariant', + payload: + record?.FreeProductDetails[0]?.ProdVariantDetails, + }); + dispatchBuyXGETX({ type: 'modal', payload: true }); + dispatchBuyXGETX({ + type: 'ProdId', + payload: record?.FreeProductDetails[0]?.FreeProdId, + }); + dispatchBuyXGETX({ type: 'type', payload: 'FREE' }); + }} + > + + + )} + + ); + }, + }, + { + title: 'FREE QTY', + key: 'FreeQty', + align: 'center', + render: (_, record) => ( + {record?.FreeProductDetails?.[0]?.FreeQty || '-'} + ), + }, + { + title: 'ACTIONS', + key: 'actions', + align: 'center', + render: (_, record, index) => { + // if (!BUYXGetTX.length) return null; + // Check if Buy and Free stocks match + const isValid = validate50PercentageOffer( + [record.ProdVariantDetails]?.[0], // Buy Product details + record?.FreeProductDetails?.[0]?.ProdVariantDetails || [] // Free Product details + ); + console.log(isValid, 'isValid'); + return ( + + {/* Show checkbox if valid */} + {isValid && + record.MinQty == record?.FreeProductDetails?.[0]?.FreeQty && ( + + 50% off  + { + setBUYXGetTX((prev) => + prev.map((item, index1) => + index === index1 + ? { + ...item, + HalfPrice: item?.HalfPrice == 'Y' ? 'N' : 'Y', + } + : item + ) + ); + }} + /> + + )} + {/* Edit */} + {record.ActiveStatus === 'A' && ( + actionsFormatter(record, index)} + /> + )} + + {record.ActiveStatus === 'A' ? ( + statusFormatter(record)} + /> + ) : ( + statusFormatter(record)} + /> + )} + + ); + }, + }, + ], + [BUYXGetTX, editStateInside] + ); const generalOfferTypeOptions = [ { value: 'Sales', label: 'On Sales Amount' }, { value: 'bogo', label: 'Buy & Get Free' }, { value: 'Item', label: 'Product Wise' }, - { value: 'Quantity', label: 'On Sales Quantity' } + { value: 'Quantity', label: 'On Sales Quantity' }, ]; - - const handleScanSearch = (type) => { - - if (type == "buy") { + if (type == 'buy') { if (scanner.BUY === false) { - message.success("Search by QrCode/BarCode Enabled") + message.success('Search by QrCode/BarCode Enabled'); } else { - message.success("Search by QrCode/BarCode Disabled") + message.success('Search by QrCode/BarCode Disabled'); } setScanner((prev) => ({ ...prev, - BUY: !prev.BUY + BUY: !prev.BUY, })); - - } - else { + } else { if (scanner.FREE === false) { - message.success("Search by QrCode/BarCode Enabled") + message.success('Search by QrCode/BarCode Enabled'); } else { - message.success("Search by QrCode/BarCode Disabled") - } setScanner((prev) => ({ + message.success('Search by QrCode/BarCode Disabled'); + } + setScanner((prev) => ({ ...prev, - FREE: !prev.FREE + FREE: !prev.FREE, })); - } - - - - } + }; const ProductDropDownChange = async (ProdId, option, type) => { - if (type == "buy") { + if (type == 'buy') { setBogoBuyProduct({ label: option?.label ? option?.label : '', - prodId: ProdId - } - ) - } - else { + prodId: ProdId, + }); + } else { setBogoFreeProduct({ label: option?.label ? option?.label : '', - prodId: ProdId - }) + prodId: ProdId, + }); // setBogoFreeProduct(option?.label ? option?.label : '') } // setBogoBuyProduct(option?.label ? option?.label : '') - setProductSearchText("") - - } + setProductSearchText(''); + }; const handleProductSearch = (value, label, type) => { setProductSearchText(value); - if (type === "buy") { - + if (type === 'buy') { if (scanner.BUY) { - debouncedScannerSearch(value, type); } setBogoBuyProduct({ label: label ?? value, prodId: value }); - } - else { + } else { if (scanner.FREE) { debouncedScannerSearch(value, type); } setBogoFreeProduct({ label: label ?? value, prodId: value }); - } // setBogoBuyProduct(value) @@ -798,8 +808,6 @@ const OfferList = ({ formType }) => { // setVariants([]) }; - - const getApplyOnLabels = (offerType) => { switch (offerType) { case 'Quantity': @@ -815,10 +823,13 @@ const OfferList = ({ formType }) => { } }; - const handleProductClick = (product, options = {}) => { if (!product) return; - const { selectedVariantName = null, selectedInwardId = null, isChecked = true } = options; + const { + selectedVariantName = null, + selectedInwardId = null, + isChecked = true, + } = options; setSelectedProductsNew((prev) => { const exists = prev.find((p) => p.ProdId === product.ProdId); @@ -829,16 +840,19 @@ const OfferList = ({ formType }) => { const updatedVariants = p.ProdVariantDetails.map((variant) => { // Variant-level toggle - if (selectedVariantName && variant.ProdVariantName === selectedVariantName) { + if ( + selectedVariantName && + variant.ProdVariantName === selectedVariantName + ) { return { ...variant, StockDetails: variant.StockDetails.map((stock) => ({ ...stock, checked: isChecked, ActiveStatus: isChecked - ? "A" + ? 'A' : stock.ProdOfferId - ? "D" + ? 'D' : stock.ActiveStatus, })), }; @@ -851,27 +865,24 @@ const OfferList = ({ formType }) => { StockDetails: variant.StockDetails.map((stock) => stock.InwardDtlId === selectedInwardId ? { - ...stock, - checked: isChecked, - ActiveStatus: isChecked ? "A" : "D", - } - : - stock - + ...stock, + checked: isChecked, + ActiveStatus: isChecked ? 'A' : 'D', + } + : stock ), }; } - return { ...variant, StockDetails: variant.StockDetails.map((stock) => ({ ...stock, checked: isChecked, ActiveStatus: isChecked - ? "A" + ? 'A' : stock.ProdOfferId - ? "D" + ? 'D' : stock.ActiveStatus, })), }; @@ -886,7 +897,7 @@ const OfferList = ({ formType }) => { return { ...p, checked: false, - ActiveStatus: "D", + ActiveStatus: 'D', ProdVariantDetails: updatedVariants, }; } @@ -896,7 +907,11 @@ const OfferList = ({ formType }) => { return { ...p, checked: hasAnyStockChecked, - ActiveStatus: hasAnyStockChecked ? "A" : p.OfferId ? "D" : p.ActiveStatus, + ActiveStatus: hasAnyStockChecked + ? 'A' + : p.OfferId + ? 'D' + : p.ActiveStatus, ProdVariantDetails: updatedVariants, }; }); @@ -910,23 +925,25 @@ const OfferList = ({ formType }) => { const newProduct = { ProdCat: product.ProdCat, ProdId: product.ProdId, - ActiveStatus: "A", + ActiveStatus: 'A', checked: true, - ProdVariantDetails: (product.ProdVariantDetails || []).map((variant) => ({ - ProdVariantName: variant.ProdVariantName, - StockDetails: (variant.StockDetails || []).map((stock) => { - const isTarget = selectedInwardId - ? stock.InwardDtlId === selectedInwardId - : true; + ProdVariantDetails: (product.ProdVariantDetails || []).map( + (variant) => ({ + ProdVariantName: variant.ProdVariantName, + StockDetails: (variant.StockDetails || []).map((stock) => { + const isTarget = selectedInwardId + ? stock.InwardDtlId === selectedInwardId + : true; - return { - ProdOfferId: stock.ProdOfferId || "", - InwardDtlId: stock.InwardDtlId || "", - checked: isTarget, - ActiveStatus: isTarget ? "A" : "D", - }; - }), - })), + return { + ProdOfferId: stock.ProdOfferId || '', + InwardDtlId: stock.InwardDtlId || '', + checked: isTarget, + ActiveStatus: isTarget ? 'A' : 'D', + }; + }), + }) + ), FreeProductDetails: [], }; @@ -934,11 +951,6 @@ const OfferList = ({ formType }) => { }); }; - - - - - const handleCategoryClick = (categoryId, isChecked = true) => { setSelectedProductsNew((prev) => { if (!isChecked) { @@ -947,24 +959,31 @@ const OfferList = ({ formType }) => { } // ✅ Checked → add all products in this category - const productsInCategory = (Prods || []).filter((p) => p.ProdCat === categoryId); + const productsInCategory = (Prods || []).filter( + (p) => p.ProdCat === categoryId + ); const newProducts = productsInCategory - .filter((product) => product?.ProdId && !prev.some((p) => p.ProdId === product.ProdId)) // skip invalid & already added + .filter( + (product) => + product?.ProdId && !prev.some((p) => p.ProdId === product.ProdId) + ) // skip invalid & already added .map((product) => ({ ProdCat: product.ProdCat, ProdId: product.ProdId, - ActiveStatus: "A", + ActiveStatus: 'A', checked: true, - ProdVariantDetails: (product.ProdVariantDetails || []).map((variant) => ({ - ProdVariantName: variant.ProdVariantName || "", - StockDetails: (variant.StockDetails || []).map((stock) => ({ - ProdOfferId: stock.ProdOfferId || "", - ActiveStatus: "A", - InwardDtlId: stock.InwardDtlId || "", - checked: true, // all stocks auto-selected - })), - })), + ProdVariantDetails: (product.ProdVariantDetails || []).map( + (variant) => ({ + ProdVariantName: variant.ProdVariantName || '', + StockDetails: (variant.StockDetails || []).map((stock) => ({ + ProdOfferId: stock.ProdOfferId || '', + ActiveStatus: 'A', + InwardDtlId: stock.InwardDtlId || '', + checked: true, // all stocks auto-selected + })), + }) + ), FreeProductDetails: [], })); @@ -974,30 +993,34 @@ const OfferList = ({ formType }) => { const handleSelectAllProducts = (isChecked = true) => { setSelectedProductsNew((prev) => { if (!isChecked) { - setSelectedCategories([]); // clear categories too - console.log("Selected Categories: 0"); - console.log("Selected Products: 0"); + console.log('Selected Categories: 0'); + console.log('Selected Products: 0'); return []; } // ✅ Checked → add all products const newProducts = (Prods || []) - .filter((product) => product?.ProdId && !prev.some((p) => p.ProdId === product.ProdId)) + .filter( + (product) => + product?.ProdId && !prev.some((p) => p.ProdId === product.ProdId) + ) .map((product) => ({ ProdCat: product.ProdCat, ProdId: product.ProdId, - ActiveStatus: "A", + ActiveStatus: 'A', checked: true, - ProdVariantDetails: (product.ProdVariantDetails || []).map((variant) => ({ - ProdVariantName: variant.ProdVariantName || "", - StockDetails: (variant.StockDetails || []).map((stock) => ({ - ProdOfferId: stock.ProdOfferId || "", - ActiveStatus: "A", - InwardDtlId: stock.InwardDtlId || "", - checked: true, - })), - })), + ProdVariantDetails: (product.ProdVariantDetails || []).map( + (variant) => ({ + ProdVariantName: variant.ProdVariantName || '', + StockDetails: (variant.StockDetails || []).map((stock) => ({ + ProdOfferId: stock.ProdOfferId || '', + ActiveStatus: 'A', + InwardDtlId: stock.InwardDtlId || '', + checked: true, + })), + }) + ), FreeProductDetails: [], })); @@ -1006,8 +1029,12 @@ const OfferList = ({ formType }) => { setSelectedCategories(categoryIds); - console.log("Selected Categories:", categoryIds.length, categoryIds); - console.log("Selected Products:", newProducts.length, newProducts.map(p => p.ProdId)); + console.log('Selected Categories:', categoryIds.length, categoryIds); + console.log( + 'Selected Products:', + newProducts.length, + newProducts.map((p) => p.ProdId) + ); return [...prev, ...newProducts]; }); @@ -1024,70 +1051,70 @@ const OfferList = ({ formType }) => { return `${day}-${month}-${year}`; } - - const handleBackToOfferTable = async () => { - - - if (formType === 'edit') { - if (generalOfferType === "bogo") { - - - const hasTwoDates = Array.isArray(generalDateRange) && generalDateRange.length === 2 && generalDateRange[0] && generalDateRange[1]; + if (generalOfferType === 'bogo') { + const hasTwoDates = + Array.isArray(generalDateRange) && + generalDateRange.length === 2 && + generalDateRange[0] && + generalDateRange[1]; let postData = { OfferId: editstate.OfferId, - "AppId": AppId, - "CompId": CompId, - "BranchId": BranchId, - "OfferName": generalOfferName, - "OfferAmt": 0, - "ValueType": null, - "OfferFrom": hasTwoDates ? generalDateRange[0] : null, - "OfferTo": hasTwoDates ? generalDateRange[1] : null, - "WeekWiseOffer": - selectedDays, - "LimitUsage": limitUsage, - "MappingType": null, - "OfferDetails": BUYXGetTX, - UpdatedBy: UserId + AppId: AppId, + CompId: CompId, + BranchId: BranchId, + OfferName: generalOfferName, + OfferAmt: 0, + ValueType: null, + OfferFrom: hasTwoDates ? generalDateRange[0] : null, + OfferTo: hasTwoDates ? generalDateRange[1] : null, + WeekWiseOffer: selectedDays, + LimitUsage: limitUsage, + MappingType: null, + OfferDetails: BUYXGetTX, + UpdatedBy: UserId, }; - console.log(postData, 'postData') + console.log(postData, 'postData'); let response; response = await dispatch(PutOfferNew(postData)).unwrap(); - if (response?.data?.statusCode === 1) { - - - navigate(`${subDirectory}setting/productBased-offer`, { state: { Notiffy: { - messageData: response?.data?.response || "Offer updated successfully", - messageType: "success" + messageData: + response?.data?.response || 'Offer updated successfully', + messageType: 'success', }, }, - }); - } else { - message.error(response?.data?.response || "Failed to update offer"); + message.error(response?.data?.response || 'Failed to update offer'); } + } else { + const hasTwoDates = + Array.isArray(generalDateRange) && + generalDateRange.length === 2 && + generalDateRange[0] && + generalDateRange[1]; - } - else { - const hasTwoDates = Array.isArray(generalDateRange) && generalDateRange.length === 2 && generalDateRange[0] && generalDateRange[1]; - - - const offerTypeCode = generalOfferType === 'Item' ? 'I' : generalOfferType === 'Sales' ? 'S' : generalOfferType === 'Quantity' ? 'Q' : ''; - const firstNum = applyFirstValue !== '' ? Number(applyFirstValue) : null; - const secondNum = applySecondValue !== '' ? Number(applySecondValue) : null; - + const offerTypeCode = + generalOfferType === 'Item' + ? 'I' + : generalOfferType === 'Sales' + ? 'S' + : generalOfferType === 'Quantity' + ? 'Q' + : ''; + const firstNum = + applyFirstValue !== '' ? Number(applyFirstValue) : null; + const secondNum = + applySecondValue !== '' ? Number(applySecondValue) : null; const defaultOfferFields = { OfferType: offerTypeCode, @@ -1105,13 +1132,6 @@ const OfferList = ({ formType }) => { ...defaultOfferFields, })); - - - - - - - let putData = { AppId: AppId, CompId: CompId, @@ -1124,25 +1144,34 @@ const OfferList = ({ formType }) => { OfferTo: hasTwoDates ? generalDateRange[1] : null, WeekWiseOffer: selectedDays, LimitUsage: limitUsage, - MappingType: mappingType === 'all' ? 'A' : mappingType === 'category' ? 'C' : 'P', - OfferDetails: generalOfferType == "Sales" ? [{ - AmountTo: secondNum !== '' ? secondNum : 0, - AmountFrom: firstNum !== '' ? firstNum : 0, - OfferType: 'S', - ActiveStatus: 'A', - }] : offerDetail, + MappingType: + mappingType === 'all' + ? 'A' + : mappingType === 'category' + ? 'C' + : 'P', + OfferDetails: + generalOfferType == 'Sales' + ? [ + { + AmountTo: secondNum !== '' ? secondNum : 0, + AmountFrom: firstNum !== '' ? firstNum : 0, + OfferType: 'S', + ActiveStatus: 'A', + }, + ] + : offerDetail, UpdatedBy: UserId, }; - - let response = await dispatch(PutOfferNew(putData)).unwrap(); if (response?.data?.statusCode === 1) { navigate(`${subDirectory}setting/productBased-offer`, { state: { Notiffy: { - messageData: response?.data?.response || 'Offer updated successfully', + messageData: + response?.data?.response || 'Offer updated successfully', messageType: 'success', }, }, @@ -1150,80 +1179,73 @@ const OfferList = ({ formType }) => { } else { message.error(response?.data?.response || 'Failed to update offer'); } - - } - - - - } - else if (formType === 'add') { - const hasTwoDates = Array.isArray(generalDateRange) && generalDateRange.length === 2 && generalDateRange[0] && generalDateRange[1]; + } else if (formType === 'add') { + const hasTwoDates = + Array.isArray(generalDateRange) && + generalDateRange.length === 2 && + generalDateRange[0] && + generalDateRange[1]; if (generalOfferType === 'bogo') { - if (BUYXGetTX?.length == 0) { - - message.error("mimimum choose one product ") - return - + message.error('mimimum choose one product '); + return; } let postData = { - "AppId": AppId, - "CompId": CompId, - "BranchId": BranchId, - "OfferName": generalOfferName, - "OfferAmt": 0, - "ValueType": null, - "OfferFrom": hasTwoDates ? generalDateRange[0] : null, - "OfferTo": hasTwoDates ? generalDateRange[1] : null, - "WeekWiseOffer": - selectedDays - , - "LimitUsage": limitUsage, - "MappingType": null, - "OfferDetails": BUYXGetTX, - CreatedBy: UserId + AppId: AppId, + CompId: CompId, + BranchId: BranchId, + OfferName: generalOfferName, + OfferAmt: 0, + ValueType: null, + OfferFrom: hasTwoDates ? generalDateRange[0] : null, + OfferTo: hasTwoDates ? generalDateRange[1] : null, + WeekWiseOffer: selectedDays, + LimitUsage: limitUsage, + MappingType: null, + OfferDetails: BUYXGetTX, + CreatedBy: UserId, }; - console.log(postData, 'postData') + console.log(postData, 'postData'); let response; response = await dispatch(PostOfferNew(postData)).unwrap(); - if (response?.data?.statusCode === 1) { - - - navigate(`${subDirectory}setting/productBased-offer`, { state: { Notiffy: { - messageData: response?.data?.response || "Offer updated successfully", - messageType: "success" + messageData: + response?.data?.response || 'Offer updated successfully', + messageType: 'success', }, }, - }); - } else { - message.error(response?.data?.response || "Failed to update offer"); + message.error(response?.data?.response || 'Failed to update offer'); } - } + } else { + if (selectedProductsNew?.length == 0 && generalOfferType != 'Sales') { + message.error('mimimum choose one product '); - else { - - if (selectedProductsNew?.length == 0 && generalOfferType != "Sales") { - - message.error("mimimum choose one product ") - - return + return; } - const offerTypeCode = generalOfferType === 'Item' ? 'I' : generalOfferType === 'Sales' ? 'S' : generalOfferType === 'Quantity' ? 'Q' : ''; - const firstNum = applyFirstValue !== '' ? Number(applyFirstValue) : null; - const secondNum = applySecondValue !== '' ? Number(applySecondValue) : null; + const offerTypeCode = + generalOfferType === 'Item' + ? 'I' + : generalOfferType === 'Sales' + ? 'S' + : generalOfferType === 'Quantity' + ? 'Q' + : ''; + const firstNum = + applyFirstValue !== '' ? Number(applyFirstValue) : null; + const secondNum = + applySecondValue !== '' ? Number(applySecondValue) : null; const defaultOfferFields = { OfferType: offerTypeCode, MinQty: offerTypeCode === 'I' ? firstNum : null, @@ -1235,76 +1257,73 @@ const OfferList = ({ formType }) => { PointType: null, }; let postData = { - "AppId": AppId, - "CompId": CompId, - "BranchId": BranchId, - "OfferName": generalOfferName, - "OfferAmt": generalDiscountValue ? Number(generalDiscountValue) : 0, - "ValueType": generalDiscountType === 'fixed' ? "F" : "P", - "OfferFrom": hasTwoDates ? generalDateRange[0] : null, - "OfferTo": hasTwoDates ? generalDateRange[1] : null, - "WeekWiseOffer": - selectedDays - , - "LimitUsage": limitUsage, - "MappingType": mappingType === 'all' ? 'A' : mappingType === 'category' ? 'C' : 'P', - OfferDetails: (offerTypeCode === 'S') ? - [{ - AmountTo: secondNum !== '' ? secondNum : 0, - AmountFrom: firstNum !== '' ? firstNum : 0, - OfferType: 'S', - - }] : (selectedProductsNew || []).map(prod => ({ - ...defaultOfferFields, - ProdCat: prod.ProdCat, - ProdId: prod.ProdId, - ProdVariantDetails: (prod.ProdVariantDetails || []).map(variant => ({ - ProdVariantName: variant.ProdVariantName, - StockDetails: (variant.StockDetails || []) - .filter(stock => stock.checked) - .map(stock => ({ - InwardDtlId: stock.InwardDtlId - })) - })), - FreeProductDetails: [] - })), - CreatedBy: UserId + AppId: AppId, + CompId: CompId, + BranchId: BranchId, + OfferName: generalOfferName, + OfferAmt: generalDiscountValue ? Number(generalDiscountValue) : 0, + ValueType: generalDiscountType === 'fixed' ? 'F' : 'P', + OfferFrom: hasTwoDates ? generalDateRange[0] : null, + OfferTo: hasTwoDates ? generalDateRange[1] : null, + WeekWiseOffer: selectedDays, + LimitUsage: limitUsage, + MappingType: + mappingType === 'all' + ? 'A' + : mappingType === 'category' + ? 'C' + : 'P', + OfferDetails: + offerTypeCode === 'S' + ? [ + { + AmountTo: secondNum !== '' ? secondNum : 0, + AmountFrom: firstNum !== '' ? firstNum : 0, + OfferType: 'S', + }, + ] + : (selectedProductsNew || []).map((prod) => ({ + ...defaultOfferFields, + ProdCat: prod.ProdCat, + ProdId: prod.ProdId, + ProdVariantDetails: (prod.ProdVariantDetails || []).map( + (variant) => ({ + ProdVariantName: variant.ProdVariantName, + StockDetails: (variant.StockDetails || []) + .filter((stock) => stock.checked) + .map((stock) => ({ + InwardDtlId: stock.InwardDtlId, + })), + }) + ), + FreeProductDetails: [], + })), + CreatedBy: UserId, }; - let response; - console.log(postData, "postData") + console.log(postData, 'postData'); response = await dispatch(PostOfferNew(postData)).unwrap(); - if (response?.data?.statusCode === 1) { - - - navigate(`${subDirectory}setting/productBased-offer`, { state: { Notiffy: { - messageData: response?.data?.response || "Offer updated successfully", - messageType: "success" + messageData: + response?.data?.response || 'Offer updated successfully', + messageType: 'success', }, }, - }); - } else { - message.error(response?.data?.response || "Failed to update offer"); + message.error(response?.data?.response || 'Failed to update offer'); } - } - } - // console.log(postData, "postData") // setNewOffer(false); - - }; const BacktoList = () => { @@ -1312,7 +1331,7 @@ const OfferList = ({ formType }) => { }; return ( <> -
+
{/*
navigate('/app-page/home')} className="breadcrumb-item"> Dashboard @@ -1333,7 +1352,6 @@ const OfferList = ({ formType }) => {

Product Offers

-
{/* {newOffer && ( */} @@ -1341,7 +1359,7 @@ const OfferList = ({ formType }) => {
{ }} >
- -
- - - +
{ { required: true, message: 'Please Enter OfferName', - } - + }, ]} >
- +
{ placeholder="Enter Offer Name" className="limit-usage-input" value={generalOfferName} - onChange={e => setGeneralOfferName(e.target.value)} + onChange={(e) => setGeneralOfferName(e.target.value)} />
-
{ { required: true, message: 'OfferType is required', - } - + }, ]} >
- +
{ setGeneralOfferType(value); formRef.current?.setFieldsValue({ OfferType: value }) }} + onChangeFunction={(value) => { + setGeneralOfferType(value); + formRef.current?.setFieldsValue({ + OfferType: value, + }); + }} placeholder="Select Offer Type" style={{ flex: 1 }} - disabled={formType === "edit" && editstate ? true : false} + disabled={ + formType === 'edit' && editstate ? true : false + } />
- {generalOfferType != "bogo" &&
- -
-
- -
+ {generalOfferType != 'bogo' && ( +
+ +
+
+
{ - setGeneralDiscountType('fixed'); - setGeneralDiscountValue(''); - formRef.current.resetFields(['discount-type']); - }} + className="tab-buttons" + style={{ display: 'flex', gap: 8 }} > - Fixed +
{ + setGeneralDiscountType('fixed'); + setGeneralDiscountValue(''); + formRef.current.resetFields([ + 'discount-type', + ]); + }} + > + Fixed +
+ + {/* Percentage Tab */} +
{ + setGeneralDiscountType('percentage'); + setGeneralDiscountValue(''); + formRef.current.resetFields([ + 'discount-type', + ]); + }} + > + Percentage +
- {/* Percentage Tab */} + {/* Input with symbol */}
{ - setGeneralDiscountType('percentage'); - setGeneralDiscountValue(''); - formRef.current.resetFields(['discount-type']); + position: 'relative', + display: 'inline-block', + width: 150, }} > - Percentage + + {generalDiscountType === 'fixed' + ? '₹' + : generalDiscountType === 'percentage' + ? '%' + : ''} + + { + let val = parseFloat(e.target.value); + if ( + generalDiscountType === 'percentage' && + val > 100 + ) + val = 100; + setGeneralDiscountValue( + isNaN(val) ? '' : val + ); + }} + style={{ + paddingLeft: 25, // make space for symbol + }} + />
- - {/* Input with symbol */} -
- - {generalDiscountType === 'fixed' ? '₹' : generalDiscountType === 'percentage' ? '%' : ''} - - { - let val = parseFloat(e.target.value); - if (generalDiscountType === 'percentage' && val > 100) val = 100; - setGeneralDiscountValue(isNaN(val) ? '' : val); - }} - style={{ - paddingLeft: 25, // make space for symbol - }} - /> -
+
+
+ )} -
- -
} - - - - {generalOfferType != "bogo" &&
-
- -
- - -
- - setApplyFirstValue(e.target.value.replace(/[^0-9.]/g, ''))} - /> -
-
- - -
- - setApplySecondValue(e.target.value.replace(/[^0-9.]/g, ''))} - /> -
-
+ {generalOfferType != 'bogo' && ( +
+
+ +
+ +
+ + + setApplyFirstValue( + e.target.value.replace(/[^0-9.]/g, '') + ) + } + /> +
+
+ +
+ + + setApplySecondValue( + e.target.value.replace(/[^0-9.]/g, '') + ) + } + /> +
+
+
-
} + )} - -
+
-
+
{ cursor: 'pointer', padding: '6px 18px', borderRadius: 6, - border: generalOfferSchedule === 'date' ? '1.5px solid #2563EA' : '1.5px solid #e5e7eb', - background: generalOfferSchedule === 'date' ? '#2563EA' : '#fff', - color: generalOfferSchedule === 'date' ? '#fff' : '#222', + border: + generalOfferSchedule === 'date' + ? '1.5px solid #2563EA' + : '1.5px solid #e5e7eb', + background: + generalOfferSchedule === 'date' + ? '#2563EA' + : '#fff', + color: + generalOfferSchedule === 'date' ? '#fff' : '#222', fontWeight: 500, transition: 'all 0.2s', userSelect: 'none', @@ -1600,22 +1717,55 @@ const OfferList = ({ formType }) => {
{ if (selectedDays.length === 7) { setSelectedDays([]); } else { - setSelectedDays(['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']); + setSelectedDays([ + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday', + ]); } }} - title={selectedDays.length === 7 ? 'Unselect All Days' : 'Select All Days'} + title={ + selectedDays.length === 7 + ? 'Unselect All Days' + : 'Select All Days' + } > - {selectedDays.length === 7 ? 'Unselect All' : 'Select All'} + {selectedDays.length === 7 + ? 'Unselect All' + : 'Select All'}
- {['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'].map((day) => ( + {[ + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday', + ].map((day) => (
-
+
- + { placeholder="Enter limit usage (e.g., 10)" className="limit-usage-input" value={limitUsage} - onChange={e => setLimitUsage(e.target.value.replace(/[^0-9]/g, ""))} + onChange={(e) => + setLimitUsage(e.target.value.replace(/[^0-9]/g, '')) + } />
-
- - -
-
+
{/*
{ setMappingModalOpen((prev) => !prev) }}> Mapping
*/} - {(generalOfferType != "Sales" && generalOfferType != 'bogo') ? -
- -
+ {generalOfferType != 'Sales' && generalOfferType != 'bogo' ? ( +
+
0} // all products selected + checked={ + selectedProductsNew.length === Prods.length && + Prods.length > 0 + } // all products selected onChange={(e) => { const isChecked = e.target.checked; setActive(isChecked ? 'all' : ''); @@ -1752,19 +1953,19 @@ const OfferList = ({ formType }) => { All Products
-
{ - setActive("category"); + setActive('category'); setMappingModalOpen(true); - setMappingType("category"); + setMappingType('category'); }} style={{ - padding: "6px 12px", - borderRadius: "6px", - cursor: "pointer", - backgroundColor: active === "category" ? "#007bff" : "#f0f0f0", - color: active === "category" ? "#fff" : "#333", + padding: '6px 12px', + borderRadius: '6px', + cursor: 'pointer', + backgroundColor: + active === 'category' ? '#007bff' : '#f0f0f0', + color: active === 'category' ? '#fff' : '#333', }} > Category {selectedCategories.length} @@ -1772,24 +1973,32 @@ const OfferList = ({ formType }) => {
{ - setActive("product"); + setActive('product'); setMappingModalOpen(true); - setMappingType("product"); + setMappingType('product'); }} style={{ - padding: "6px 12px", - borderRadius: "6px", - cursor: "pointer", - backgroundColor: active === "product" ? "#007bff" : "#f0f0f0", - color: active === "product" ? "#fff" : "#333", + padding: '6px 12px', + borderRadius: '6px', + cursor: 'pointer', + backgroundColor: + active === 'product' ? '#007bff' : '#f0f0f0', + color: active === 'product' ? '#fff' : '#333', }} > - Product {selectedProductsNew?.filter((e) => e?.ActiveStatus == "A")?.length} + Product{' '} + { + selectedProductsNew?.filter( + (e) => e?.ActiveStatus == 'A' + )?.length + }
-
:
} +
+ ) : ( +
+ )} {generalOfferType === 'bogo' && (
-
{/* Buy Product */}
@@ -1803,36 +2012,69 @@ const OfferList = ({ formType }) => { ))} */} -
+
- + { - const product = Prods.find(p => p.ProdId === option.value); - const nameMatch = option.label?.toLowerCase().includes(productSearchText?.toLowerCase()); - const qrMatch = product?.QrCode?.toLowerCase() === productSearchText?.toLowerCase(); + const product = Prods.find( + (p) => p.ProdId === option.value + ); + const nameMatch = option.label + ?.toLowerCase() + .includes( + productSearchText?.toLowerCase() + ); + const qrMatch = + product?.QrCode?.toLowerCase() === + productSearchText?.toLowerCase(); return nameMatch || qrMatch; }} - options={!scanner.BUY ? Prods?.map - ((option) => ({ - value: option.ProdId, - label: `${option.ProdName} ` - })) : []} - onSelect={(ProdId, option) => ProductDropDownChange(ProdId, option, "buy")} - onChange={(value) => handleProductSearch(value, null, "buy")} + options={ + !scanner.BUY + ? Prods?.map((option) => ({ + value: option.ProdId, + label: `${option.ProdName} `, + })) + : [] + } + onSelect={(ProdId, option) => + ProductDropDownChange(ProdId, option, 'buy') + } + onChange={(value) => + handleProductSearch(value, null, 'buy') + } onKeyDown={(e) => { - if (scanner.BUY && e.key === "Enter") { + if (scanner.BUY && e.key === 'Enter') { e.preventDefault(); } }} - style={{ width: "250px" }} - disabled={editStateInside}> - + style={{ width: '250px' }} + disabled={editStateInside} + > - - { handleScanSearch("buy") }} /> + + { + handleScanSearch('buy'); + }} + />
{/* { min="1" placeholder="Qty" value={bogoBuyQuantity} - onChange={e => setBogoBuyQuantity(e.target.value.replace(/[^0-9]/g, ''))} + onChange={(e) => + setBogoBuyQuantity( + e.target.value.replace(/[^0-9]/g, '') + ) + } />
@@ -1865,8 +2111,7 @@ const OfferList = ({ formType }) => { {/* Free Product */}
-
- +
{/* ({ value: option?.ProdId, @@ -1883,38 +2128,70 @@ const OfferList = ({ formType }) => { /> */}
- + { - const product = Prods.find(p => p.ProdId === option.value); - const nameMatch = option.label?.toLowerCase().includes(input.toLowerCase()); - const qrMatch = product?.QrCode?.toLowerCase() === input.toLowerCase(); + const product = Prods.find( + (p) => p.ProdId === option.value + ); + const nameMatch = option.label + ?.toLowerCase() + .includes(input.toLowerCase()); + const qrMatch = + product?.QrCode?.toLowerCase() === + input.toLowerCase(); return nameMatch || qrMatch; }} options={ !scanner.FREE - ? Prods?.map(option => ({ - value: option.ProdId, - label: option.ProdName, - })) + ? Prods?.map((option) => ({ + value: option.ProdId, + label: option.ProdName, + })) : [] } - onSelect={(ProdId, option) => ProductDropDownChange(ProdId, option, "free")} - onChange={(value) => handleProductSearch(value, null, "free")} - onKeyDown={e => { - if (scanner.FREE && e.key === "Enter") { + onSelect={(ProdId, option) => + ProductDropDownChange( + ProdId, + option, + 'free' + ) + } + onChange={(value) => + handleProductSearch(value, null, 'free') + } + onKeyDown={(e) => { + if (scanner.FREE && e.key === 'Enter') { e.preventDefault(); } }} - style={{ width: "250px" }} + style={{ width: '250px' }} disabled={editStateInside} /> - - { handleScanSearch("free") }} /> + + { + handleScanSearch('free'); + }} + />
@@ -1924,17 +2201,27 @@ const OfferList = ({ formType }) => { min="1" placeholder="Qty" value={bogoFreeQuantity} - onChange={e => setBogoFreeQuantity(e.target.value.replace(/[^0-9]/g, ''))} + onChange={(e) => + setBogoFreeQuantity( + e.target.value.replace(/[^0-9]/g, '') + ) + } />
-
- {/* Add Button */} -
BogoFreeAddFn(bogoBuyProduct.prodId, bogoFreeProduct.prodId)}> -
+
+ BogoFreeAddFn( + bogoBuyProduct.prodId, + bogoFreeProduct.prodId + ) + } + > +
@@ -1943,47 +2230,42 @@ const OfferList = ({ formType }) => { columns={Columns} data={BUYXGetTX} dataSource={BUYXGetTX} - />
)} - - - - - - -
-
Cancel
- +
+ {' '} + Cancel +
+
- - setMappingModalOpen(false)} - - className={"OfferListModal"} + className={'OfferListModal'} >
@@ -2003,64 +2285,146 @@ const OfferList = ({ formType }) => { {mappingType === 'category' && (
-
- +
+
- - - - + + + {category?.map((cat, idx) => ( - - - - + + ))}
SelectSL.NOCategory Name + Select + + SL.NO + + Category Name +
+ { + onChange={(e) => { if (e.target.checked) { // ✅ add category to selectedCategories - setSelectedCategories([...selectedCategories, cat.ProdCat]); + setSelectedCategories([ + ...selectedCategories, + cat.ProdCat, + ]); // ✅ also add all products of that category handleCategoryClick(cat.ProdCat, true); } else { // ❌ remove category from selectedCategories - setSelectedCategories(selectedCategories.filter(c => c !== cat.ProdCat)); + setSelectedCategories( + selectedCategories.filter( + (c) => c !== cat.ProdCat + ) + ); // ❌ also remove all products of that category handleCategoryClick(cat.ProdCat, false); } }} /> - {idx + 1}{cat.ProdCatName} + {idx + 1} + + {cat.ProdCatName} +
-
)} {mappingType === 'product' && (
-
+
setProductSearch(e.target.value)} - style={{ padding: '6px 12px', borderRadius: 5, border: '1px solid #ccc', fontSize: 14, width: 220 }} + onChange={(e) => setProductSearch(e.target.value)} + style={{ + padding: '6px 12px', + borderRadius: 5, + border: '1px solid #ccc', + fontSize: 14, + width: 220, + }} />
setShowStockInfo(!showStockInfo)} > {showStockInfo ? 'Hide Stock Info' : 'Show Stock Info'} @@ -2069,43 +2433,43 @@ const OfferList = ({ formType }) => {
- + - - - {/* Product checkbox */} - {showStockInfo && ( )} @@ -2304,12 +2707,17 @@ const OfferList = ({ formType }) => {
Select SL.NO Product Name @@ -2114,9 +2478,9 @@ const OfferList = ({ formType }) => { {showStockInfo && ( Stock @@ -2131,24 +2495,24 @@ const OfferList = ({ formType }) => { (prod) => !productSearch || (prod.ProdName && - prod.ProdName - .toLowerCase() - .includes(productSearch.toLowerCase())) + prod.ProdName.toLowerCase().includes( + productSearch.toLowerCase() + )) ) .map((prod, idx) => { const selectedProd = selectedProductsNew.find( (p) => p.ProdId === prod.ProdId ); - const isProductChecked = selectedProd?.checked || false; + const isProductChecked = + selectedProd?.checked || false; return (
{/* PRODUCT CHECKBOX */} @@ -2156,145 +2520,184 @@ const OfferList = ({ formType }) => { type="checkbox" checked={isProductChecked} onChange={(e) => { - handleProductClick(prod, { isChecked: e.target.checked }); + handleProductClick(prod, { + isChecked: e.target.checked, + }); }} /> - + {idx + 1} + {prod.ProdName} {prod.ProdVariantDetails?.length > 0 ? ( - prod.ProdVariantDetails.map((variant, vIdx) => ( -
+ prod.ProdVariantDetails.map( + (variant, vIdx) => (
- - {variant.ProdVariantName}: - -
- {variant.StockDetails?.length > 0 ? ( - variant.StockDetails.map((stock, sIdx) => { - const isStockChecked = - selectedProd?.ProdVariantDetails.find( - (v) => - v.ProdVariantName === - variant.ProdVariantName - ) - ?.StockDetails.find( - (s) => - s.InwardDtlId === stock.InwardDtlId - )?.checked || false; + + {variant.ProdVariantName}: + - return ( - - ); - }) - ) : ( - - No Stock - - )} +
+ {variant.StockDetails?.length > + 0 ? ( + variant.StockDetails.map( + (stock, sIdx) => { + const isStockChecked = + selectedProd?.ProdVariantDetails.find( + (v) => + v.ProdVariantName === + variant.ProdVariantName + )?.StockDetails.find( + (s) => + s.InwardDtlId === + stock.InwardDtlId + )?.checked || false; + + return ( + + ); + } + ) + ) : ( + + No Stock + + )} +
-
- {vIdx !== prod.ProdVariantDetails.length - 1 && ( -
- )} -
- )) + {vIdx !== + prod.ProdVariantDetails.length - + 1 && ( +
+ )} + + ) + ) ) : ( - No Variants + + No Variants + )}
-
)} - -
+
{ open={BuyXGETX.modal} width={800} footer={null} - handleCancel={() => dispatchBuyXGETX({ type: "Reset" })} + handleCancel={() => dispatchBuyXGETX({ type: 'Reset' })} className="OfferListModal" - title={"Stock Mapping"} + title={'Stock Mapping'} >
{BuyXGETX?.Prodvariant?.map((variant, variantIndex) => ( -
-
+
+
{variant?.ProdVariantName || variant?.FreeProdVariantName}
{variant?.StockDetails?.map((stock, stockIndex) => ( -
+
{ const isChecked = ev.target.checked; if (!isChecked) { // Count all active stocks across all variants - const totalActiveStocks = BuyXGETX?.Prodvariant?.reduce( - (count, v) => - count + - (v.StockDetails?.filter((sd) => sd.ActiveStatus === "A") - .length || 0), - 0 - ); + const totalActiveStocks = + BuyXGETX?.Prodvariant?.reduce( + (count, v) => + count + + (v.StockDetails?.filter( + (sd) => sd.ActiveStatus === 'A' + ).length || 0), + 0 + ); if (totalActiveStocks <= 1) { alert( - "At least one stock must remain active across all variants!" + 'At least one stock must remain active across all variants!' ); return; } } dispatchBuyXGETX({ - type: "TOGGLE_ACTIVE_STATUS", + type: 'TOGGLE_ACTIVE_STATUS', payload: { prodVariantIndex: variantIndex, stockIndex: stockIndex, @@ -2408,53 +2824,59 @@ const OfferList = ({ formType }) => {
{ setBUYXGetTX((prev) => prev.map((item) => { if (item.ProdId !== BuyXGETX.ProdId) return item; - if (BuyXGETX.type === "BUY") { - return { ...item, ProdVariantDetails: BuyXGETX.Prodvariant }; + if (BuyXGETX.type === 'BUY') { + return { + ...item, + ProdVariantDetails: BuyXGETX.Prodvariant, + }; } - if (BuyXGETX.type === "FREE") { + if (BuyXGETX.type === 'FREE') { const updatedFreeDetails = item.FreeProductDetails?.[0] ? [ - { - ...item.FreeProductDetails[0], - ProdVariantDetails: BuyXGETX.Prodvariant, - }, - ] + { + ...item.FreeProductDetails[0], + ProdVariantDetails: BuyXGETX.Prodvariant, + }, + ] : [{ ProdVariantDetails: BuyXGETX.Prodvariant }]; - return { ...item, FreeProductDetails: updatedFreeDetails }; + return { + ...item, + FreeProductDetails: updatedFreeDetails, + }; } return item; }) ); - dispatchBuyXGETX({ type: "Reset" }); + dispatchBuyXGETX({ type: 'Reset' }); }} > Save @@ -2462,11 +2884,9 @@ const OfferList = ({ formType }) => {
- -
); }; -export default OfferList; \ No newline at end of file +export default OfferList; diff --git a/src/Pages/Offer/Offer/OfferList.scss b/src/Pages/Offer/Offer/OfferList.scss index 7ec53a4..5751a44 100644 --- a/src/Pages/Offer/Offer/OfferList.scss +++ b/src/Pages/Offer/Offer/OfferList.scss @@ -200,7 +200,7 @@ // width: 550px; } -.content-section { +.contentsection { h2 { margin: 0 0 16px 0; font-size: 20px; @@ -484,8 +484,6 @@ margin-top: 10px; grid-column: 1 / -1; background-color: #fff; - border: 1px solid #bbbbbb80; - padding: 10px 10px; border-radius: 10px; width: 100%; @@ -1578,7 +1576,6 @@ /* elegant dark gray text */ transition: all 0.25s ease; /* smooth hover effect */ - } // Limit Usage section @@ -1923,4 +1920,4 @@ background-color: #f3f3f3; padding: 6px 16px; border-radius: 6px; -} \ No newline at end of file +}