Android_Retail/src/Pages/Preference/PreferenceList.jsx

773 lines
27 KiB
JavaScript

import { useCallback, useEffect, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Form, Checkbox, Radio, Divider } from 'antd';
import { ArrowRightOutlined } from '@ant-design/icons';
import FormHeader from '../PageComponents/FormHeader.jsx';
import Buttons from '../../Components/Forms/Buttons.jsx';
import { Messages } from '../../Components/Notifications/Messages';
import {
changeBreadCrumb,
getEmpAccess,
} from '../../Features/AppPage/CenterPage.js';
import {
getApplicationDtlsByAppId,
getPreferenceAppNames02,
gettableData,
postPreferenceAppNames,
settingDataSelector,
} from '../../Features/PreferenceMaster/PreferenceMaster.js';
import { getSession } from '../../Services/Others.js';
import { useAuth } from '../../AuthContext.jsx';
import { ApplicationPreferences } from '../../Features/BrachLogin/BranchLogin.js';
import './PreferenceList.scss';
const PreferenceList = () => {
const { SadminuserAccess } = useAuth();
const dispatch = useDispatch();
const formRef = useRef();
const CompId = getSession('CompId');
const BranchId = getSession('BranchId');
const AppId = getSession('AppId');
const UserId = getSession('UserId');
const UserType = getSession('UserType');
const SalesReport = getSession('SalesReport');
const [open, setOpen] = useState(false);
const [applicationValue, setApplicationValue] = useState(null);
const [applicationName, setApplicationName] = useState(null);
const [messageType, setMessageType] = useState(null);
const [messageData, setMessageData] = useState(null);
const [activeSection, setActiveSection] = useState('general');
const [empData, setEmpData] = useState();
const [preferenceConfigs, setPreferenceConfigs] = useState([]);
const [addnewAccess, setAddNewAccess] = useState(true);
const tableValue = useSelector(settingDataSelector);
const appPreferences = useSelector(ApplicationPreferences);
const bookingTypePreference = appPreferences?.find(
(pre) => pre?.PreferredCatName === 'Booking Type'
)?.PreferenceCatDetails;
const dinePreference = bookingTypePreference?.find(
(type) =>
type?.PreferredSubCatName?.toLowerCase() === 'dine in' &&
type?.PreferredStatus === 'Y'
);
const settingsList = tableValue[0]?.SettingDtlDetails ?? preferenceConfigs;
const allSettingsMap = {};
settingsList?.forEach(({ SettingIdName, SettingValue }) => {
allSettingsMap[SettingIdName?.toLowerCase()] = SettingValue;
});
console.log(allSettingsMap, 'allSettingsMapallSettingsMapallSettingsMap');
const buildInitialValues = () => ({
dashboard: allSettingsMap['dashboard'] === 'Y',
shortcutkeys:allSettingsMap['shortcutkeys']==="Y",
autoreceivestock: allSettingsMap['autoreceivestock'] === 'Y',
decimal: allSettingsMap['decimal'] === 'Y',
enabledModules: [
...(allSettingsMap['dinein'] === 'Y' ? ['dinein'] : []),
...(allSettingsMap['estimation'] === 'Y' ? ['estimation'] : []),
],
searchfocus: allSettingsMap['searchfocus'] === 'Y',
addproductcard: allSettingsMap['addproductcard'] === 'Y',
enabledFeatures: [
...(allSettingsMap['parking'] === 'Y' ? ['parking'] : []),
...(allSettingsMap['offer'] === 'Y' ? ['offer'] : []),
],
stockselection: allSettingsMap['stockselection'] === 'Y',
weightasquantity: allSettingsMap['weightasquantity'] === 'Y',
expiredselection: allSettingsMap['expiredselection'] === 'Y',
'sales mode': allSettingsMap['sales mode'] === 'Y',
billitemsorder: allSettingsMap['billitemsorder'] === 'Y',
preorderpricechange: allSettingsMap['preorderpricechange'] === 'Y',
billOption: ['whatsapp', 'sms', 'email'].some(
(k) => allSettingsMap[k] === 'Y'
)
? 'pdf'
: 'print',
pdfSendOptions: ['whatsapp', 'email', 'sms'].filter(
(k) => allSettingsMap[k] === 'Y'
),
tokenonly: allSettingsMap['tokenonly'] === 'Y',
allproductindividualtoken:
allSettingsMap['allproductindividualtoken'] === 'Y',
printOptions: ['printuom', 'printlogo', 'printgreetings'].filter(
(k) => allSettingsMap[k] === 'Y'
),
mobilea4: allSettingsMap['mobilea4'] === 'Y',
estimateprintheader: allSettingsMap['estimateprintheader'] === 'Y',
scanlayout: allSettingsMap['scanlayout'] === 'Y',
verifyproduct: allSettingsMap['verifyproduct'] === 'Y',
customisedbillnumber: allSettingsMap['customisedbillnumber'] === 'Y',
upiqr: allSettingsMap['upiqr'] === 'Y',
lowstockreport: allSettingsMap['lowstockreport'] === 'Y',
weeklysalesreport: allSettingsMap['weeklysalesreport'] === 'Y',
notificationblink: allSettingsMap['notificationblink'] === 'Y',
onlineindivdualslots: allSettingsMap['onlineindivdualslots'] === 'Y',
editbill: allSettingsMap['editbill'] === 'Y',
notification: [
...(allSettingsMap['onbilltime'] === 'Y' ? ['onbilltime'] : []),
...(allSettingsMap['1daybefore'] === 'Y' ? ['1daybefore'] : []),
...(allSettingsMap['1hourbefore'] === 'Y' ? ['1hourbefore'] : []),
],
BookingOptionsandmethod: [
...(allSettingsMap['allow individual booking'] === 'Y'
? ['allow individual booking']
: []),
...(allSettingsMap['single booking only'] === 'Y'
? ['single booking only']
: []),
],
});
const [initialValues, setInitialValues] = useState();
console.log(initialValues, 'initialValues');
useEffect(() => {
dispatch(
changeBreadCrumb({
items: [
{ name: 'Home', link: `${import.meta.env.BASE_URL}app-page/home` },
],
})
);
fetchTableData();
const centerPageSub = document.querySelector('.centerPageSub');
if (centerPageSub) {
centerPageSub.style.overflow = 'hidden';
}
return () => {
if (centerPageSub) {
centerPageSub.style.overflow = '';
}
};
}, []);
useEffect(() => {
if (settingsList) {
const built = buildInitialValues();
setInitialValues(built);
formRef.current?.setFieldsValue(built);
}
}, [settingsList]);
useEffect(() => {
if (UserType === 'Employee') fetchEmpAccess();
}, [UserType]);
useEffect(() => {
let hasAccess =
['Admin', 'Super Admin'].includes(UserType) ||
(UserType === 'Employee' && empData?.AddAccess === 'Y') ||
(UserType === 'Super Admin User' &&
SadminuserAccess?.find((e) => e.MenuName === 'Preference')
?.AddAccess === 'Y');
setAddNewAccess(!hasAccess);
}, [empData, SadminuserAccess, UserType]);
useEffect(() => {
if (open) applicationDropdownData();
}, [open]);
useEffect(() => {
fetchTableData();
if (tableValue?.length === 0) {
getPreferenceConfigs();
}
}, []);
useEffect(() => {
const container = document.querySelector('.preferences-list');
if (!container) return;
const handleScroll = () => {
const sections = [
'general',
'notifications',
'sales-page',
'print-preferences',
];
const containerTop = container.scrollTop;
for (const sectionId of sections) {
const element = document.getElementById(sectionId);
if (element) {
const elementTop = element.offsetTop - container.offsetTop;
const elementBottom = elementTop + element.offsetHeight;
if (
elementTop <= containerTop + 100 &&
elementBottom > containerTop
) {
setActiveSection(sectionId);
break;
}
}
}
};
container.addEventListener('scroll', handleScroll);
return () => container.removeEventListener('scroll', handleScroll);
}, []);
const getPreferenceConfigs = async () => {
const res = await dispatch(getPreferenceAppNames02())?.unwrap();
if (res?.data?.statusCode === 1) {
setPreferenceConfigs(
res?.data?.data?.map((i) => ({
SettingIdName: i.ConfigName,
SettingId: i.ConfigId,
Comments: 'Enter Comment',
SettingValue: 'N',
}))
);
}
};
const fetchEmpAccess = async () => {
const data = { CompId, BranchId, AppId, EmpId: UserId };
const response = await dispatch(getEmpAccess(data)).unwrap();
const access = response?.data?.data?.[0]?.EmpAccessDetails?.find(
(i) => i.ConfigName === 'Preference'
);
setEmpData(access);
};
const applicationDropdownData = async () => {
const res = await dispatch(getApplicationDtlsByAppId({ AppId })).unwrap();
if (res?.data?.statusCode === 1) {
setApplicationName(res?.data?.data?.[0]?.AppName);
await fetchTableData();
}
};
const fetchTableData = async () => {
await dispatch(gettableData({ CompId, BranchId, AppId })).unwrap();
handleApplicationChange(AppId);
};
const handleApplicationChange = async (value) => {
setApplicationValue(value);
formRef.current?.setFieldsValue({ AppId: value });
};
const onComplete = useCallback(() => {
setMessageData(null);
setMessageType(null);
}, []);
const handleMenuClick = (e, targetId) => {
e.preventDefault();
setActiveSection(targetId);
const container = document.querySelector('.preferences-list');
const target = document.getElementById(targetId);
if (container && target) {
const containerTop = container.offsetTop;
const targetTop = target.offsetTop;
const scrollPosition = targetTop - containerTop;
container.scrollTo({
top: scrollPosition,
behavior: 'smooth',
});
}
};
const handleSubmit = async () => {
const values = formRef.current.getFieldsValue();
const settings = settingsList || [];
console.log(values, 'values');
const updatedSettings = settings.map((setting) => {
const key = setting.SettingIdName.toLowerCase();
const boolValues = {
dashboard: values.dashboard,
shortcutkeys:values.shortcutkeys,
autoreceivestock: values.autoreceivestock,
decimal: values.decimal,
searchfocus: values.searchfocus,
addproductcard: values.addproductcard,
stockselection: values.stockselection,
weightasquantity: values.weightasquantity,
expiredselection: values.expiredselection,
'sales mode': values?.['sales mode'],
billitemsorder: values.billitemsorder,
preorderpricechange: values.preorderpricechange,
tokenonly: values.tokenonly,
allproductindividualtoken: values.allproductindividualtoken,
mobilea4: values.mobilea4,
estimateprintheader: values.estimateprintheader,
scanlayout: values.scanlayout,
verifyproduct: values.verifyproduct,
customisedbillnumber: values.customisedbillnumber,
upiqr: values.upiqr,
lowstockreport: values.lowstockreport,
weeklysalesreport: values.weeklysalesreport,
notificationblink: values.notificationblink,
editbill: values.editbill,
};
const arrayValues = {
dinein: values.enabledModules,
estimation: values.enabledModules,
parking: values.enabledFeatures,
offer: values.enabledFeatures,
whatsapp: values.pdfSendOptions,
sms: values.pdfSendOptions,
email: values.pdfSendOptions,
printuom: values.printOptions,
printlogo: values.printOptions,
printgreetings: values.printOptions,
onbilltime: values.notification,
'1daybefore': values.notification,
'1hourbefore': values.notification,
'allow individual booking': values['BookingOptionsandmethod'],
'single booking only': values['BookingOptionsandmethod'],
};
const isChecked =
key in boolValues
? boolValues[key]
: (arrayValues[key]?.includes(key) ?? false);
return {
ConfigName: setting.SettingIdName,
SettingId: setting.SettingId,
Comments: setting.Comments || 'Enter Comment',
SettingValue: isChecked ? 'Y' : 'N',
};
});
const payload = {
CompId,
BranchId,
CreatedBy: UserId,
AppId,
SettingDtlDetails: updatedSettings,
};
const response = await dispatch(postPreferenceAppNames(payload)).unwrap();
if (response?.data?.statusCode === 1) {
setMessageType('success');
setMessageData(response?.data?.response);
await fetchTableData();
} else {
setMessageType('error');
setMessageData(response?.data?.response);
}
};
const renderCheckbox = (name, label) =>
allSettingsMap[name] !== undefined && (
<Form.Item name={name} label={label} valuePropName="checked">
<Checkbox>Yes</Checkbox>
</Form.Item>
);
return (
<>
<Messages
messageType={messageType}
messageData={messageData}
onComplete={onComplete}
/>
<div className="userPageTable" style={{ overflow: 'hidden' }}>
<FormHeader title="Preference" />
<div className="menu-and-preferences">
<div className="menu-section">
<div
onClick={(e) => handleMenuClick(e, 'general')}
style={{
backgroundColor:
activeSection === 'general' ? '#e6f3ff' : '#f4f4f4',
color: activeSection === 'general' ? '#1890ff' : '#23378a',
borderRight:
activeSection === 'general' ? '2px solid #1890ff' : 'none',
transform:
activeSection === 'general' ? 'scale(1.07)' : 'scale(1)',
}}
>
General
</div>
<div
onClick={(e) => handleMenuClick(e, 'notifications')}
style={{
backgroundColor:
activeSection === 'notifications' ? '#e6f3ff' : '#f4f4f4',
color:
activeSection === 'notifications' ? '#1890ff' : '#23378a',
borderRight:
activeSection === 'notifications'
? '2px solid #1890ff'
: 'none',
transform:
activeSection === 'notifications'
? 'scale(1.07)'
: 'scale(1)',
}}
>
Notifications
</div>
<div
onClick={(e) => handleMenuClick(e, 'sales-page')}
style={{
backgroundColor:
activeSection === 'sales-page' ? '#e6f3ff' : '#f4f4f4',
color: activeSection === 'sales-page' ? '#1890ff' : '#23378a',
borderRight:
activeSection === 'sales-page' ? '2px solid #1890ff' : 'none',
transform:
activeSection === 'sales-page' ? 'scale(1.07)' : 'scale(1)',
}}
>
Sales Page
</div>
<div
onClick={(e) => handleMenuClick(e, 'print-preferences')}
style={{
backgroundColor:
activeSection === 'print-preferences' ? '#e6f3ff' : '#f4f4f4',
color:
activeSection === 'print-preferences' ? '#1890ff' : '#23378a',
borderRight:
activeSection === 'print-preferences'
? '2px solid #1890ff'
: 'none',
transform:
activeSection === 'print-preferences'
? 'scale(1.07)'
: 'scale(1)',
}}
>
Print Preferences
</div>
</div>
<Form
ref={formRef}
layout="vertical"
onFinish={handleSubmit}
initialValues={initialValues}
className="preferences-list"
>
<div
style={{
backgroundColor:
activeSection === 'general' ? '#e6f3ff' : 'transparent',
padding: '16px',
borderRadius: '10px',
transition: 'background-color 0.3s ease',
}}
>
<div className="preference-headers" id="general">
General
</div>
{renderCheckbox(
'dashboard',
'Stay on the Dashboard when you open the app?'
)}
{renderCheckbox(
'shortcutkeys',
'Would you like to enable the shortcut keys?'
)}
{renderCheckbox(
'autoreceivestock',
'Items received from godown. Add to stock Automatically ?'
)}
{renderCheckbox(
'decimal',
'Display values with 2 decimal places throughout the app?'
)}
{((allSettingsMap['dinein'] !== undefined && dinePreference) ||
allSettingsMap['estimation'] !== undefined) && (
<Form.Item
name="enabledModules"
label="Select the modules you want to enable:"
>
<Checkbox.Group>
{allSettingsMap['dinein'] !== undefined &&
dinePreference && (
<Checkbox value="dinein">Dine-In</Checkbox>
)}
{allSettingsMap['estimation'] !== undefined && (
<Checkbox value="estimation">Estimation</Checkbox>
)}
</Checkbox.Group>
</Form.Item>
)}
{(allSettingsMap['onbilltime'] !== undefined ||
allSettingsMap['1daybefore'] !== undefined ||
allSettingsMap['1hourbefore'] !== undefined) && (
<Form.Item
name="notification"
label="Choose notification timing:"
>
<Checkbox.Group>
{allSettingsMap['onbilltime'] !== undefined && (
<Checkbox value="onbilltime">On Bill Time</Checkbox>
)}
{allSettingsMap['1daybefore'] !== undefined && (
<Checkbox value="1daybefore">1 Day Before</Checkbox>
)}
{allSettingsMap['1hourbefore'] !== undefined && (
<Checkbox value="1hourbefore">1 Hour Before</Checkbox>
)}
</Checkbox.Group>
</Form.Item>
)}
{(allSettingsMap['onlineindividualslots'] !== undefined ||
allSettingsMap['allow individual booking'] !== undefined ||
allSettingsMap['single booking only'] !== undefined) && (
<Form.Item
name="BookingOptionsandmethod"
label="Individual Selling Setup"
>
<Checkbox.Group>
{allSettingsMap['allow individual booking'] !==
undefined && (
<Checkbox value="allow individual booking">
Allow online individual booking
</Checkbox>
)}
{allSettingsMap['single booking only'] !== undefined && (
<Checkbox value="single booking only">
Allow single booking Only
</Checkbox>
)}
</Checkbox.Group>
</Form.Item>
)}
</div>
<Divider />
<div
style={{
backgroundColor:
activeSection === 'notifications' ? '#e6f3ff' : 'transparent',
padding: '16px',
borderRadius: '10px',
transition: 'background-color 0.3s ease',
}}
>
<div className="preference-headers" id="notifications">
Notifications{' '}
</div>
{renderCheckbox(
'lowstockreport',
'Do you want to receive a low-stock report every day?'
)}
{renderCheckbox(
'weeklysalesreport',
'Do you want to receive a Weekly Sales Report?'
)}
{renderCheckbox(
'notificationblink',
'Do you want to enable the low-stock blink notification?'
)}
</div>
<div
style={{
backgroundColor:
activeSection === 'sales-page' ? '#e6f3ff' : 'transparent',
padding: '16px',
borderRadius: '10px',
transition: 'background-color 0.3s ease',
}}
>
<div className="preference-headers" id="sales-page">
Sales Page
</div>
{renderCheckbox('searchfocus', 'Always focus the search bar?')}
{renderCheckbox(
'addproductcard',
'Would you like to remove Add Product card from sales page ?'
)}
{(allSettingsMap['offer'] !== undefined ||
allSettingsMap['parking'] !== undefined) && (
<Form.Item
name="enabledFeatures"
label="Select the features you want to enable:"
>
<Checkbox.Group>
{allSettingsMap['parking'] !== undefined && (
<Checkbox value="parking">Parking</Checkbox>
)}
{allSettingsMap['offer'] !== undefined && (
<Checkbox value="offer">Offer</Checkbox>
)}
</Checkbox.Group>
</Form.Item>
)}
{renderCheckbox('stockselection', 'Enable stock selection?')}
{renderCheckbox('weightasquantity', 'Use Weight as Quantity?')}
{renderCheckbox('expiredselection', 'Show product expiry date?')}
{renderCheckbox('sales mode', 'Retail or Wholesale mode?')}
{renderCheckbox(
'billitemsorder',
'Show selected items first in Order Summary?'
)}
{renderCheckbox(
'preorderpricechange',
'Prefer price update for pre-bookings?'
)}
{renderCheckbox(
'verifyproduct',
'Do you Want Verify the Product?'
)}
{renderCheckbox(
'customisedbillnumber',
'Do you Want Customised Bill Number?'
)}
{renderCheckbox('upiqr', 'Do you want to show the UPI QR code?')}
{/* {renderCheckbox('editbill', 'Do you want to edit the previously created bill?')} */}
</div>
<Divider />
<div
style={{
backgroundColor:
activeSection === 'print-preferences'
? '#e6f3ff'
: 'transparent',
padding: '16px',
borderRadius: '10px',
transition: 'background-color 0.3s ease',
}}
>
<div className="preference-headers" id="print-preferences">
Print Preferences
</div>
{['whatsapp', 'sms', 'email'].some(
(k) => allSettingsMap[k] !== undefined
) && (
<>
<Form.Item
name="billOption"
label="Choose how to handle bills:"
>
<Radio.Group>
<Radio value="print">Print Bill</Radio>
<Radio value="pdf">Send PDF</Radio>
</Radio.Group>
</Form.Item>
<Form.Item
noStyle
shouldUpdate={(prev, curr) =>
prev.billOption !== curr.billOption
}
>
{({ getFieldValue }) =>
getFieldValue('billOption') === 'pdf' && (
<Form.Item
name="pdfSendOptions"
label="Select how to send the PDF:"
>
<Checkbox.Group>
{allSettingsMap['whatsapp'] !== undefined && (
<Checkbox value="whatsapp">WhatsApp</Checkbox>
)}
{allSettingsMap['email'] !== undefined && (
<Checkbox value="email">Email</Checkbox>
)}
{allSettingsMap['sms'] !== undefined && (
<Checkbox value="sms">SMS</Checkbox>
)}
</Checkbox.Group>
</Form.Item>
)
}
</Form.Item>
</>
)}
{renderCheckbox(
'tokenonly',
'Print only token for token-maintained products?'
)}
{allSettingsMap['allproductindividualtoken'] !== undefined && (
<Form.Item
noStyle
shouldUpdate={(prev, curr) =>
prev.tokenonly !== curr.tokenonly
}
>
{({ getFieldValue }) => {
const tokenOnlyTrue = getFieldValue('tokenonly');
return (
tokenOnlyTrue &&
renderCheckbox(
'allproductindividualtoken',
'Print individual token for each product?'
)
);
}}
</Form.Item>
)}
{['printuom', 'printlogo', 'printgreetings'].some(
(k) => allSettingsMap[k] !== undefined
) && (
<Form.Item
name="printOptions"
label="Select what you want to include in the print:"
>
<Checkbox.Group>
{allSettingsMap['printuom'] !== undefined && (
<Checkbox value="printuom">
Unit of Measure (UOM)
</Checkbox>
)}
{allSettingsMap['printlogo'] !== undefined && (
<Checkbox value="printlogo">Branch Logo</Checkbox>
)}
{allSettingsMap['printgreetings'] !== undefined && (
<Checkbox value="printgreetings">Greetings</Checkbox>
)}
</Checkbox.Group>
</Form.Item>
)}
{renderCheckbox(
'mobilea4',
'Prefer printing in A4/A5 on mobile?'
)}
{renderCheckbox(
'estimateprintheader',
'Do you want to include a header when printing Estimate bills?'
)}
{renderCheckbox('scanlayout', 'Do you Want Scan Layout Page?')}
</div>
<div className="submitButton">
<Buttons
buttonText="Submit Preferences"
color="901D77"
htmlType="SUBMIT"
disabled={addnewAccess}
icon={<ArrowRightOutlined />}
/>
</div>
</Form>
</div>
</div>
</>
);
};
export default PreferenceList;