import { useCallback, useEffect, useRef, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { Form, Checkbox, Radio, Divider, InputNumber } 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'; import { InputField } from '../../Components/Forms/InputField.jsx'; const PreferenceList = () => { const { SadminuserAccess, featureaddDetails } = 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, SettingCount, SettingTime,Comments }) => { allSettingsMap[SettingIdName?.toLowerCase()] = { value: SettingValue, count: SettingCount, time: SettingTime?.split(' ')?.[0], comments: Comments }; }); console.log(featureaddDetails, 'featureaddDetails'); const buildInitialValues = () => ({ dashboard: allSettingsMap['dashboard']?.value === 'Y', shortcutkeys: allSettingsMap['shortcutkeys']?.value === 'Y', autoreceivestock: allSettingsMap['autoreceivestock']?.value === 'Y', salespageaskiosk: allSettingsMap['salespageaskiosk']?.value === 'Y', kioskotp: allSettingsMap['kioskotp']?.value === 'Y', decimal: allSettingsMap['decimal']?.value === 'Y', enabledModules: [ ...(allSettingsMap['dinein']?.value === 'Y' ? ['dinein'] : []), ...(allSettingsMap['estimation']?.value === 'Y' ? ['estimation'] : []), ], searchfocus: allSettingsMap['searchfocus']?.value === 'Y', addproductcard: allSettingsMap['addproductcard']?.value === 'Y', enabledFeatures: [ ...(allSettingsMap['parking']?.value === 'Y' ? ['parking'] : []), ...(allSettingsMap['offer']?.value === 'Y' ? ['offer'] : []), ], stockselection: allSettingsMap['stockselection']?.value === 'Y', weightasquantity: allSettingsMap['weightasquantity']?.value === 'Y', expiredselection: allSettingsMap['expiredselection']?.value === 'Y', salesmode: allSettingsMap['sales mode']?.value === 'Y', retailshortname: allSettingsMap['retailshortname']?.comments || 'RT', wholesaleshortname: allSettingsMap['wholesaleshortname']?.comments || 'WS', billitemsorder: allSettingsMap['billitemsorder']?.value === 'Y', preorderpricechange: allSettingsMap['preorderpricechange']?.value === 'Y', quantityrestriction: allSettingsMap['overalllimit']?.value === 'Y' || allSettingsMap['itemwiselimit']?.value === 'Y', quantityrestrictiontype: allSettingsMap['overalllimit']?.value === 'Y' ? 'overall' : allSettingsMap['itemwiselimit']?.value === 'Y' ? 'itemwise' : 'overall', kiosktimelimit: allSettingsMap['hours']?.value === 'Y' || allSettingsMap['minutes']?.value === 'Y', kiosktimelimittype: allSettingsMap['hours']?.value === 'Y' ? 'hours' : allSettingsMap['minutes']?.value === 'Y' ? 'minutes' : 'minutes', maxquantity: allSettingsMap['overalllimit']?.value === 'Y' ? allSettingsMap['overalllimit']?.count || 1 : allSettingsMap['itemwiselimit']?.value === 'Y' ? allSettingsMap['itemwiselimit']?.count || 1 : 1, maxtime: allSettingsMap['hours']?.value === 'Y' ? (allSettingsMap['hours']?.time ? parseFloat(allSettingsMap['hours']?.time / 60) : 0.5) : allSettingsMap['minutes']?.value === 'Y' ? parseFloat(allSettingsMap['minutes']?.time || 30) : 30, billOption: ['whatsapp', 'sms', 'email'].some( (k) => allSettingsMap[k]?.value === 'Y' ) ? 'pdf' : 'print', pdfSendOptions: ['whatsapp', 'email', 'sms'].filter( (k) => allSettingsMap[k]?.value === 'Y' ), tokenonly: allSettingsMap['tokenonly']?.value === 'Y', allproductindividualtoken: allSettingsMap['allproductindividualtoken']?.value === 'Y', printOptions: ['printuom', 'printlogo', 'printgreetings'].filter( (k) => allSettingsMap[k]?.value === 'Y' ), mobilea4: allSettingsMap['mobilea4']?.value === 'Y', estimateSettings: [ ...(allSettingsMap['estimateprintheader']?.value === 'Y' ? ['estimateprintheader'] : []), ...(allSettingsMap['estimatetitle']?.value === 'Y' ? ['estimatetitle'] : []), ], scanlayout: allSettingsMap['scanlayout']?.value === 'Y', verifyproduct: allSettingsMap['verifyproduct']?.value === 'Y', imeidetails: allSettingsMap['imeidetails']?.value === 'Y', customisedbillnumber: allSettingsMap['customisedbillnumber']?.value === 'Y', upiqr: allSettingsMap['upiqr']?.value === 'Y', lowstockreport: allSettingsMap['lowstockreport']?.value === 'Y', weeklysalesreport: allSettingsMap['weeklysalesreport']?.value === 'Y', notificationblink: allSettingsMap['notificationblink']?.value === 'Y', onlineindivdualslots: allSettingsMap['onlineindivdualslots']?.value === 'Y', editbill: allSettingsMap['editbill']?.value === 'Y', notification: [ ...(allSettingsMap['onbilltime']?.value === 'Y' ? ['onbilltime'] : []), ...(allSettingsMap['1daybefore']?.value === 'Y' ? ['1daybefore'] : []), ...(allSettingsMap['1hourbefore']?.value === 'Y' ? ['1hourbefore'] : []), ], BookingOptionsandmethod: [ ...(allSettingsMap['allow individual booking']?.value === 'Y' ? ['allow individual booking'] : []), ...(allSettingsMap['single booking only']?.value === '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); console.log(built, '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: i.Comments || "", 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 salesMode = values.salesmode; console.log("Sales Mode:", values.salesmode); console.log("Retail Short Name:", values.retailshortname); console.log("Wholesale Short Name:", values.wholesaleshortname); 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, salespageaskiosk: values.salespageaskiosk, kioskotp: values.kioskotp, decimal: values.decimal, searchfocus: values.searchfocus, addproductcard: values.addproductcard, stockselection: values.stockselection, weightasquantity: values.weightasquantity, expiredselection: values.expiredselection, 'sales mode': values?.['salesmode'], billitemsorder: values.billitemsorder, preorderpricechange: values.preorderpricechange, tokenonly: values.tokenonly, allproductindividualtoken: values.allproductindividualtoken, mobilea4: values.mobilea4, scanlayout: values.scanlayout, verifyproduct: values.verifyproduct, imeidetails: values.imeidetails, customisedbillnumber: values.customisedbillnumber, upiqr: values.upiqr, lowstockreport: values.lowstockreport, weeklysalesreport: values.weeklysalesreport, notificationblink: values.notificationblink, editbill: values.editbill, overalllimit: values.quantityrestriction && values.quantityrestrictiontype === 'overall', itemwiselimit: values.quantityrestriction && values.quantityrestrictiontype === 'itemwise', hours: values.kiosktimelimit && values.kiosktimelimittype === 'hours', minutes: values.kiosktimelimit && values.kiosktimelimittype === 'minutes', }; const arrayValues = { dinein: values.enabledModules, estimation: values.enabledModules, parking: values.enabledFeatures, estimateprintheader: values.estimateSettings, estimatetitle: values.estimateSettings, 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: key === "retailshortname" ? values.retailshortname || "" : key === "wholesaleshortname" ? values.wholesaleshortname || "" : setting.Comments || "", SettingValue: key === "retailshortname" || key === "wholesaleshortname" ? salesMode ? "Y" : "N" : isChecked ? "Y" : "N", SettingCount: (key === "overalllimit" || key === "itemwiselimit") && isChecked ? parseFloat(values.maxquantity) || null : null, SettingTime: key === "hours" && isChecked ? (parseFloat(values.maxtime) * 60).toFixed(2) + " Minutes" : key === "minutes" && isChecked ? parseFloat(values.maxtime).toFixed(2) + " Minutes" : null, }; }); 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 && ( Yes ); return ( <>
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
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
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
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
General
{renderCheckbox( 'dashboard', 'Stay on the Dashboard when you open the app?' )} {renderCheckbox( 'autoreceivestock', 'Items received from godown. Add to stock Automatically ?' )} {renderCheckbox( 'decimal', 'Display values with 2 decimal places throughout the app?' )} {renderCheckbox( 'salespageaskiosk', 'Do you want to open sales page as kiosk layout?' )} {(allSettingsMap['onlineindividualslots'] !== undefined || allSettingsMap['allow individual booking'] !== undefined || allSettingsMap['single booking only'] !== undefined) && ( {allSettingsMap['allow individual booking'] !== undefined && ( Allow online individual booking )} {allSettingsMap['single booking only'] !== undefined && ( Allow single booking Only )} )} {featureaddDetails?.find( (item) => item?.FeatureAddonName?.toLowerCase() === 'kiosk sales' ) && renderCheckbox('kioskotp', 'Enable OTP verification for Kiosk Orders?')} {featureaddDetails?.find( (item) => item?.FeatureAddonName?.toLowerCase() === 'kiosk sales' ) && (allSettingsMap['hours'] !== undefined || allSettingsMap['minutes'] !== undefined) && <> Yes prev.kiosktimelimit !== curr.kiosktimelimit}> {({ getFieldValue }) => getFieldValue('kiosktimelimit') && ( <> formRef.current?.setFieldsValue({ maxtime: undefined })}> {allSettingsMap['minutes'] !== undefined && ( Minutes )} {allSettingsMap['hours'] !== undefined && ( Hours )} prev.kiosktimelimittype !== curr.kiosktimelimittype } > {({ getFieldValue }) => { const type = getFieldValue('kiosktimelimittype'); const isHours = type === 'hours'; return ( ); }} )} }
Notifications{' '}
{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?' )} {(allSettingsMap['onbilltime'] !== undefined || allSettingsMap['1daybefore'] !== undefined || allSettingsMap['1hourbefore'] !== undefined) && ( {allSettingsMap['onbilltime'] !== undefined && ( On Bill Time )} {allSettingsMap['1daybefore'] !== undefined && ( 1 Day Before )} {allSettingsMap['1hourbefore'] !== undefined && ( 1 Hour Before )} )}
Sales Page
{renderCheckbox('searchfocus', 'Always focus the search bar?')} {renderCheckbox( 'shortcutkeys', 'Would you like to enable the shortcut keys?' )} {renderCheckbox( 'addproductcard', 'Would you like to remove Add Product card from sales page ?' )} {(allSettingsMap['offer'] !== undefined || allSettingsMap['parking'] !== undefined) && ( {allSettingsMap['parking'] !== undefined && ( Parking )} {allSettingsMap['offer'] !== undefined && ( Offer )} )} {((allSettingsMap['dinein'] !== undefined && dinePreference) || allSettingsMap['estimation'] !== undefined) && ( {allSettingsMap['dinein'] !== undefined && dinePreference && ( Dine-In )} {allSettingsMap['estimation'] !== undefined && ( Estimation )} )} {renderCheckbox('stockselection', 'Enable stock selection?')} {renderCheckbox('weightasquantity', 'Use Weight as Quantity?')} {renderCheckbox('expiredselection', 'Show product expiry date?')} {/* {renderCheckbox('sales mode', 'Retail or Wholesale mode?')} */} {(allSettingsMap['sales mode'] !== undefined ) && ( <> Yes )} prev.salesmode !== curr.salesmode} > {({ getFieldValue }) => getFieldValue('salesmode') && ( <> ) } {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( 'imeidetails', 'Do you want to open the IMEI model without IMEI details?' )} {renderCheckbox( 'customisedbillnumber', 'Do you Want Customised Bill Number?' )} {renderCheckbox('scanlayout', 'Do you Want Scan Layout Page?')} {renderCheckbox('upiqr', 'Do you want to show the UPI QR code?')} {/* {renderCheckbox('editbill', 'Do you want to edit the previously created bill?')} */} {(allSettingsMap['overalllimit'] !== undefined || allSettingsMap['itemwiselimit'] !== undefined) && ( <> Yes prev.quantityrestriction !== curr.quantityrestriction}> {({ getFieldValue }) => getFieldValue('quantityrestriction') && ( <> formRef.current?.setFieldsValue({ maxquantity: undefined })}> {allSettingsMap['overalllimit'] !== undefined && ( Overall Order Quantity )} {allSettingsMap['itemwiselimit'] !== undefined && ( Item-wise Quantity )} )} )}
{['whatsapp', 'sms', 'email'].some( (k) => allSettingsMap[k] !== undefined ) && ( <> Print Bill Send PDF prev.billOption !== curr.billOption } > {({ getFieldValue }) => getFieldValue('billOption') === 'pdf' && ( {allSettingsMap['whatsapp'] !== undefined && ( WhatsApp )} {allSettingsMap['email'] !== undefined && ( Email )} {allSettingsMap['sms'] !== undefined && ( SMS )} ) } )} {renderCheckbox( 'tokenonly', 'Print only token for token-maintained products?' )} {allSettingsMap['allproductindividualtoken'] !== undefined && ( prev.tokenonly !== curr.tokenonly } > {({ getFieldValue }) => { const tokenOnlyTrue = getFieldValue('tokenonly'); return ( tokenOnlyTrue && renderCheckbox( 'allproductindividualtoken', 'Print individual token for each product?' ) ); }} )} {['printuom', 'printlogo', 'printgreetings'].some( (k) => allSettingsMap[k] !== undefined ) && ( {allSettingsMap['printuom'] !== undefined && ( Unit of Measure (UOM) )} {allSettingsMap['printlogo'] !== undefined && ( Branch Logo )} {allSettingsMap['printgreetings'] !== undefined && ( Greetings )} )} {renderCheckbox( 'mobilea4', 'Prefer printing in A4/A5 on mobile?' )} {(allSettingsMap['estimateprintheader'] !== undefined || allSettingsMap['estimatetitle'] !== undefined) && ( {allSettingsMap['estimateprintheader'] !== undefined && ( Show shop header (Name, Address, GST) )} {allSettingsMap['estimatetitle'] !== undefined && ( Show “Estimate (R/W)” title )} )}
} />
); }; export default PreferenceList;