Merge pull request 'tax, layout card, access based menu warehouse bug fix' (#310) from bug-fix-250326 into main

Reviewed-on: Pozomind/pozo-retail-app#310
This commit is contained in:
karthikalakshmi 2026-03-25 14:54:56 +05:30
commit 4f3cc45eb7
6 changed files with 95 additions and 189 deletions

View File

@ -26,7 +26,6 @@ import useSubscriptionManager from './useSubscriptionManager.js';
import useSessionManager from './useSessionManager.js'; import useSessionManager from './useSessionManager.js';
import ExtendSubscriptionModal from './Pages/ExtentedModal/ExtendSubscriptionModal.jsx'; import ExtendSubscriptionModal from './Pages/ExtentedModal/ExtendSubscriptionModal.jsx';
import devtools from 'devtools-detect'; import devtools from 'devtools-detect';
import { useDevToolsDetection } from './utils/useDevToolsDetection.js';
const isCapacitor = () => !!window.Capacitor?.isNativePlatform?.(); const isCapacitor = () => !!window.Capacitor?.isNativePlatform?.();
@ -172,66 +171,46 @@ const AppRoutes = () => {
}; };
}, [navigate, location.pathname, location.search]); }, [navigate, location.pathname, location.search]);
// mohan // mohan
// useEffect(() => { useEffect(() => {
// if (isMobile || isIOS) { if (isMobile || isIOS) {
// console.log('📱 Mobile/iOS device skipping DevTools detection'); console.log('📱 Mobile/iOS device → skipping DevTools detection');
// return; return;
// } }
// const checkDevTools = setInterval(() => { const checkDevTools = setInterval(() => {
// if (devtools.isOpen && !devToolsOpen) { if (devtools.isOpen && !devToolsOpen) {
// setDevToolsOpen(true); setDevToolsOpen(true);
// document.body.innerHTML = document.body.innerHTML =
// "<h1 style='color: red; text-align: center;'>Close Inspect to continue using the application.</h1>"; "<h1 style='color: red; text-align: center;'>Close Inspect to continue using the application.</h1>";
// } else if (!devtools.isOpen && devToolsOpen) { } else if (!devtools.isOpen && devToolsOpen) {
// setDevToolsOpen(false); setDevToolsOpen(false);
// setTimeout(() => { setTimeout(() => {
// window.location.reload(); window.location.reload();
// }, 100); }, 100);
// clearInterval(checkDevTools); clearInterval(checkDevTools);
// } }
// if (!devtools.isOpen) { if (!devtools.isOpen) {
// let before = performance.now(); let before = performance.now();
// let after = performance.now(); let after = performance.now();
// let executionDelay = after - before; let executionDelay = after - before;
// if (executionDelay > 100) { if (executionDelay > 100) {
// setDevToolsOpen(true); setDevToolsOpen(true);
// document.body.innerHTML = document.body.innerHTML =
// "<h1 style='color: red; text-align: center;'>Close Inspect to continue using the application.</h1>"; "<h1 style='color: red; text-align: center;'>Close Inspect to continue using the application.</h1>";
// } else { } else {
// setDevToolsOpen(false); setDevToolsOpen(false);
// } }
// } }
// }, 1000); }, 1000);
// return () => clearInterval(checkDevTools); return () => clearInterval(checkDevTools);
// }, [devToolsOpen]); }, [devToolsOpen]);
const isBlocked = useDevToolsDetection(() => {
// optional: log, notify, etc.
console.warn('DevTools detected');
});
if (isBlocked) {
return (
<div style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100vh',
flexDirection: 'column',
gap: '1rem'
}}>
<h1 style={{ color: 'red' }}>
DevTools detected. Please close it to continue.
</h1>
</div>
);
}
if (extendModel) { if (extendModel) {
return ( return (
<ExtendSubscriptionModal <ExtendSubscriptionModal

View File

@ -2160,15 +2160,15 @@ const BookingData = createSlice({
state.getmultipleSearchDatas = []; state.getmultipleSearchDatas = [];
} }
}); });
builder.addCase(getAppSubscriptionDate.fulfilled, (state, action) => { builder.addCase(getAppSubscriptionDate.fulfilled, (state, action) => {
if (action?.payload?.data?.statusCode === 1) { if (action?.payload?.data?.statusCode === 1) {
state.AppExpDateData = state.AppExpDateData =
action?.payload?.data?.data?.[0]|| {}; action?.payload?.data?.data?.[0] || {};
} else { } else {
state.AppExpDateData = {}; state.AppExpDateData = {};
} }
}); });
}, },
}); });

View File

@ -534,10 +534,14 @@ function BSCategoryHorizontal(props) {
} }
} else { } else {
// 2 or more items, always show // 2 or more items, always show
setSubCat(true); if (FavSelected) {
setSubCat(false);
} else {
setSubCat(true);
}
} }
} }
}, [SubcategorieData, templateData]); }, [SubcategorieData, templateData, FavSelected]);
useEffect(() => { useEffect(() => {
if (typeof searchData === 'string' && categoryData?.length > 0) { if (typeof searchData === 'string' && categoryData?.length > 0) {
@ -608,9 +612,9 @@ function BSCategoryHorizontal(props) {
AppId: AppId, AppId: AppId,
...(AvailableDate && selectedDate ...(AvailableDate && selectedDate
? { ? {
fromDate: selectedDate?.[0], fromDate: selectedDate?.[0],
toDate: selectedDate?.[1], toDate: selectedDate?.[1],
} }
: {}), : {}),
}; };
@ -647,9 +651,9 @@ function BSCategoryHorizontal(props) {
AppId: AppId, AppId: AppId,
...(AvailableDate && selectedDate ...(AvailableDate && selectedDate
? { ? {
fromDate: selectedDate?.[0], fromDate: selectedDate?.[0],
toDate: selectedDate?.[1], toDate: selectedDate?.[1],
} }
: {}), : {}),
}; };
let res = await dispatch(getSelectedFavItems(data)).unwrap(); let res = await dispatch(getSelectedFavItems(data)).unwrap();
@ -886,9 +890,9 @@ function BSCategoryHorizontal(props) {
backgroundColor: backgroundColor:
!accessOther && accessToCard !accessOther && accessToCard
? lightenColor( ? lightenColor(
SelectedCatgColor?.['BackgroundColor'], SelectedCatgColor?.['BackgroundColor'],
0.4 0.4
) )
: SelectedCatgColor?.['BackgroundColor'], : SelectedCatgColor?.['BackgroundColor'],
padding: padding, padding: padding,
border: accessToCard ? '1px solid' : undefined, border: accessToCard ? '1px solid' : undefined,
@ -899,9 +903,9 @@ function BSCategoryHorizontal(props) {
: SelectedCatgColor?.['BackgroundColor'] === '#000000' : SelectedCatgColor?.['BackgroundColor'] === '#000000'
? '#ffffff' ? '#ffffff'
: darkenColor( : darkenColor(
SelectedCatgColor?.['BackgroundColor'], SelectedCatgColor?.['BackgroundColor'],
70 70
) )
: undefined, : undefined,
}} }}
className="sampleCard" className="sampleCard"
@ -935,9 +939,9 @@ function BSCategoryHorizontal(props) {
backgroundColor: backgroundColor:
!accessOther && !accessToCard && -2 == indexval !accessOther && !accessToCard && -2 == indexval
? lightenColor( ? lightenColor(
SelectedCatgColor?.['BackgroundColor'], SelectedCatgColor?.['BackgroundColor'],
0.4 0.4
) )
: SelectedCatgColor?.['BackgroundColor'], : SelectedCatgColor?.['BackgroundColor'],
padding: padding, padding: padding,
border: border:
@ -983,9 +987,9 @@ function BSCategoryHorizontal(props) {
? index != indexval ? index != indexval
? SelectedCatgColor?.['BackgroundColor'] ? SelectedCatgColor?.['BackgroundColor']
: lightenColor( : lightenColor(
SelectedCatgColor?.['BackgroundColor'], SelectedCatgColor?.['BackgroundColor'],
0.4 0.4
) )
: SelectedCatgColor?.['BackgroundColor'], : SelectedCatgColor?.['BackgroundColor'],
padding: padding, padding: padding,
border: '1px solid', border: '1px solid',
@ -1088,11 +1092,11 @@ function BSCategoryHorizontal(props) {
? index !== indexval ? index !== indexval
? SelectedCatgColor?.['BackgroundColor'] ? SelectedCatgColor?.['BackgroundColor']
: lightenColor( : lightenColor(
SelectedCatgColor?.[ SelectedCatgColor?.[
'BackgroundColor' 'BackgroundColor'
], ],
0.4 0.4
) )
: SelectedCatgColor?.['BackgroundColor'], : SelectedCatgColor?.['BackgroundColor'],
padding: padding, padding: padding,
border: '1px solid', border: '1px solid',
@ -1100,18 +1104,18 @@ function BSCategoryHorizontal(props) {
index !== indexval index !== indexval
? SelectedCatgColor?.['BackgroundColor'] ? SelectedCatgColor?.['BackgroundColor']
: SelectedCatgColor?.['BackgroundColor'] === : SelectedCatgColor?.['BackgroundColor'] ===
'#ffffff' '#ffffff'
? '#000000' ? '#000000'
: SelectedCatgColor?.[ : SelectedCatgColor?.[
'BackgroundColor' 'BackgroundColor'
] === '#000000' ] === '#000000'
? '#ffffff' ? '#ffffff'
: darkenColor( : darkenColor(
SelectedCatgColor?.[ SelectedCatgColor?.[
'BackgroundColor' 'BackgroundColor'
], ],
70 70
), ),
userSelect: 'none', userSelect: 'none',
minWidth: 'max-content', // set a width if needed minWidth: 'max-content', // set a width if needed
}} }}
@ -1170,16 +1174,16 @@ function BSCategoryHorizontal(props) {
backgroundColor: backgroundColor:
!accessOther && accessToCard !accessOther && accessToCard
? lightenColor( ? lightenColor(
SelectedCatgColor?.['BackgroundColor'], SelectedCatgColor?.['BackgroundColor'],
0.4 0.4
) )
: SelectedCatgColor?.['BackgroundColor'], : SelectedCatgColor?.['BackgroundColor'],
padding: padding, padding: padding,
border: accessToCard && '1px solid', border: accessToCard && '1px solid',
borderColor: borderColor:
accessToCard && accessToCard &&
!accessOther && !accessOther &&
SelectedCatgColor?.['BackgroundColor'] == '#ffffff' SelectedCatgColor?.['BackgroundColor'] == '#ffffff'
? '#000000' ? '#000000'
: SelectedCatgColor?.['BackgroundColor'] === '#000000' : SelectedCatgColor?.['BackgroundColor'] === '#000000'
? '#ffffff' ? '#ffffff'
@ -1219,7 +1223,7 @@ function BSCategoryHorizontal(props) {
border: accessOther && '1px solid', border: accessOther && '1px solid',
borderColor: borderColor:
accessOther && accessOther &&
SelectedCatgColor?.['BackgroundColor'] == '#ffffff' SelectedCatgColor?.['BackgroundColor'] == '#ffffff'
? '#000000' ? '#000000'
: SelectedCatgColor?.['BackgroundColor'] === '#000000' : SelectedCatgColor?.['BackgroundColor'] === '#000000'
? '#ffffff' ? '#ffffff'

View File

@ -1,7 +1,9 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useSelector, useDispatch, shallowEqual } from 'react-redux'; import { useSelector, useDispatch, shallowEqual } from 'react-redux';
import { import {
ChangeSubcategoryData,
getLayoutSubCategories, getLayoutSubCategories,
GlobalisFavClicked,
GlobalProductCategorie, GlobalProductCategorie,
} from '../../Features/BookingScreen/BookingData/BookingData'; } from '../../Features/BookingScreen/BookingData/BookingData';
import { getTemplateData } from '../../Features/ThemeChange/ThemeChange'; import { getTemplateData } from '../../Features/ThemeChange/ThemeChange';
@ -12,6 +14,7 @@ const LayoutSubCategoryFetcher = () => {
const ProdCat = useSelector(GlobalProductCategorie, shallowEqual); const ProdCat = useSelector(GlobalProductCategorie, shallowEqual);
const templateData = useSelector(getTemplateData, shallowEqual); const templateData = useSelector(getTemplateData, shallowEqual);
const favSelected = useSelector(GlobalisFavClicked);
const CompId = getSession('CompId'); const CompId = getSession('CompId');
const BranchId = getSession('BranchId'); const BranchId = getSession('BranchId');
@ -23,6 +26,11 @@ const LayoutSubCategoryFetcher = () => {
const isCategory5 = templateData?.BookingCategory?.[0] === 'Category5'; const isCategory5 = templateData?.BookingCategory?.[0] === 'Category5';
const isLayout2 = templateData?.BookingLayout?.[0] === 'Layout2'; const isLayout2 = templateData?.BookingLayout?.[0] === 'Layout2';
if (favSelected) {
dispatch(ChangeSubcategoryData([]));
return
}
if (isCategory5 && isLayout2) { if (isCategory5 && isLayout2) {
dispatch( dispatch(
getLayoutSubCategories({ getLayoutSubCategories({
@ -37,6 +45,7 @@ const LayoutSubCategoryFetcher = () => {
ProdCat, ProdCat,
templateData?.BookingCategory?.[0], templateData?.BookingCategory?.[0],
templateData?.BookingLayout?.[0], templateData?.BookingLayout?.[0],
favSelected
]); ]);
return null; // this component renders nothing return null; // this component renders nothing

View File

@ -49,7 +49,7 @@ const OtherServices = ({ formType }) => {
const AppId = getSession('AppId'); const AppId = getSession('AppId');
const UserId = getSession('UserId'); const UserId = getSession('UserId');
console.log(SelectedCategory, 'SelectedCategory'); console.log(TaxData, 'TaxData');
const items = [ const items = [
{ {
name: 'Home', name: 'Home',
@ -435,8 +435,8 @@ const OtherServices = ({ formType }) => {
<DropDowns <DropDowns
options={[ options={[
...TaxData?.map((option) => ({ ...TaxData?.map((option) => ({
value: option.TaxId, value: option?.TaxId,
label: option.TaxIdName, label: `${option?.TaxIdName} - ${option?.TaxPercentage}%`,
})), })),
]} ]}
label="Tax" label="Tax"

View File

@ -1,86 +0,0 @@
const DevToolsDetector = {
checkWindowSize() {
const threshold = 160;
return (
window.outerWidth - window.innerWidth > threshold ||
window.outerHeight - window.innerHeight > threshold
);
},
checkConsole() {
let detected = false;
const element = new Image();
Object.defineProperty(element, 'id', {
get: () => { detected = true; }
});
console.log('%c', element);
console.clear();
return detected;
},
checkDebugger() {
if (import.meta.env.DEV) return false;
const start = performance.now();
// eslint-disable-next-line no-debugger
debugger;
const end = performance.now();
return end - start > 100;
},
checkToString() {
let detected = false;
const div = document.createElement('div');
Object.defineProperty(div, 'id', {
get: function () {
detected = true;
return 'id';
}
});
console.log(div);
console.clear();
return detected;
},
detect() {
return (
this.checkWindowSize() ||
this.checkConsole() ||
this.checkDebugger() ||
this.checkToString()
);
}
};
export default DevToolsDetector;
import { useEffect, useState } from 'react';
const isMobileOrIOS = () =>
/iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
export const useDevToolsDetection = (onDetected) => {
const [isBlocked, setIsBlocked] = useState(false);
useEffect(() => {
if (isMobileOrIOS()) return;
const interval = setInterval(() => {
const detected = DevToolsDetector.detect();
if (detected && !isBlocked) {
setIsBlocked(true);
onDetected?.();
} else if (!detected && isBlocked) {
setIsBlocked(false);
clearInterval(interval);
setTimeout(() => window.location.reload(), 100);
}
}, 1000);
return () => clearInterval(interval);
}, [isBlocked]);
return isBlocked;
};