Merge pull request 'Fix 14: multiple-search-product' (#15) from 14-multiple-search-product into main

Reviewed-on: Pozomind/pozo-retail-app#15
This commit is contained in:
karthikalakshmi 2026-01-29 00:17:49 -05:00
commit 06075caca4
9 changed files with 328 additions and 10 deletions

View File

@ -1460,6 +1460,23 @@ export const CustomerOrderList = createAsyncThunk(
}
);
// post /ProductSearch
export const PostProductSearch = createAsyncThunk(
'multipleSearch/ProductSearch',
async (postData) => {
return await axiosRetailInstanceData.post(`/ProductSearch`, postData);
}
);
// get /GetProductSearch
export const getmultipleSearch = createAsyncThunk(
'multipleSearch/GetProductSearch',
async (data) => {
return await axiosRetailInstanceData.get(
`/GetProductSearch?compId=${data?.CompId}&branchId=${data?.BranchId}&appId=${data?.AppId}`
);
}
);
const initialState = {

View File

@ -108,6 +108,7 @@ import { BiSolidPhoneCall } from 'react-icons/bi';
import { PiSignOutLight } from 'react-icons/pi';
import PozoSwapIcon from '../UtillComponents/Pozo retail icons/PozoSwapIcon.jsx';
import { MdEdit } from 'react-icons/md';
import { CgSearchLoading } from "react-icons/cg";
import UserRelieveManager from '../../Template/RealivingUser.jsx';
import user from '../../../../Images/dashboard/user.jpg';
import BSNavBarUserInfo from './BSNavBarUserInfo';
@ -119,6 +120,8 @@ import BSScanTemplate from '../UtillComponents/BSScanTemplate.jsx';
import VerfiedProducts from './verfiedProduct/VerfiedProducts.jsx';
import BSMembership from '../UtillComponents/BSMembership.jsx';
import BranchName from '../../Template/BranchName.jsx';
import MultipleSearch from '../UtillComponents/MultipleSearch.jsx';
import { DefaultModal } from '../../../../Components/Modal/DefaultModal.jsx';
const subDirectory = import.meta.env.ENV_BASE_URL;
const commonUrl = import.meta.env.ENV_COMMON_BASE_URL;
@ -133,6 +136,7 @@ const BSNavbar1 = (props) => {
const [paymentfeataddon, setpaymentfeataddon] = useState(false);
const [addcustomer, setAddCustomer] = useState(false);
const [hold, setHold] = useState(false);
const [multiple, setMultiple] = useState(false);
const BSLayout1Data = useSelector(getTemplateData);
const navbarOptions = BSLayout1Data?.BookingNavbar?.[1];
const PreferenceDatas = useSelector(PreferenceData);
@ -634,6 +638,16 @@ const BSNavbar1 = (props) => {
position: 'relative',
}}
>
{/* Multiple search */}
<Tooltip title={'Multiple Search'}>
<div className='MultiSearchIconDiv'>
<CgSearchLoading onClick={() => setMultiple(true)} />
</div>
</Tooltip>
{!OtherServicesglobal && (
<>
{navbarOptions?.map((item) => (
@ -1292,6 +1306,22 @@ const BSNavbar1 = (props) => {
<PozoMenuIcon size={20} />
)}
</div>
<DefaultModal
open={multiple}
title="Multiple Search"
footer={false}
width={350}
handleCancel={() => setMultiple(false)}
destroyOnClose={true}
children={
<>
<MultipleSearch
close={setMultiple}
/>
</>
}
/>
</div>
);
};

View File

@ -103,7 +103,7 @@ import {
import { FaUserLarge } from 'react-icons/fa6';
import { BiSolidPhoneCall } from 'react-icons/bi';
import PozoSwapIcon from '../UtillComponents/Pozo retail icons/PozoSwapIcon.jsx';
import { MdEdit } from 'react-icons/md';
import { CgSearchLoading } from "react-icons/cg";
import UserRelieveManager from '../../Template/RealivingUser.jsx';
import { FaParking } from 'react-icons/fa';
import BSNavBarUserInfo from './BSNavBarUserInfo';
@ -113,6 +113,8 @@ import BSMobilePrintSettings from '../UtillComponents/BSMobilePrintSettings.jsx'
import BSScanTemplate from '../UtillComponents/BSScanTemplate.jsx';
import VerfiedProducts from './verfiedProduct/VerfiedProducts';
import BranchName from '../../Template/BranchName.jsx';
import MultipleSearch from '../UtillComponents/MultipleSearch.jsx';
import { DefaultModal } from '../../../../Components/Modal/DefaultModal.jsx';
const subDirectory = import.meta.env.ENV_BASE_URL;
const commonUrl = import.meta.env.ENV_COMMON_BASE_URL;
@ -203,6 +205,7 @@ const BSNavbar2 = () => {
const { SadminuserAccess } = useAuth();
const [OtherServiceStatus, setOtherServiceStatus] = useState(false);
const [isHoldEnable, setisisHoldEnable] = useState(false);
const [multiple, setMultiple] = useState(false);
let SAAccessCommonMaster = SadminuserAccess?.find(
(e) => e?.MenuName === 'Sales'
);
@ -610,7 +613,12 @@ const BSNavbar2 = () => {
</div>
)}
</div>
{/* Multiple search */}
<Tooltip title={'Multiple Search'}>
<div className='MultiSearchIconDiv2'>
<CgSearchLoading onClick={() => setMultiple(true)} />
</div>
</Tooltip>
<div className="BSBillingNav2div2">
{searchOption &&
!Comboglobal &&
@ -1305,6 +1313,22 @@ const BSNavbar2 = () => {
<div className="BSBillingnav2-threedots" onClick={NavmenuOpenClose}>
<MenuOutlined />
</div>
<DefaultModal
open={multiple}
title="Multiple Search"
footer={false}
width={350}
handleCancel={() => setMultiple(false)}
destroyOnClose={true}
children={
<>
<MultipleSearch
close={setMultiple}
/>
</>
}
/>
</div>
);
};

View File

@ -122,6 +122,9 @@ import BSNavBarWholeSale from '../UtillComponents/BSNavBarWholeSale.jsx';
import { Global_OfferStatus } from '../../../../Features/Offer/Offer.js';
import { globalholddata } from '../../../../Features/BookingScreen/HoldOption/HoldOption.js';
import BSNavBarWeightScale from '../UtillComponents/BSNavBarWeightScale.jsx';
import { CgSearchLoading } from "react-icons/cg";
import { DefaultModal } from '../../../../Components/Modal/DefaultModal.jsx';
import MultipleSearch from '../UtillComponents/MultipleSearch.jsx';
const subDirectory = import.meta.env.ENV_BASE_URL;
const commonUrl = import.meta.env.ENV_COMMON_BASE_URL;
@ -154,6 +157,7 @@ const BSNavbar3 = ({ optionNames }) => {
const [quickAdd, setQuickAdd] = useState(false);
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const [isFullscreen, setIsFullscreen] = useState(false);
const [multiple, setMultiple] = useState(false);
const GlobEstBooking = useSelector(GlobalEstimateBooking);
const compBranchData = useSelector(GlobalCompBranchData);
const userProfileData = useSelector(userDataByUserId);
@ -598,6 +602,12 @@ const BSNavbar3 = ({ optionNames }) => {
)}
</div>
{/* Multiple search */}
<Tooltip title={'Multiple Search'}>
<div className='MultiSearchIconDiv3'>
<CgSearchLoading onClick={() => setMultiple(true)} />
</div>
</Tooltip>
{!sportsAppPreference && searchOption && (
<div
className="BsnavbarSearchMain"
@ -1165,6 +1175,22 @@ const BSNavbar3 = ({ optionNames }) => {
</div>
</div>
</div>
<DefaultModal
open={multiple}
title="Multiple Search"
footer={false}
width={350}
handleCancel={() => setMultiple(false)}
destroyOnClose={true}
children={
<>
<MultipleSearch
close={setMultiple}
/>
</>
}
/>
{quickAdd && (
<FeaturesFunctionalities
handleQuickAddCancel={handleQuickAddClose}

View File

@ -0,0 +1,126 @@
import React, { useEffect, useState } from "react";
import { getSession } from "../../../../Services/Others";
import { useDispatch } from "react-redux";
import { getmultipleSearch, PostProductSearch } from "../../../../Features/BookingScreen/BookingData/BookingData";
import Buttons from "../../../../Components/Forms/Buttons";
const MultipleSearch = ({ close }) => {
const CompId = getSession("CompId");
const BranchId = getSession("BranchId");
const AppId = getSession("AppId");
const dispatch = useDispatch();
const options = [
{ label: "Product Name", value: "ProdName" },
{ label: "Product Variant Name", value: "ProdVariantName" },
// { label: "Product ID", value: "ProdId" },
{ label: "One Piece QR", value: "OnePcQR" },
{ label: "QR Code", value: "QrCode" },
{ label: "Product Name Code", value: "ProdNameCode" },
{ label: "Category Name", value: "CategoryName" },
{ label: "Sub Category Name", value: "SubCategoryName" },
{ label: "Brand Name", value: "BrandName" },
];
const [selectedValues, setSelectedValues] = useState([]);
console.log(selectedValues, 'selectedValuesselectedValues');
useEffect(() => {
GetmultipleSearchData();
}, []);
const postMultipleSearch = async () => {
if (selectedValues.length === 0) {
alert("Please select at least one option!");
return;
}
const data = {
CompId: CompId,
BranchId: BranchId,
AppId: AppId,
SearchTerms: selectedValues,
};
try {
const response = await dispatch(PostProductSearch(data)).unwrap();
console.log("Search Response:", response);
if (response?.data?.statusCode == 1) {
setSelectedValues('')
close(false);
}
} catch (error) {
console.error("Search Error:", error);
}
};
const GetmultipleSearchData = async () => {
const data = {
AppId,
CompId,
BranchId,
};
try {
const response = await dispatch(getmultipleSearch(data)).unwrap();
if (response?.data?.statusCode === 1) {
const selected = response?.data?.data?.[0]?.SearchTermDtl?.map(
(item) => item?.SearchTerm
) || [];
setSelectedValues(selected);
}
} catch (error) {
console.error("Get Search Terms Error:", error);
}
};
return (
<>
<div>
{options.map((item) => (
<label
key={item.value}
style={{
display: "block",
marginBottom: "6px",
cursor: "pointer",
fontSize: "14px",
color: "#333",
}}
>
<input
type="checkbox"
checked={selectedValues.includes(item.value)}
onChange={() => {
setSelectedValues((prev) =>
prev.includes(item.value)
? prev.filter((i) => i !== item.value)
: [...prev, item.value]
);
}}
style={{ marginRight: "8px" }}
/>
{item.label}
</label>
))}
</div>
<div>
<Buttons
buttonText={'Submit'}
handleSubmit={postMultipleSearch}
color="901D77"
// icon={<PlusOutlined />}
/>
</div>
</>
);
};
export default MultipleSearch;

View File

@ -67,6 +67,9 @@ import BSExpireProductsList from '../../Components/UtillComponents/BSExpireProdu
import ComboSalesBillTable from '../../Components/BSBillingTables/ComboSalesBillTable/ComboSalesBillTable.jsx';
import { GiBasket } from 'react-icons/gi';
import { FaRegKeyboard } from 'react-icons/fa';
import { CgSearchLoading } from "react-icons/cg";
import { DefaultModal } from '../../../../Components/Modal/DefaultModal.jsx';
import MultipleSearch from '../../Components/UtillComponents/MultipleSearch.jsx';
const subDirectory = import.meta.env.BASE_URL;
const commonDirectory = import.meta.env.COMMON_BASE_URL;
@ -106,6 +109,7 @@ export default function BSCombo1() {
const [count, setcount] = useState(0);
const [messageType, setMessageType] = useState(null);
const [messageData, setMessageData] = useState(null);
const [multiple, setMultiple] = useState(false);
const BookingBilling = BSComboData?.BookingBilling?.[0];
const DineInAccess = SettingDataSelector?.[0]?.SettingDtlDetails.filter(
(i) => i.SettingIdName === 'DineIn'
@ -351,6 +355,13 @@ export default function BSCombo1() {
<div className="SearchSubnavbar-combo">
<BSC1NavBar data={BSComboData} SessionData={SessionData} />
<div className="comboNavbarSubMain">
{/* Multiple search */}
<Tooltip title={'Multiple Search'}>
<div className='MultiSearchIconDiv'>
<CgSearchLoading onClick={() => setMultiple(true)} />
</div>
</Tooltip>
{Comboglobal === false && (
<BSC1Search
data={BSComboData?.BookingLayout[0]}
@ -592,6 +603,21 @@ export default function BSCombo1() {
handleInvoiceClose={handleInvoiceClose}
/>
)}
<DefaultModal
open={multiple}
title="Multiple Search"
footer={false}
width={350}
handleCancel={() => setMultiple(false)}
destroyOnClose={true}
children={
<>
<MultipleSearch
close={setMultiple}
/>
</>
}
/>
</>
);
}

View File

@ -484,3 +484,26 @@
.DisableIcon {
pointer-events: none;
}
.MultiSearchIconDiv {
background-color: #1292ee;
color: #fff !important;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
width: 35px !important;
height: 35px;
padding: 6px;
svg {
font-size: 22px;
width: 35px !important;
height: 35px;
display: flex;
}
}

View File

@ -397,3 +397,26 @@
left: 11px;
top: 10px;
}
.MultiSearchIconDiv2 {
background-color: #1292ee;
color: #ffffff !important;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
width: 32px !important;
height: 32px;
padding: 4px;
svg {
font-size: 22px;
width: 32px !important;
height: 32px;
display: flex;
}
}

View File

@ -569,9 +569,9 @@
);
background-size: 300% 300%;
animation: rainbowBorder 5s linear infinite;
-webkit-mask:
linear-gradient(#fff 0 0) content-box,
linear-gradient(#fff 0 0);
// -webkit-mask:
// linear-gradient(#fff 0 0) content-box,
// linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
@ -679,11 +679,11 @@
}
}
.BSCategory2New {
// position: absolute;
// bottom: -50%;
// height: 0 !important;
}
// .BSCategory2New {
// // position: absolute;
// // bottom: -50%;
// // height: 0 !important;
// }
.ant-tooltip {
display: none !important;
@ -734,3 +734,26 @@
color: #fff;
cursor: pointer;
}
.MultiSearchIconDiv3 {
background-color: #ffffff;
color: #1292ee !important;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
width: 32px !important;
height: 32px;
padding: 4px;
svg {
font-size: 22px;
width: 32px !important;
height: 32px;
display: flex;
}
}