2026-01-29 10:15:06 +05:30
|
|
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
2026-01-27 18:27:29 +05:30
|
|
|
import '../../Styles/DashBoard/RetailDashBoard.scss';
|
|
|
|
|
import GraphChart from './Chart/GraphChart';
|
|
|
|
|
import { DatePicker, Space, Tooltip } from 'antd';
|
|
|
|
|
import dayjs from 'dayjs';
|
|
|
|
|
import { IoMdRefresh } from 'react-icons/io';
|
|
|
|
|
import { CiShop } from 'react-icons/ci';
|
|
|
|
|
import { FiMenu } from 'react-icons/fi';
|
|
|
|
|
import PozoMind from '../../Images/pozologowhite.svg';
|
|
|
|
|
import { useNavigate, useOutletContext } from 'react-router-dom';
|
|
|
|
|
import CalendarDropdown from '../../Components/CalendarDropdown';
|
|
|
|
|
import { MdKeyboardArrowDown } from 'react-icons/md';
|
|
|
|
|
import { IoMdNotificationsOutline } from 'react-icons/io';
|
|
|
|
|
import {
|
|
|
|
|
getdashboard,
|
|
|
|
|
getdashboarddate,
|
|
|
|
|
getpreOrderDashBoard,
|
|
|
|
|
getSalesHdr,
|
|
|
|
|
getTopSellingCustomers,
|
|
|
|
|
} from '../../Features/RetailDashboard/Dashboard.js';
|
|
|
|
|
import { FaTimesCircle } from 'react-icons/fa';
|
|
|
|
|
import sandClock from '../../Images/sandClock.png';
|
|
|
|
|
import {
|
|
|
|
|
FeatureAddon,
|
|
|
|
|
getTemplate,
|
|
|
|
|
GlobalPricingAppPricingName,
|
|
|
|
|
StoredSessionData,
|
|
|
|
|
} from '../../Features/ThemeChange/ThemeChange.js';
|
|
|
|
|
import {
|
|
|
|
|
getAllCustomerPendingBalance,
|
|
|
|
|
getAppSubscriptionDate,
|
|
|
|
|
getPreferenceData,
|
|
|
|
|
} from '../../Features/BookingScreen/BookingData/BookingData.js';
|
|
|
|
|
import {
|
|
|
|
|
clearSession,
|
|
|
|
|
dateFormatChange,
|
|
|
|
|
encryptedValuesUrlFun,
|
|
|
|
|
ExtractDateFormate,
|
|
|
|
|
getSession,
|
|
|
|
|
} from '../../Services/Others';
|
|
|
|
|
import { shallowEqual, useDispatch } from 'react-redux';
|
|
|
|
|
import { useSelector } from 'react-redux';
|
|
|
|
|
import {
|
|
|
|
|
getAllprodIds,
|
|
|
|
|
getExpireProductsList,
|
|
|
|
|
getLowStockAlertProductsList,
|
|
|
|
|
getTopSellingProduct,
|
|
|
|
|
} from '../../Features/ProductPage/ProductPage.js';
|
|
|
|
|
import {
|
|
|
|
|
ApplicationPreferences,
|
|
|
|
|
checkSession,
|
|
|
|
|
GenerateLogout,
|
|
|
|
|
getCompBranchData,
|
|
|
|
|
getEmpAccesData,
|
|
|
|
|
GLobalSadminUserData,
|
|
|
|
|
GlobalSelectedBranchId,
|
|
|
|
|
PostLoginSuser,
|
|
|
|
|
PUTLoginuser,
|
|
|
|
|
} from '../../Features/BrachLogin/BranchLogin.js';
|
|
|
|
|
import { getPurchasedAppDetails } from '../../Features/BookingScreen/Pricing/Pricing.js';
|
|
|
|
|
import Add from '../../Images/dashboard/Add.png';
|
|
|
|
|
import AddPurchase from '../../Images/dashboard/AddPurchase.png';
|
|
|
|
|
import invoice from '../../Images/dashboard/invoice.png';
|
|
|
|
|
import user from '../../Images/dashboard/user.jpg';
|
|
|
|
|
import report from '../../Images/dashboard/report.png';
|
|
|
|
|
import Calendar from '../../Components/Calendar/Calendar';
|
|
|
|
|
import { PiSignOut } from 'react-icons/pi';
|
|
|
|
|
import BSNavBarUserInfo from '../BookingScreen/Components/BSNavbar/BSNavBarUserInfo';
|
|
|
|
|
import { DefaultModal } from '../../Components/Modal/DefaultModal';
|
|
|
|
|
|
|
|
|
|
import { RadioGrpButton } from '../../Components/Forms/RadioGroup.jsx';
|
|
|
|
|
import { DropDowns } from '../../Components/Forms/DropDown.jsx';
|
|
|
|
|
import {
|
|
|
|
|
ChangeRedirectStatus,
|
|
|
|
|
getEmpAccess,
|
|
|
|
|
GlobalRedirectStatus,
|
|
|
|
|
} from '../../Features/AppPage/CenterPage.js';
|
|
|
|
|
import { UserDataBasedOnBranchId } from '../../Features/Reports/Reports.js';
|
|
|
|
|
import { gettableData } from '../../Features/PreferenceMaster/PreferenceMaster.js';
|
|
|
|
|
import Loader from '../../Components/Loader/Loader.jsx';
|
|
|
|
|
import { getUserProfile } from '../../Features/UserAccount/userData.js';
|
|
|
|
|
import TopSellingProductsChart from './TopSellingProductsChart.jsx';
|
|
|
|
|
import { Messages } from '../../Components/Notifications/Messages.jsx';
|
|
|
|
|
|
|
|
|
|
const commonUrl = import.meta.env.ENV_COMMON_BASE_URL;
|
|
|
|
|
const subDirectory = import.meta.env.ENV_BASE_URL;
|
|
|
|
|
const RetailDashboard = () => {
|
|
|
|
|
const today = new Date();
|
|
|
|
|
const year = today.getFullYear();
|
|
|
|
|
const month = today.getMonth();
|
|
|
|
|
|
|
|
|
|
const formatDate = (date) =>
|
|
|
|
|
`${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
|
|
|
|
|
|
|
|
|
|
const intialFromDate = `${year}-${String(month + 1).padStart(2, '0')}-01`;
|
|
|
|
|
const intialToDate = formatDate(today);
|
|
|
|
|
const navigate = useNavigate();
|
|
|
|
|
const dispatch = useDispatch();
|
|
|
|
|
const { RangePicker } = DatePicker;
|
|
|
|
|
const [selectedTab, setSelectedTab] = useState('dashboard');
|
|
|
|
|
const tabs = [
|
|
|
|
|
{ value: 'dashboard', label: 'Dashboard' },
|
|
|
|
|
{ value: 'top-selling-products', label: 'Top Selling Products' },
|
|
|
|
|
];
|
|
|
|
|
const { setCollapse } = useOutletContext();
|
|
|
|
|
const SessionData = useSelector(StoredSessionData, shallowEqual);
|
|
|
|
|
const PricingAppPricingName = useSelector(
|
|
|
|
|
GlobalPricingAppPricingName,
|
|
|
|
|
shallowEqual
|
|
|
|
|
);
|
|
|
|
|
const [topSellingProducts, setTopSellingProducts] = useState([]);
|
|
|
|
|
const [initialDate, setInitialDate] = useState(true);
|
|
|
|
|
const [dates, setDates] = useState([
|
|
|
|
|
dayjs(intialFromDate),
|
|
|
|
|
dayjs(intialToDate),
|
|
|
|
|
]);
|
|
|
|
|
const [ismounted, setIsmounted] = useState(true);
|
|
|
|
|
const [customerPendingBalance, setcustomerPendingBalance] = useState([]);
|
|
|
|
|
console.log(PricingAppPricingName, 'PricingAppPricingName');
|
|
|
|
|
// const {
|
|
|
|
|
// AppId: appId,
|
|
|
|
|
// CompId: compId,
|
|
|
|
|
// BranchId: branchId,
|
|
|
|
|
// } = SessionData || {};
|
|
|
|
|
// console.log(appId, compId, branchId, 'SessionData');
|
|
|
|
|
const [range1, setRange1] = useState('today');
|
|
|
|
|
const [range2, setRange2] = useState('today');
|
|
|
|
|
const [range3, setRange3] = useState('today');
|
|
|
|
|
const [userprofile, setUserprofile] = useState(false);
|
|
|
|
|
|
|
|
|
|
const userProfileRef = useRef(null);
|
|
|
|
|
|
|
|
|
|
const CompId = getSession('CompId');
|
|
|
|
|
const BranchId = getSession('BranchId');
|
|
|
|
|
const AppId = getSession('AppId');
|
|
|
|
|
const UserId = getSession('UserId');
|
|
|
|
|
const UserType = getSession('UserType');
|
|
|
|
|
const sessionId = getSession('SessionId');
|
|
|
|
|
const BrLength = getSession('BranchLength');
|
|
|
|
|
const [selection, setSelection] = useState('dashboard');
|
|
|
|
|
const [page, setPage] = useState(1);
|
|
|
|
|
const [totalPages, setTotalPages] = useState(0);
|
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
|
const [products, setProducts] = useState([]);
|
|
|
|
|
console.log(selection, 'selection');
|
|
|
|
|
const [CompBranchData, setCompBranchData] = useState();
|
|
|
|
|
const [EmpAcces, setEmpAccess] = useState();
|
|
|
|
|
const [seletedBranchData, setseletedBranchData] = useState(BranchId);
|
|
|
|
|
const [branchName, setBranchName] = useState('Guest');
|
|
|
|
|
const [selectedBranchForFilter, setSelectedBranchForFilter] = useState(
|
|
|
|
|
BrLength == 1 ? null : 'all'
|
|
|
|
|
);
|
|
|
|
|
const [ApiData, setApiData] = useState([]);
|
|
|
|
|
console.log(CompBranchData, 'CompBranchData');
|
|
|
|
|
const [Zero, SetZero] = useState(false);
|
|
|
|
|
const [ResponseData, setResponseData] = useState();
|
|
|
|
|
const [DateApiData, setDateApiData] = useState([]);
|
|
|
|
|
const [piedat, setPiedat] = useState([]);
|
|
|
|
|
const inputRefs = useRef([]);
|
|
|
|
|
const [pin, setPin] = useState(['', '', '', '']);
|
|
|
|
|
const [expiredList, setExpiredList] = useState([]);
|
|
|
|
|
const [lowStockList, setLowStock] = useState([]);
|
|
|
|
|
const [AllProdIds, setAllProdIds] = useState([]);
|
|
|
|
|
const [AppDetails, setAppDetails] = useState([]);
|
|
|
|
|
const [preorderData, setpreorderData] = useState([]);
|
|
|
|
|
const [TopSellingCus, setTopsellingCus] = useState([]);
|
|
|
|
|
const [SalesHdr, setSalesHdr] = useState([]);
|
|
|
|
|
const [modal, setModal] = useState(false);
|
|
|
|
|
const [SelectType, setSelectType] = useState('O');
|
|
|
|
|
const [SelectTypeName, setSelectTypeName] = useState('OTP');
|
|
|
|
|
const [pinInput, setpinInput] = useState(false);
|
|
|
|
|
const [otp, setOtp] = useState();
|
|
|
|
|
const [FirstTimeOtp, setFirstTimeOtp] = useState(false);
|
|
|
|
|
const [FirstTimePin, setFirstTimePin] = useState(false);
|
|
|
|
|
const [seconds, setSeconds] = useState(0);
|
|
|
|
|
const [disabled, setDisabled] = useState(false);
|
|
|
|
|
const clicked = useRef(false);
|
|
|
|
|
const [selectedUserData, setSelectedUserData] = useState(null);
|
|
|
|
|
const [userDropDown, setuserDropDown] = useState([]);
|
|
|
|
|
const [ExpiryDate, setExpiryDate] = useState();
|
|
|
|
|
const [EmpData, setEmpData] = useState();
|
|
|
|
|
const [messageType, setMessageType] = useState(null);
|
|
|
|
|
const [messageData, setMessageData] = useState(null);
|
|
|
|
|
console.log(EmpData, 'EmpDataEmpData');
|
|
|
|
|
|
|
|
|
|
// Loading states to prevent duplicate API calls
|
|
|
|
|
const [isLoadingBranchData, setIsLoadingBranchData] = useState(false);
|
|
|
|
|
const [isLoadingDashboard, setIsLoadingDashboard] = useState(false);
|
|
|
|
|
const [isLoadingBranchFilter, setIsLoadingBranchFilter] = useState(false);
|
|
|
|
|
const [isInitialLoad, setIsInitialLoad] = useState(true);
|
|
|
|
|
const [initialFetchCompleted, setInitialFetchCompleted] = useState(false);
|
|
|
|
|
// Ref to track if component is mounted
|
|
|
|
|
const isMountedRef = useRef(true);
|
|
|
|
|
|
|
|
|
|
const RedirectStatus = useSelector(GlobalRedirectStatus);
|
|
|
|
|
const globalbranchid = useSelector(GlobalSelectedBranchId);
|
|
|
|
|
const SAdminUserData = useSelector(GLobalSadminUserData);
|
|
|
|
|
const appPreferences = useSelector(ApplicationPreferences);
|
|
|
|
|
const isCheckSportsApp = appPreferences
|
|
|
|
|
?.find((preference) => preference?.PreferredCatName === 'Common Module')
|
|
|
|
|
?.PreferenceCatDetails?.some(
|
|
|
|
|
(e) =>
|
|
|
|
|
e?.PreferredSubCatName === 'SportsApp' && e?.PreferredStatus === 'Y'
|
|
|
|
|
);
|
|
|
|
|
const bookingTypePreference = appPreferences?.find(
|
|
|
|
|
(preference) => preference?.PreferredCatName === 'Booking Type'
|
|
|
|
|
)?.PreferenceCatDetails;
|
|
|
|
|
const dinePreference = bookingTypePreference?.find(
|
|
|
|
|
(type) =>
|
|
|
|
|
type?.PreferredSubCatName?.toLowerCase() === 'dine in' &&
|
|
|
|
|
type?.PreferredStatus === 'Y'
|
|
|
|
|
);
|
|
|
|
|
const takeAwayPreference = bookingTypePreference?.find(
|
|
|
|
|
(type) =>
|
|
|
|
|
type?.PreferredSubCatName?.toLowerCase() === 'take away' &&
|
|
|
|
|
type?.PreferredStatus === 'Y'
|
|
|
|
|
);
|
|
|
|
|
const timerDuration = 30;
|
|
|
|
|
let EndDate = AppDetails?.[0]?.ValidityEnd;
|
|
|
|
|
|
|
|
|
|
const isoDate = EndDate; // <-- July 24
|
|
|
|
|
const date = new Date(isoDate);
|
|
|
|
|
|
|
|
|
|
const options = { year: 'numeric', month: 'long', day: 'numeric' };
|
|
|
|
|
const formatted = date.toLocaleDateString('en-US', options);
|
|
|
|
|
|
|
|
|
|
// "July 24, 2025"
|
|
|
|
|
|
|
|
|
|
console.log(expiredList, lowStockList, 'lowStockList');
|
|
|
|
|
console.log(TopSellingCus, preorderData, 'preorderData');
|
|
|
|
|
let DineInData =
|
|
|
|
|
ApiData?.[0]?.ChartDtl?.map((item) => {
|
|
|
|
|
return {
|
|
|
|
|
label: '',
|
|
|
|
|
value:
|
|
|
|
|
item?.OverAllDineInAmount || 0 - item?.OverAllDineInOfferAmount || 0,
|
|
|
|
|
date: item?.SalesDate,
|
|
|
|
|
};
|
|
|
|
|
}) || [];
|
|
|
|
|
let TakeAway =
|
|
|
|
|
ApiData?.[0]?.ChartDtl?.map((item) => {
|
|
|
|
|
return {
|
|
|
|
|
label: '',
|
|
|
|
|
value:
|
|
|
|
|
item?.OverAllTakeAwayAmount ||
|
|
|
|
|
0 - item?.OverAllTakeAwayOfferAmount ||
|
|
|
|
|
0,
|
|
|
|
|
date: item?.SalesDate,
|
|
|
|
|
};
|
|
|
|
|
}) || [];
|
|
|
|
|
let selfbooking =
|
|
|
|
|
ApiData?.[0]?.ChartDtl?.map((item) => {
|
|
|
|
|
return {
|
|
|
|
|
label: '',
|
|
|
|
|
value: 0,
|
|
|
|
|
date: item?.SalesDate,
|
|
|
|
|
};
|
|
|
|
|
}) || [];
|
|
|
|
|
console.log(DineInData, 'DineInData');
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
dispatch(getUserProfile({ UserId: UserId, ActiveStatus: 'A' })).unwrap();
|
|
|
|
|
}, [UserId]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (isInitialLoad && CompId && AppId && selection === 'dashboard') {
|
|
|
|
|
// debugger
|
|
|
|
|
if (dates && dates?.[0] && dates?.[1] && !initialDate) {
|
|
|
|
|
onRangeChange(dates, [
|
|
|
|
|
dates?.[0]?.format('DD-MM-YYYY'),
|
|
|
|
|
dates?.[1]?.format('DD-MM-YYYY'),
|
|
|
|
|
]);
|
|
|
|
|
} else {
|
|
|
|
|
setIsInitialLoad(false);
|
|
|
|
|
initializeData();
|
|
|
|
|
getInitialdataForPendingBills();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}, [CompId, AppId, isInitialLoad, selection, BranchId]);
|
|
|
|
|
|
|
|
|
|
const getInitialdataForPendingBills = async () => {
|
|
|
|
|
let data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
...(!selectedBranchForFilter ? { BranchId: BranchId } : {}),
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
console.log(data, 'getSalesHdrFn');
|
|
|
|
|
dispatch(getSalesHdr(data))
|
|
|
|
|
.unwrap()
|
|
|
|
|
.then((response) => {
|
|
|
|
|
if (response?.data?.statusCode === 1) {
|
|
|
|
|
setSalesHdr(response?.data?.data);
|
|
|
|
|
} else {
|
|
|
|
|
setSalesHdr([]);
|
|
|
|
|
console.error('Failed to fetch pre-order dashboard data');
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error('Error fetching pre-order dashboard:', error);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Initialize all data in proper sequence
|
|
|
|
|
const initializeData = async () => {
|
|
|
|
|
try {
|
|
|
|
|
// First fetch branch data as other calls depend on it
|
|
|
|
|
await fetchBranchData();
|
|
|
|
|
|
|
|
|
|
// Then fetch other data that doesn't depend on branch selection
|
|
|
|
|
await Promise.all([
|
|
|
|
|
fetchData(),
|
|
|
|
|
getAllProdId(),
|
|
|
|
|
topSellingProductsFn(),
|
|
|
|
|
CustPendingBalance(),
|
|
|
|
|
getExpdate(),
|
|
|
|
|
fetchApi(),
|
|
|
|
|
]);
|
|
|
|
|
setInitialFetchCompleted(true);
|
|
|
|
|
// Dashboard-specific data will be loaded by SingleBranchFlow or Dashboardshow
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error initializing dashboard data:', error);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Cleanup effect to handle component unmounting
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
return () => {
|
|
|
|
|
isMountedRef.current = false;
|
|
|
|
|
};
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (
|
|
|
|
|
BranchId != null &&
|
|
|
|
|
BranchId != undefined &&
|
|
|
|
|
CompBranchData?.length > 0 &&
|
|
|
|
|
!isLoadingBranchData
|
|
|
|
|
) {
|
|
|
|
|
// Set branch name if we have branch data
|
|
|
|
|
const currentBranch = CompBranchData?.filter(
|
|
|
|
|
(item) => item?.BrId == BranchId
|
|
|
|
|
)?.[0];
|
|
|
|
|
if (currentBranch) {
|
|
|
|
|
setBranchName(currentBranch.BrName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle single branch flow only if we have exactly one branch
|
|
|
|
|
if (CompBranchData?.length == 1) {
|
|
|
|
|
if (UserType != 'Super Admin User') {
|
|
|
|
|
SingleBranchFlow();
|
|
|
|
|
} else {
|
|
|
|
|
const checkData = SAdminUserData?.filter(
|
|
|
|
|
(item) =>
|
|
|
|
|
item?.AppId == AppId &&
|
|
|
|
|
item?.CompId == CompId &&
|
|
|
|
|
item?.BranchId == BranchId
|
|
|
|
|
);
|
|
|
|
|
if (
|
|
|
|
|
UserType == 'Super Admin User' &&
|
|
|
|
|
(checkData?.length == 0 || checkData?.[0]?.Status !== 'Y')
|
|
|
|
|
) {
|
|
|
|
|
userDropData();
|
|
|
|
|
setModal(true);
|
|
|
|
|
} else {
|
|
|
|
|
SingleBranchFlow();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}, [
|
|
|
|
|
BranchId,
|
|
|
|
|
CompBranchData,
|
|
|
|
|
isLoadingBranchData,
|
|
|
|
|
UserType,
|
|
|
|
|
AppId,
|
|
|
|
|
CompId,
|
|
|
|
|
SAdminUserData,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (
|
|
|
|
|
AppId &&
|
|
|
|
|
CompId &&
|
|
|
|
|
BranchId &&
|
|
|
|
|
dates &&
|
|
|
|
|
selection === 'top-selling-products'
|
|
|
|
|
) {
|
|
|
|
|
const data = {
|
|
|
|
|
AppId,
|
|
|
|
|
CompId,
|
|
|
|
|
BranchId,
|
|
|
|
|
pageNumber: 1,
|
|
|
|
|
FromDate: dates[0]?.format('YYYY-MM-DD') || intialFromDate,
|
|
|
|
|
ToDate: dates[1]?.format('YYYY-MM-DD') || intialToDate,
|
|
|
|
|
};
|
|
|
|
|
setPage(1);
|
|
|
|
|
fetchProducts(data);
|
|
|
|
|
setIsInitialLoad(true);
|
|
|
|
|
}
|
|
|
|
|
}, [selection]);
|
|
|
|
|
|
|
|
|
|
const userDropData = async () => {
|
|
|
|
|
const gettinguserDropDown = await dispatch(
|
|
|
|
|
UserDataBasedOnBranchId(seletedBranchData ? seletedBranchData : BranchId)
|
|
|
|
|
).unwrap();
|
|
|
|
|
if (gettinguserDropDown?.data?.statusCode === 1) {
|
|
|
|
|
let finaluserDropDown = gettinguserDropDown?.data?.data?.filter(
|
|
|
|
|
(value) => value.ActiveStatus === 'A'
|
|
|
|
|
);
|
|
|
|
|
setuserDropDown(finaluserDropDown);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const onComplete = useCallback(() => {
|
|
|
|
|
setMessageData(null);
|
|
|
|
|
setMessageType(null);
|
|
|
|
|
}, []);
|
|
|
|
|
const fetchApi = async () => {
|
|
|
|
|
let data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
BranchId: BranchId,
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
EmpId: UserId,
|
|
|
|
|
};
|
|
|
|
|
let response = await dispatch(getEmpAccess(data)).unwrap();
|
2026-01-29 10:15:06 +05:30
|
|
|
let datas = response?.data?.data?.[0]?.EmpAccessDetails?.filter((item) =>
|
|
|
|
|
['Add Product', 'Product Receipt', 'Daily Sales', 'Sales'].includes(
|
|
|
|
|
item.ConfigName
|
|
|
|
|
)
|
2026-01-27 18:27:29 +05:30
|
|
|
);
|
|
|
|
|
console.log(datas, 'ffsasasf');
|
|
|
|
|
setEmpData(datas);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getExpdate = async () => {
|
|
|
|
|
let data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
BranchId: BranchId,
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
};
|
|
|
|
|
let res = await dispatch(getAppSubscriptionDate(data)).unwrap();
|
|
|
|
|
|
|
|
|
|
if (res?.data?.statusCode === 1 && res?.data?.data?.length > 0) {
|
|
|
|
|
const remaining = res?.data?.data?.[0];
|
|
|
|
|
// let RemainingDays = expData?.RemainingDays;
|
|
|
|
|
// let RemainingHours=expData?.RemainingHours;
|
|
|
|
|
// let RemainingMinutes=expData?.RemainingMinutes;
|
|
|
|
|
// let RemainingSeconds=expData?.RemainingSeconds
|
|
|
|
|
|
|
|
|
|
const now = new Date();
|
|
|
|
|
|
|
|
|
|
const totalMs =
|
|
|
|
|
remaining.RemainingDays * 24 * 60 * 60 * 1000 +
|
|
|
|
|
remaining.RemainingHours * 60 * 60 * 1000 +
|
|
|
|
|
remaining.RemainingMinutes * 60 * 1000 +
|
|
|
|
|
remaining.RemainingSeconds * 1000;
|
|
|
|
|
|
|
|
|
|
const futureDate = new Date(now.getTime() + totalMs);
|
|
|
|
|
|
|
|
|
|
const formatted = ExtractDateFormate(
|
|
|
|
|
futureDate.toISOString().split('T')[0]
|
|
|
|
|
);
|
|
|
|
|
// futureDate.toLocaleString();
|
|
|
|
|
setExpiryDate(formatted);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const getSalesHdrFn = (FromDate, ToDate) => {
|
|
|
|
|
let today = new Date().toISOString().split('T')[0].split('-');
|
|
|
|
|
|
|
|
|
|
let data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
...(!selectedBranchForFilter ? { BranchId: BranchId } : {}),
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
FromDate: FromDate ? FromDate : `${today[0]}-${today[1]}-${today[2]}`,
|
|
|
|
|
ToDate: ToDate ? ToDate : `${today[0]}-${today[1]}-${today[2]}`,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
console.log(data, 'getSalesHdrFn');
|
|
|
|
|
dispatch(getSalesHdr(data))
|
|
|
|
|
.unwrap()
|
|
|
|
|
.then((response) => {
|
|
|
|
|
if (response?.data?.statusCode === 1) {
|
|
|
|
|
setSalesHdr(response?.data?.data);
|
|
|
|
|
} else {
|
|
|
|
|
setSalesHdr([]);
|
|
|
|
|
console.error('Failed to fetch pre-order dashboard data');
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error('Error fetching pre-order dashboard:', error);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getTopBuyingCustomers = (FromDate, ToDate) => {
|
|
|
|
|
let today = new Date().toISOString().split('T')[0].split('-');
|
|
|
|
|
|
|
|
|
|
let data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
BranchId: BranchId,
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
FromDate: FromDate ? FromDate : `${today[2]}-${today[1]}-${today[0]}`,
|
|
|
|
|
ToDate: ToDate ? ToDate : `${today[2]}-${today[1]}-${today[0]}`,
|
|
|
|
|
};
|
|
|
|
|
dispatch(getTopSellingCustomers(data))
|
|
|
|
|
.unwrap()
|
|
|
|
|
.then((response) => {
|
|
|
|
|
if (response?.data?.statusCode === 1) {
|
|
|
|
|
setTopsellingCus(response?.data?.data);
|
|
|
|
|
} else {
|
|
|
|
|
console.error('Failed to fetch pre-order dashboard data');
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error('Error fetching pre-order dashboard:', error);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getpreOrderDashBoardFn = (FromDate, ToDate) => {
|
|
|
|
|
let today = new Date().toISOString().split('T')[0].split('-');
|
|
|
|
|
|
|
|
|
|
let data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
...(!selectedBranchForFilter ? { BranchId: BranchId } : {}),
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
|
|
|
|
|
FromDate: FromDate ? FromDate : `${today[0]}-${today[1]}-${today[2]}`,
|
|
|
|
|
ToDate: ToDate ? ToDate : `${today[0]}-${today[1]}-${today[2]}`,
|
|
|
|
|
};
|
|
|
|
|
dispatch(getpreOrderDashBoard(data))
|
|
|
|
|
.unwrap()
|
|
|
|
|
.then((response) => {
|
|
|
|
|
if (response?.data?.statusCode === 1) {
|
|
|
|
|
setpreorderData(response?.data?.data);
|
|
|
|
|
} else {
|
|
|
|
|
console.error('Failed to fetch pre-order dashboard data');
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error('Error fetching pre-order dashboard:', error);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
const fetchBranchData = async () => {
|
|
|
|
|
// Prevent duplicate calls
|
|
|
|
|
if (isLoadingBranchData) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setIsLoadingBranchData(true);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
let data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
BranchId: BranchId,
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
UserId: UserId,
|
|
|
|
|
};
|
|
|
|
|
if (UserType === 'Super Admin' || UserType === 'Super Admin User') {
|
|
|
|
|
const response = await dispatch(
|
|
|
|
|
getCompBranchData({ CompId: CompId, AppId: AppId })
|
|
|
|
|
).unwrap();
|
|
|
|
|
if (response?.data?.statusCode === 1 && isMountedRef.current) {
|
|
|
|
|
setBranchName(
|
|
|
|
|
response?.data?.data?.filter((item) => item?.BrId == BranchId)?.[0]
|
|
|
|
|
?.BrName
|
|
|
|
|
);
|
|
|
|
|
setCompBranchData(response?.data?.data);
|
|
|
|
|
setIsmounted(false);
|
|
|
|
|
}
|
|
|
|
|
} else if (
|
|
|
|
|
UserType === 'Admin' ||
|
|
|
|
|
UserType === 'Admin User' ||
|
|
|
|
|
UserType == 'Employee'
|
|
|
|
|
) {
|
|
|
|
|
if (UserType == 'Employee') {
|
|
|
|
|
const EmpAcessRepsonse = await dispatch(
|
|
|
|
|
getEmpAccesData(data)
|
|
|
|
|
).unwrap();
|
|
|
|
|
setEmpAccess(EmpAcessRepsonse?.data?.data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const response = await dispatch(
|
|
|
|
|
getCompBranchData({ AppId: AppId, UserId: UserId, CompId: CompId })
|
|
|
|
|
).unwrap();
|
|
|
|
|
if (response?.data?.statusCode === 1 && isMountedRef.current) {
|
|
|
|
|
setBranchName(
|
|
|
|
|
response?.data?.data?.filter((item) => item?.BrId == BranchId)?.[0]
|
|
|
|
|
?.BrName
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
setCompBranchData(response?.data?.data);
|
|
|
|
|
if (response?.data?.data?.length > 1) {
|
|
|
|
|
setIsmounted(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log('Branch data fetched successfully:', response?.data?.data);
|
|
|
|
|
}
|
|
|
|
|
let AppDetails = await dispatch(
|
|
|
|
|
getPurchasedAppDetails({ AppId, UserId })
|
|
|
|
|
).unwrap();
|
|
|
|
|
//;
|
|
|
|
|
if (AppDetails?.data?.statusCode === 1 && isMountedRef.current) {
|
|
|
|
|
setAppDetails(AppDetails?.data?.data);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error fetching branch data:', error);
|
|
|
|
|
} finally {
|
|
|
|
|
setIsLoadingBranchData(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
let topSellingProductsFn = async () => {
|
|
|
|
|
const today = new Date();
|
|
|
|
|
const year = today.getFullYear();
|
|
|
|
|
const month = today.getMonth(); // 0-based: Jan = 0
|
|
|
|
|
|
|
|
|
|
// Last day of the current month
|
|
|
|
|
const lastDay = new Date(year, month + 1, 0); // 0 = last day of previous month
|
|
|
|
|
|
|
|
|
|
const formatDate = (date) =>
|
|
|
|
|
`${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
|
|
|
|
|
|
|
|
|
|
const data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
BranchId: BranchId,
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
FromDate: `${year}-${String(month + 1).padStart(2, '0')}-01`, // First day
|
|
|
|
|
ToDate: formatDate(lastDay), // e.g. 2025-07-31
|
|
|
|
|
};
|
|
|
|
|
dispatch(getTopSellingProduct(data))
|
|
|
|
|
.unwrap()
|
|
|
|
|
.then((response) => {
|
|
|
|
|
if (response?.data?.statusCode === 1) {
|
|
|
|
|
setTopSellingProducts(response?.data?.data);
|
|
|
|
|
} else {
|
|
|
|
|
console.error('Failed to fetch top selling products');
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error('Error fetching top selling products:', error);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
const CustPendingBalance = () => {
|
|
|
|
|
dispatch(
|
|
|
|
|
getAllCustomerPendingBalance({
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
BranchId: BranchId,
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
})
|
|
|
|
|
)
|
|
|
|
|
.unwrap()
|
|
|
|
|
.then((response) => {
|
|
|
|
|
if (response?.data?.statusCode === 1) {
|
|
|
|
|
setcustomerPendingBalance(response?.data?.data);
|
|
|
|
|
} else {
|
|
|
|
|
console.error('Failed to fetch top selling products');
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error('Error fetching top selling products:', error);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getAllProdId = async (branchId) => {
|
|
|
|
|
let data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
...(selectedBranchForFilter !== 'all'
|
|
|
|
|
? { BranchId: branchId || BranchId }
|
|
|
|
|
: {}),
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
};
|
|
|
|
|
let response = await dispatch(getAllprodIds(data)).unwrap();
|
|
|
|
|
|
|
|
|
|
if ((response.data.statusCode = 1)) {
|
|
|
|
|
setAllProdIds(response.data.data);
|
|
|
|
|
} else {
|
|
|
|
|
setAllProdIds([]);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (selectedBranchForFilter && initialFetchCompleted) {
|
|
|
|
|
getAllProdId(selectedBranchForFilter);
|
|
|
|
|
}
|
|
|
|
|
}, [selectedBranchForFilter]);
|
|
|
|
|
|
|
|
|
|
const fetchData = async () => {
|
|
|
|
|
try {
|
|
|
|
|
const [expireRes, lowStockRes] = await Promise.all([
|
|
|
|
|
dispatch(
|
|
|
|
|
getExpireProductsList({
|
|
|
|
|
compId: CompId,
|
|
|
|
|
...(!selectedBranchForFilter ? { branchId: BranchId } : {}),
|
|
|
|
|
appId: AppId,
|
|
|
|
|
})
|
|
|
|
|
)?.unwrap(),
|
|
|
|
|
dispatch(
|
|
|
|
|
getLowStockAlertProductsList({
|
|
|
|
|
compId: CompId,
|
|
|
|
|
...(!selectedBranchForFilter ? { branchId: BranchId } : {}),
|
|
|
|
|
appId: AppId,
|
|
|
|
|
})
|
|
|
|
|
)?.unwrap(),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
if (expireRes?.data?.statusCode === 1) {
|
|
|
|
|
setExpiredList(expireRes?.data?.data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lowStockRes?.data?.statusCode === 1) {
|
|
|
|
|
setLowStock(lowStockRes?.data?.data);
|
|
|
|
|
}
|
|
|
|
|
} catch (err) {
|
|
|
|
|
// setMessage({ type: 'error', data: 'API failed' });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const datasets = [
|
|
|
|
|
dinePreference && {
|
|
|
|
|
name: 'Dine In',
|
|
|
|
|
color: '#978FED',
|
|
|
|
|
data: DineInData,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: takeAwayPreference ? 'Takeaway' : 'Sales',
|
|
|
|
|
color: '#EE89DF',
|
|
|
|
|
data: TakeAway,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
name: 'Self booking',
|
|
|
|
|
color: '#F6CF7D',
|
|
|
|
|
data: selfbooking,
|
|
|
|
|
},
|
|
|
|
|
].filter(Boolean);
|
|
|
|
|
|
|
|
|
|
const UserDropDownChange = async (e) => {
|
|
|
|
|
setSelectedUserData(e);
|
|
|
|
|
};
|
|
|
|
|
const handlePageChange = async () => {
|
|
|
|
|
if (CompBranchData?.length === 1) {
|
|
|
|
|
const commonUrl = import.meta.env.ENV_COMMON_BASE_URL;
|
|
|
|
|
|
|
|
|
|
const MobileNo = encryptedValuesUrlFun(getSession('MobileNo'));
|
|
|
|
|
const userName = encryptedValuesUrlFun(getSession('userName'));
|
|
|
|
|
const UserId = encryptedValuesUrlFun(getSession('UserId'));
|
|
|
|
|
const UserType = encryptedValuesUrlFun(getSession('UserType'));
|
|
|
|
|
const CompId = encryptedValuesUrlFun(getSession('CompId'));
|
|
|
|
|
const CompName = encryptedValuesUrlFun(getSession('CompName'));
|
|
|
|
|
const SessionId = encryptedValuesUrlFun(getSession('SessionId'));
|
|
|
|
|
|
|
|
|
|
if (sessionStorage.getItem('BranchId') !== null) {
|
|
|
|
|
clearSession('BranchId');
|
|
|
|
|
}
|
|
|
|
|
if (sessionStorage.getItem('AppId') !== null) {
|
|
|
|
|
clearSession('AppId');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const param = {
|
|
|
|
|
MN: MobileNo,
|
|
|
|
|
UN: userName,
|
|
|
|
|
UD: UserId,
|
|
|
|
|
UT: UserType,
|
|
|
|
|
CD: CompId,
|
|
|
|
|
CN: CompName,
|
|
|
|
|
SD: SessionId,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const queryParams = new URLSearchParams(param).toString();
|
|
|
|
|
window.location.replace(
|
|
|
|
|
`${commonUrl}/home/landing-page/home?${queryParams}`
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
setseletedBranchData();
|
|
|
|
|
if (sessionStorage.getItem('BranchId') !== null) {
|
|
|
|
|
clearSession('BranchId');
|
|
|
|
|
}
|
|
|
|
|
navigate(`${subDirectory}app-page/branch-login`);
|
|
|
|
|
}
|
|
|
|
|
if (sessionStorage.getItem('hasRefreshed') !== null) {
|
|
|
|
|
sessionStorage.removeItem('hasRefreshed');
|
|
|
|
|
}
|
|
|
|
|
setModal(false);
|
|
|
|
|
};
|
|
|
|
|
const handleUserProfile = () => {
|
|
|
|
|
setUserprofile((prev) => !prev);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleChange = (index, event) => {
|
|
|
|
|
const value = event.target.value;
|
|
|
|
|
|
|
|
|
|
if (/^\d$/.test(value)) {
|
|
|
|
|
const newPin = [...pin];
|
|
|
|
|
newPin[index] = value;
|
|
|
|
|
setPin(newPin);
|
|
|
|
|
|
|
|
|
|
if (index < inputRefs?.current?.length - 1) {
|
|
|
|
|
inputRefs?.current[index + 1]?.focus(); // Move to next input
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (newPin.every((num) => num !== '')) {
|
|
|
|
|
handleSubmit(newPin.join('')); // Call function when all 4 digits are entered
|
|
|
|
|
} // Call function when all 4 digits are entered
|
|
|
|
|
} else {
|
|
|
|
|
event.target.value = '';
|
|
|
|
|
const newPin = [...pin];
|
|
|
|
|
newPin[index] = value;
|
|
|
|
|
setPin(newPin); // Clear input if more than one digit is entered
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleKeyDown = (index, event) => {
|
|
|
|
|
if (event.key === 'Backspace' && index > 0 && !event.target.value) {
|
|
|
|
|
inputRefs?.current[index - 1]?.focus(); // Move to previous input on backspace
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleSubmit = async (enteredPin) => {
|
|
|
|
|
if (otp == Number(enteredPin)) {
|
|
|
|
|
let data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
BranchId:
|
|
|
|
|
seletedBranchData != null && seletedBranchData != undefined
|
|
|
|
|
? seletedBranchData
|
|
|
|
|
: BranchId,
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
UserId: UserId,
|
|
|
|
|
SignInType: SelectTypeName,
|
|
|
|
|
SecurityCode: Number(enteredPin),
|
|
|
|
|
UpdatedBy: UserId,
|
|
|
|
|
SessionId: sessionId,
|
|
|
|
|
EmpId: selectedUserData,
|
|
|
|
|
};
|
|
|
|
|
let response = await dispatch(PUTLoginuser(data)).unwrap();
|
|
|
|
|
if (response?.data?.statusCode == 1) {
|
|
|
|
|
await dispatch(checkSession({ UserId, sessionId })).unwrap();
|
|
|
|
|
setModal(false);
|
|
|
|
|
inputRefs?.current.forEach((ref) => {
|
|
|
|
|
if (ref) {
|
|
|
|
|
ref.value = '';
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
setPin(['', '', '', '']);
|
|
|
|
|
SingleBranchFlow();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
alert(`Invalid ${SelectType == 'O' ? 'OTP' : 'Pin'}`);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const ChangeMethod = (e) => {
|
|
|
|
|
setSelectType(e);
|
|
|
|
|
setSelectTypeName(e === 'O' ? 'OTP' : 'PIN');
|
|
|
|
|
};
|
|
|
|
|
const sentpinfn = async () => {
|
|
|
|
|
let data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
BranchId:
|
|
|
|
|
seletedBranchData != null && seletedBranchData != undefined
|
|
|
|
|
? seletedBranchData
|
|
|
|
|
: BranchId,
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
UserId: UserId,
|
|
|
|
|
SignInType: SelectTypeName,
|
|
|
|
|
CreatedBy: UserId,
|
|
|
|
|
EmpId: selectedUserData,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let response = await dispatch(PostLoginSuser(data)).unwrap();
|
|
|
|
|
|
|
|
|
|
if (response?.data?.statusCode == 1) {
|
|
|
|
|
setOtp(response?.data?.OTP || response?.data?.PIN);
|
|
|
|
|
setpinInput(true); // Show PIN/OTP input fields
|
|
|
|
|
setSeconds(timerDuration); // Start the countdown timer
|
|
|
|
|
setDisabled(true); // Disable the button temporarily
|
|
|
|
|
if (SelectTypeName === 'OTP') {
|
|
|
|
|
setFirstTimeOtp(true); // Set OTP as sent
|
|
|
|
|
} else {
|
|
|
|
|
setFirstTimePin(true); // Set PIN as sent
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const handleClick = async () => {
|
|
|
|
|
if (selectedUserData) {
|
|
|
|
|
if (clicked.current) return;
|
|
|
|
|
clicked.current = true;
|
|
|
|
|
if (seconds === 0) {
|
|
|
|
|
// Disable the button temporarily
|
|
|
|
|
|
|
|
|
|
sentpinfn(); // Resend PIN/OTP after 30 seconds
|
|
|
|
|
}
|
|
|
|
|
inputRefs?.current.forEach((ref) => {
|
|
|
|
|
if (ref) {
|
|
|
|
|
ref.value = ''; // Reset the value of each input
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
setPin(['', '', '', '']);
|
|
|
|
|
} else {
|
|
|
|
|
alert('Please select user');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const SingleBranchFlow = async () => {
|
|
|
|
|
try {
|
|
|
|
|
let data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
BranchId: BranchId ? BranchId : globalbranchid,
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let res = await dispatch(getPreferenceData(data)).unwrap();
|
|
|
|
|
setIsmounted(false);
|
|
|
|
|
const filteredDatas = res?.data?.data?.[0]?.SettingDtlDetails?.filter(
|
|
|
|
|
(item) =>
|
|
|
|
|
item.SettingIdName?.toLowerCase() === 'dashboard' &&
|
|
|
|
|
item.SettingValue === 'N'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (!RedirectStatus && filteredDatas?.length > 0) {
|
|
|
|
|
if (
|
|
|
|
|
res?.data?.data?.[0]?.SettingDtlDetails.find(
|
|
|
|
|
(item) => item.SettingIdName === 'Dashboard'
|
|
|
|
|
)?.SettingValue === 'N'
|
|
|
|
|
) {
|
|
|
|
|
if (UserType !== 'Employee') {
|
|
|
|
|
dispatch(ChangeRedirectStatus(true));
|
|
|
|
|
// await dispatch(getTemplate({ CompId, BranchId, AppId })).unwrap();
|
|
|
|
|
navigate(`${subDirectory}sales`);
|
|
|
|
|
} else if (
|
|
|
|
|
EmpAcces?.length > 0 &&
|
|
|
|
|
EmpAcces?.[0]?.EmpAccessDetails?.find(
|
|
|
|
|
(item) => item?.ConfigName === 'Sales'
|
|
|
|
|
)?.ReadAccess === 'Y'
|
|
|
|
|
) {
|
|
|
|
|
dispatch(ChangeRedirectStatus(true));
|
|
|
|
|
// await dispatch(getTemplate({ CompId, BranchId, AppId })).unwrap();
|
|
|
|
|
navigate(`${subDirectory}sales`);
|
|
|
|
|
} else {
|
|
|
|
|
// Only call Dashboardshow if not already loading
|
|
|
|
|
if (!isLoadingDashboard) {
|
|
|
|
|
Dashboardshow();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Only call Dashboardshow if not already loading
|
|
|
|
|
if (!isLoadingDashboard) {
|
|
|
|
|
Dashboardshow();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Only call Dashboardshow if not already loading
|
|
|
|
|
if (!isLoadingDashboard) {
|
|
|
|
|
Dashboardshow();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error in SingleBranchFlow:', error);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (SessionData && CompId && BranchId && AppId && !isInitialLoad) {
|
|
|
|
|
Dashboardshow();
|
|
|
|
|
}
|
|
|
|
|
}, [SessionData, CompId, BranchId, AppId, isInitialLoad]);
|
|
|
|
|
|
|
|
|
|
const Dashboardshow = async () => {
|
|
|
|
|
// Prevent duplicate calls and only call Dashboardshow if not already loading
|
|
|
|
|
if (isLoadingDashboard) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setIsLoadingDashboard(true);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
let data;
|
|
|
|
|
if (UserType === 'Employee') {
|
|
|
|
|
data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
...(!selectedBranchForFilter ? { BranchId: BranchId } : {}),
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
UserId: UserId,
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
...(!selectedBranchForFilter ? { BranchId: BranchId } : {}),
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
console.log(data, 'data');
|
|
|
|
|
|
|
|
|
|
let response = await dispatch(getdashboard(data)).unwrap();
|
|
|
|
|
if (isMountedRef.current) {
|
|
|
|
|
setApiData(response?.data?.data);
|
|
|
|
|
setPiedat(response?.data?.data);
|
|
|
|
|
setResponseData(response?.data?.statusCode);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error fetching dashboard data:', error);
|
|
|
|
|
} finally {
|
|
|
|
|
setIsLoadingDashboard(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const dateFormat = 'DD-MM-YYYY';
|
|
|
|
|
|
|
|
|
|
const onChangeBranchFilter = async (branchId) => {
|
|
|
|
|
if (isLoadingBranchFilter) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setIsLoadingBranchFilter(true);
|
|
|
|
|
setSelectedBranchForFilter(branchId);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (branchId === 'all') {
|
|
|
|
|
await fetchAllBranchesData();
|
|
|
|
|
} else {
|
|
|
|
|
await fetchSingleBranchData(branchId);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error changing branch filter:', error);
|
|
|
|
|
} finally {
|
|
|
|
|
setIsLoadingBranchFilter(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const fetchAllBranchesData = async () => {
|
|
|
|
|
try {
|
|
|
|
|
if (!CompBranchData || CompBranchData.length === 0) return;
|
|
|
|
|
|
|
|
|
|
let data;
|
|
|
|
|
if (UserType === 'Employee') {
|
|
|
|
|
data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
UserId: UserId,
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
data = { CompId: CompId, AppId: AppId };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let response = await dispatch(getdashboard(data)).unwrap();
|
|
|
|
|
if (response?.data?.statusCode === 1) {
|
|
|
|
|
setApiData(response?.data?.data);
|
|
|
|
|
setPiedat(response?.data?.data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setApiData(response?.data?.data);
|
|
|
|
|
setPiedat(response?.data?.data);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error fetching all branches data:', error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Also refresh other data for all branches
|
|
|
|
|
getpreOrderDashBoardFnAllBranches();
|
|
|
|
|
getTopBuyingCustomersAllBranches();
|
|
|
|
|
getSalesHdrFnAllBranches();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const fetchSingleBranchData = async (branchId) => {
|
|
|
|
|
let data;
|
|
|
|
|
if (UserType === 'Employee') {
|
|
|
|
|
data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
BranchId: branchId,
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
UserId: UserId,
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
data = { CompId: CompId, BranchId: branchId, AppId: AppId };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let response = await dispatch(getdashboard(data)).unwrap();
|
|
|
|
|
setApiData(response?.data?.data);
|
|
|
|
|
setPiedat(response?.data?.data);
|
|
|
|
|
|
|
|
|
|
// Also refresh other data
|
|
|
|
|
getpreOrderDashBoardFn();
|
|
|
|
|
getTopBuyingCustomers();
|
|
|
|
|
getSalesHdrFn();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Function to aggregate data from multiple branches
|
|
|
|
|
const aggregateBranchData = (branchDataArray) => {
|
|
|
|
|
const aggregated = {
|
|
|
|
|
DineInOrderCount: 0,
|
|
|
|
|
TakeAwayOrderCount: 0,
|
|
|
|
|
SelfTakeAwayOrderCount: 0,
|
|
|
|
|
OverAllSalesAmt: 0,
|
|
|
|
|
OverAllDineInAmount: 0,
|
|
|
|
|
OverAllTakeAwayAmount: 0,
|
|
|
|
|
ChartDtl: [],
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
branchDataArray.forEach((branchData) => {
|
|
|
|
|
if (branchData) {
|
|
|
|
|
aggregated.DineInOrderCount += branchData.DineInOrderCount || 0;
|
|
|
|
|
aggregated.TakeAwayOrderCount += branchData.TakeAwayOrderCount || 0;
|
|
|
|
|
aggregated.SelfTakeAwayOrderCount +=
|
|
|
|
|
branchData.SelfTakeAwayOrderCount || 0;
|
|
|
|
|
aggregated.OverAllSalesAmt += branchData.OverAllSalesAmt || 0;
|
|
|
|
|
aggregated.OverAllDineInAmount += branchData.OverAllDineInAmount || 0;
|
|
|
|
|
aggregated.OverAllTakeAwayAmount +=
|
|
|
|
|
branchData.OverAllTakeAwayAmount || 0;
|
|
|
|
|
|
|
|
|
|
// Merge chart data (you might want to customize this based on your needs)
|
|
|
|
|
if (branchData.ChartDtl && branchData.ChartDtl.length > 0) {
|
|
|
|
|
aggregated.ChartDtl = aggregated.ChartDtl.concat(branchData.ChartDtl);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return aggregated;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Helper functions for fetching data from all branches
|
|
|
|
|
const getpreOrderDashBoardFnAllBranches = async (FromDate, ToDate) => {
|
|
|
|
|
if (!CompBranchData || CompBranchData.length === 0) return;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
let today = new Date().toISOString().split('T')[0].split('-');
|
|
|
|
|
let data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
...(!selectedBranchForFilter ? { BranchId: BranchId } : {}),
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
FromDate: FromDate ? FromDate : `${today[0]}-${today[1]}-${today[2]}`,
|
|
|
|
|
ToDate: ToDate ? ToDate : `${today[0]}-${today[1]}-${today[2]}`,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const response = await dispatch(getpreOrderDashBoard(data)).unwrap();
|
|
|
|
|
if (response?.data?.statusCode === 1) {
|
|
|
|
|
setpreorderData(response?.data?.data);
|
|
|
|
|
} else {
|
|
|
|
|
setpreorderData([]);
|
|
|
|
|
console.error('Failed to fetch pre-order dashboard data');
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error fetching preorder data for all branches:', error);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getTopBuyingCustomersAllBranches = async (FromDate, ToDate) => {
|
|
|
|
|
if (!CompBranchData || CompBranchData.length === 0) return;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const allBranchPromises = CompBranchData.map(async (branch) => {
|
|
|
|
|
let today = new Date().toISOString().split('T')[0].split('-');
|
|
|
|
|
let data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
BranchId: branch.BrId,
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
FromDate: FromDate ? FromDate : `${today[2]}-${today[1]}-${today[0]}`,
|
|
|
|
|
ToDate: ToDate ? ToDate : `${today[2]}-${today[1]}-${today[0]}`,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const response = await dispatch(getTopSellingCustomers(data)).unwrap();
|
|
|
|
|
return response?.data?.data || [];
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const allBranchData = await Promise.all(allBranchPromises);
|
|
|
|
|
|
|
|
|
|
// Flatten and merge customer data from all branches
|
|
|
|
|
const allCustomers = allBranchData.flat();
|
|
|
|
|
|
|
|
|
|
// Group by customer and sum amounts
|
|
|
|
|
const customerMap = {};
|
|
|
|
|
allCustomers.forEach((customer) => {
|
|
|
|
|
if (customer.CustName) {
|
|
|
|
|
if (customerMap[customer.CustName]) {
|
|
|
|
|
customerMap[customer.CustName].TotalSalesAmount +=
|
|
|
|
|
customer.TotalSalesAmount || 0;
|
|
|
|
|
} else {
|
|
|
|
|
customerMap[customer.CustName] = { ...customer };
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Convert back to array and sort by total sales
|
|
|
|
|
const aggregatedCustomers = Object.values(customerMap)
|
|
|
|
|
.sort((a, b) => (b.TotalSalesAmount || 0) - (a.TotalSalesAmount || 0))
|
|
|
|
|
.slice(0, 10); // Top 10 customers
|
|
|
|
|
|
|
|
|
|
setTopsellingCus(aggregatedCustomers);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error fetching top customers for all branches:', error);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getSalesHdrFnAllBranches = async (FromDate, ToDate) => {
|
|
|
|
|
if (!CompBranchData || CompBranchData.length === 0) return;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
let today = new Date().toISOString().split('T')[0].split('-');
|
|
|
|
|
let data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
...(!selectedBranchForFilter ? { BranchId: BranchId } : {}),
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
FromDate: FromDate ? FromDate : `${today[0]}-${today[1]}-${today[2]}`,
|
|
|
|
|
ToDate: ToDate ? ToDate : `${today[0]}-${today[1]}-${today[2]}`,
|
|
|
|
|
};
|
|
|
|
|
const response = await dispatch(getSalesHdr(data)).unwrap();
|
|
|
|
|
setSalesHdr(response?.data?.data);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error fetching sales header for all branches:', error);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onRangeChange = async (dates, dateStrings) => {
|
|
|
|
|
SetZero(true);
|
|
|
|
|
let fromDateVal = dateStrings[0]?.split('-');
|
|
|
|
|
let toDateVal = dateStrings[1]?.split('-');
|
|
|
|
|
setDates(dates);
|
|
|
|
|
setInitialDate(false);
|
|
|
|
|
if (dates && selection === 'dashboard') {
|
|
|
|
|
const fromDate =
|
|
|
|
|
fromDateVal[2] + '-' + fromDateVal[1] + '-' + fromDateVal[0];
|
|
|
|
|
const toDate = toDateVal[2] + '-' + toDateVal[1] + '-' + toDateVal[0];
|
|
|
|
|
|
|
|
|
|
if (selectedBranchForFilter === 'all') {
|
|
|
|
|
// Fetch data for all branches with date range
|
|
|
|
|
await fetchAllBranchesDataWithDateRange(fromDate, toDate);
|
|
|
|
|
} else {
|
|
|
|
|
// Fetch data for specific branch with date range
|
|
|
|
|
await fetchSingleBranchDataWithDateRange(
|
|
|
|
|
selectedBranchForFilter ? selectedBranchForFilter : BranchId,
|
|
|
|
|
fromDate,
|
|
|
|
|
toDate
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
getpreOrderDashBoardFn();
|
|
|
|
|
} else if (selection === 'top-selling-products') {
|
|
|
|
|
const FromDate = dates?.[0]?.format('YYYY-MM-DD') || intialFromDate;
|
|
|
|
|
const ToDate = dates?.[1]?.format('YYYY-MM-DD') || intialToDate;
|
|
|
|
|
await fetchProducts({
|
|
|
|
|
AppId,
|
|
|
|
|
CompId,
|
|
|
|
|
BranchId,
|
|
|
|
|
FromDate,
|
|
|
|
|
ToDate,
|
|
|
|
|
pageNumber: 1,
|
|
|
|
|
});
|
|
|
|
|
setPage(1);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const fetchProducts = async (data) => {
|
|
|
|
|
setLoading(true);
|
|
|
|
|
try {
|
|
|
|
|
const res = await dispatch(getTopSellingProduct(data))?.unwrap();
|
|
|
|
|
if (res?.data?.statusCode === 1 && res?.data?.data?.length > 0) {
|
|
|
|
|
setProducts(res?.data?.data);
|
|
|
|
|
setTotalPages(Math.ceil(res?.data?.data?.[0]?.TotalCount / 10));
|
|
|
|
|
} else {
|
|
|
|
|
setProducts([]);
|
|
|
|
|
setTotalPages(0);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error fetching products:', error);
|
|
|
|
|
}
|
|
|
|
|
setLoading(false);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const fetchAllBranchesDataWithDateRange = async (fromDate, toDate) => {
|
|
|
|
|
try {
|
|
|
|
|
let data;
|
|
|
|
|
if (UserType === 'Employee') {
|
|
|
|
|
data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
...(!selectedBranchForFilter ? { BranchId: BranchId } : {}),
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
FromDate: fromDate,
|
|
|
|
|
ToDate: toDate,
|
|
|
|
|
UserId: UserId,
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
...(!selectedBranchForFilter ? { BranchId: BranchId } : {}),
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
FromDate: fromDate,
|
|
|
|
|
ToDate: toDate,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
const response = await dispatch(getdashboarddate(data)).unwrap();
|
|
|
|
|
if (response?.data?.statusCode === 1) {
|
|
|
|
|
setDateApiData(response?.data?.data);
|
|
|
|
|
setApiData(response?.data?.data);
|
|
|
|
|
} else {
|
|
|
|
|
setDateApiData([]);
|
|
|
|
|
setApiData([]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// const allBranchData = await Promise.all(allBranchPromises);
|
|
|
|
|
|
|
|
|
|
// // Aggregate the data from all branches
|
|
|
|
|
// const aggregatedData = aggregateBranchData(allBranchData);
|
|
|
|
|
// setDateApiData([aggregatedData]);
|
|
|
|
|
// setApiData([aggregatedData]);
|
|
|
|
|
// setPiedat([aggregatedData]);
|
|
|
|
|
|
|
|
|
|
// Also refresh other data for all branches with date range
|
|
|
|
|
getpreOrderDashBoardFnAllBranches(fromDate, toDate);
|
|
|
|
|
getTopBuyingCustomersAllBranches(fromDate, toDate);
|
|
|
|
|
getSalesHdrFnAllBranches(fromDate, toDate);
|
|
|
|
|
getSalesHdrFn(fromDate, toDate);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error fetching all branches data with date range:', error);
|
|
|
|
|
setDateApiData([]);
|
|
|
|
|
setApiData([]);
|
|
|
|
|
setPiedat([]);
|
|
|
|
|
setpreorderData([]);
|
|
|
|
|
setTopsellingCus([]);
|
|
|
|
|
setSalesHdr([]);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Function to fetch data for single branch with date range
|
|
|
|
|
const fetchSingleBranchDataWithDateRange = async (
|
|
|
|
|
branchId,
|
|
|
|
|
fromDate,
|
|
|
|
|
toDate
|
|
|
|
|
) => {
|
|
|
|
|
try {
|
|
|
|
|
const targetBranchId = branchId === 'all' ? BranchId : branchId;
|
|
|
|
|
|
|
|
|
|
let data;
|
|
|
|
|
if (UserType === 'Employee') {
|
|
|
|
|
data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
BranchId: targetBranchId,
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
FromDate: fromDate,
|
|
|
|
|
ToDate: toDate,
|
|
|
|
|
UserId: UserId,
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
data = {
|
|
|
|
|
CompId: CompId,
|
|
|
|
|
BranchId: targetBranchId,
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
FromDate: fromDate,
|
|
|
|
|
ToDate: toDate,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
let response = await dispatch(getdashboarddate(data)).unwrap();
|
|
|
|
|
if (response?.data?.statusCode === 1) {
|
|
|
|
|
setDateApiData(response?.data?.data);
|
|
|
|
|
setApiData(response?.data?.data);
|
|
|
|
|
setPiedat(response?.data?.data);
|
|
|
|
|
getpreOrderDashBoardFn(fromDate, toDate);
|
|
|
|
|
getTopBuyingCustomers(fromDate, toDate);
|
|
|
|
|
getSalesHdrFn(fromDate, toDate);
|
|
|
|
|
} else {
|
|
|
|
|
setDateApiData([]);
|
|
|
|
|
setApiData([]);
|
|
|
|
|
setPiedat([]);
|
|
|
|
|
setpreorderData([]);
|
|
|
|
|
setTopsellingCus([]);
|
|
|
|
|
setSalesHdr([]);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(
|
|
|
|
|
'Error fetching single branch data with date range:',
|
|
|
|
|
error
|
|
|
|
|
);
|
|
|
|
|
setDateApiData([]);
|
|
|
|
|
setApiData([]);
|
|
|
|
|
setPiedat([]);
|
|
|
|
|
setpreorderData([]);
|
|
|
|
|
setTopsellingCus([]);
|
|
|
|
|
setSalesHdr([]);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const disabledDate = (current) => {
|
|
|
|
|
const today = dayjs().endOf('day');
|
|
|
|
|
const firstSalesDate = ApiData?.[0]?.Firstsalesdate;
|
|
|
|
|
|
|
|
|
|
// If firstSalesDate exists and is valid, use it as minimum date
|
|
|
|
|
if (firstSalesDate) {
|
|
|
|
|
const minDate = dayjs(firstSalesDate).startOf('day');
|
|
|
|
|
return current && (current < minDate || current > today);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If no firstSalesDate, disable future dates only
|
|
|
|
|
return current && current > today;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const handleResize = () => {
|
|
|
|
|
setCollapse(window.innerWidth < 768);
|
|
|
|
|
};
|
|
|
|
|
window.addEventListener('resize', handleResize);
|
|
|
|
|
return () => window.removeEventListener('resize', handleResize);
|
|
|
|
|
}, []);
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const handleClickOutside = (event) => {
|
|
|
|
|
if (
|
|
|
|
|
userProfileRef.current &&
|
|
|
|
|
!userProfileRef.current.contains(event.target)
|
|
|
|
|
) {
|
|
|
|
|
setUserprofile(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
document.addEventListener('mousedown', handleClickOutside);
|
|
|
|
|
return () => {
|
|
|
|
|
document.removeEventListener('mousedown', handleClickOutside);
|
|
|
|
|
};
|
|
|
|
|
}, [userProfileRef]);
|
|
|
|
|
|
|
|
|
|
const Logout = async () => {
|
|
|
|
|
const status = 'N'; // replace with your actual status
|
|
|
|
|
const res = await dispatch(GenerateLogout({ UserId, status })).unwrap();
|
|
|
|
|
if (res?.data?.statusCode === 1) {
|
|
|
|
|
sessionStorage.clear();
|
|
|
|
|
window.location.replace(`${commonUrl}`);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
if (ismounted)
|
|
|
|
|
return (
|
|
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
position: 'fixed',
|
|
|
|
|
top: '0',
|
|
|
|
|
left: '0',
|
|
|
|
|
right: '0',
|
|
|
|
|
bottom: '0',
|
|
|
|
|
height: '100vh',
|
|
|
|
|
width: '100vw',
|
|
|
|
|
backgroundColor: '#fff',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Loader />
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const handleSelectChange = (value) => {
|
|
|
|
|
setSelection(value);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="RetailDashboard-Master">
|
|
|
|
|
<div className="dashboardHeader">
|
|
|
|
|
<Messages
|
|
|
|
|
messageType={messageType}
|
|
|
|
|
messageData={messageData}
|
|
|
|
|
onComplete={onComplete}
|
|
|
|
|
/>
|
|
|
|
|
<div className="shopName">
|
|
|
|
|
<div>{branchName}</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="dashboareduser">
|
|
|
|
|
<div>
|
|
|
|
|
{(() => {
|
|
|
|
|
if (!ExpiryDate) return null;
|
|
|
|
|
const today = new Date();
|
|
|
|
|
const expiryDate = new Date(ExpiryDate);
|
|
|
|
|
const timeDiff = expiryDate.getTime() - today.getTime();
|
|
|
|
|
const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24));
|
|
|
|
|
|
|
|
|
|
if (daysDiff <= 7 && daysDiff >= 0) {
|
|
|
|
|
return (
|
|
|
|
|
<div>
|
|
|
|
|
<img src={sandClock} alt="" width={25} />
|
|
|
|
|
|
|
|
|
|
{PricingAppPricingName?.[0]?.PricingName && (
|
|
|
|
|
<div className="infoplan">
|
|
|
|
|
Current Plan:{' '}
|
|
|
|
|
{PricingAppPricingName?.[0]?.PricingName +
|
|
|
|
|
' / ' +
|
|
|
|
|
PricingAppPricingName?.[0]?.Type}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
<div className="infoplan">Plan Expiry on {ExpiryDate}</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
})()}
|
|
|
|
|
</div>
|
|
|
|
|
<div className="userShortName" onClick={handleUserProfile}>
|
|
|
|
|
{(AppDetails?.[0]?.UserName || 'Guest')
|
|
|
|
|
?.substring(0, 2)
|
|
|
|
|
?.toUpperCase()}
|
|
|
|
|
</div>
|
|
|
|
|
{userprofile && (
|
|
|
|
|
<BSNavBarUserInfo
|
|
|
|
|
isOpen={userprofile}
|
|
|
|
|
divRef={userProfileRef}
|
|
|
|
|
userProfileData={{
|
|
|
|
|
UserImage: user,
|
|
|
|
|
UserName: AppDetails?.[0]?.UserName,
|
|
|
|
|
MobileNo: AppDetails?.[0]?.MobileNo,
|
|
|
|
|
}}
|
|
|
|
|
Logout={Logout}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
className={`dashboardHeader2${selection === 'top-selling-products' ? ' top' : ''}`}
|
|
|
|
|
>
|
|
|
|
|
{/* <div style={{ fontSize: '18px', fontWeight: '500' }}>Dashboard</div> */}
|
|
|
|
|
{/* public Login dashboard*/}
|
|
|
|
|
<div className="tab-switcher">
|
|
|
|
|
{tabs?.map((tab) => (
|
|
|
|
|
<button
|
|
|
|
|
key={tab.value}
|
|
|
|
|
className={`tab-button ${selection === tab?.value ? 'active' : ''}`}
|
|
|
|
|
onClick={() => handleSelectChange(tab?.value)}
|
|
|
|
|
>
|
|
|
|
|
{tab.label}
|
|
|
|
|
</button>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Branch Filter Dropdown */}
|
|
|
|
|
{CompBranchData?.length > 1 && selection !== 'top-selling-products' && (
|
|
|
|
|
<div className="branch-filter-dropdown">
|
|
|
|
|
<DropDowns
|
|
|
|
|
options={[
|
|
|
|
|
{ value: 'all', label: 'All Branches' },
|
|
|
|
|
...CompBranchData?.map((option) => ({
|
|
|
|
|
value: option.BrId,
|
|
|
|
|
label: option.BrName,
|
|
|
|
|
})),
|
|
|
|
|
]}
|
|
|
|
|
className="branch-filter-select"
|
|
|
|
|
onChangeFunction={onChangeBranchFilter}
|
|
|
|
|
valueData={selectedBranchForFilter}
|
|
|
|
|
defaultValue="all"
|
|
|
|
|
placeholder="All Branches"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
<div className="FilterAndRefresh">
|
|
|
|
|
<RangePicker
|
|
|
|
|
presets={[]}
|
|
|
|
|
onChange={onRangeChange}
|
|
|
|
|
format={dateFormat}
|
|
|
|
|
disabledDate={disabledDate}
|
|
|
|
|
className="datepickerDashboardrange"
|
|
|
|
|
inputReadOnly={true}
|
|
|
|
|
/>
|
|
|
|
|
{/* <div className="refershdashboard">
|
|
|
|
|
<div>
|
|
|
|
|
{' '}
|
|
|
|
|
<IoMdRefresh />
|
|
|
|
|
Refresh
|
|
|
|
|
</div>
|
|
|
|
|
<span>10sec auto refresh</span>
|
|
|
|
|
</div> */}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{selection === 'dashboard' ? (
|
|
|
|
|
<>
|
|
|
|
|
<div className="dashboardMainGrid">
|
|
|
|
|
<div className="TotalRevenue">
|
|
|
|
|
<div className="tlxHeader"></div>
|
|
|
|
|
<div className="TotalRevenue-Graph">
|
|
|
|
|
<GraphChart datasets={datasets} />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="dashboardMainCenter">
|
|
|
|
|
<div className="todaySnapshotRow">
|
2026-01-29 10:15:06 +05:30
|
|
|
<p
|
|
|
|
|
style={{
|
|
|
|
|
fontSize: '13px',
|
|
|
|
|
marginBottom: '0.2rem',
|
|
|
|
|
fontWeight: '500',
|
|
|
|
|
fontFamily: 'Inter',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Today's Snapshot
|
|
|
|
|
</p>
|
2026-01-27 18:27:29 +05:30
|
|
|
{selectedBranchForFilter === 'all' ? (
|
2026-01-29 10:15:06 +05:30
|
|
|
<div className="todaySnapFlex">
|
2026-01-27 18:27:29 +05:30
|
|
|
<Tooltip
|
|
|
|
|
title={
|
|
|
|
|
<div
|
|
|
|
|
className="tooltip-scrollable"
|
|
|
|
|
style={{
|
|
|
|
|
maxHeight: 300,
|
|
|
|
|
overflowY: 'auto',
|
|
|
|
|
overflowX: 'hidden', // Moves scrollbar to far right edge of tooltip
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{ApiData?.[0]?.BranchDtl?.map((item, index) => (
|
|
|
|
|
<div
|
|
|
|
|
key={index}
|
|
|
|
|
style={{
|
|
|
|
|
marginBottom: 8,
|
|
|
|
|
paddingBottom: 8,
|
|
|
|
|
borderBottom: '1px solid #f0f0f0',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<strong>{item.BrName || 'N/A'}</strong>
|
|
|
|
|
<br />
|
|
|
|
|
Orders:{' '}
|
|
|
|
|
{(item.DineInOrderCount || 0) +
|
|
|
|
|
(item.TakeAwayOrderCount || 0)}
|
|
|
|
|
<br />
|
|
|
|
|
Revenue: ₹{item.OverAllSalesAmt || 0}
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
placement="bottom"
|
|
|
|
|
>
|
|
|
|
|
<div className="todaySnapshotBox orders">
|
|
|
|
|
{ApiData?.[0]?.DineInOrderCount +
|
|
|
|
|
ApiData?.[0]?.TakeAwayOrderCount +
|
|
|
|
|
ApiData?.[0]?.DineIn_TakeAwayOrderCount || 0}{' '}
|
|
|
|
|
<div>Orders</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
<Tooltip
|
|
|
|
|
title={
|
|
|
|
|
<div
|
|
|
|
|
className="tooltip-scrollable"
|
|
|
|
|
style={{
|
|
|
|
|
maxHeight: 300,
|
|
|
|
|
overflowY: 'auto',
|
|
|
|
|
overflowX: 'hidden', // Moves scrollbar to far right edge of tooltip
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{ApiData?.[0]?.BranchDtl?.map((item, index) => (
|
|
|
|
|
<div
|
|
|
|
|
key={index}
|
|
|
|
|
style={{
|
|
|
|
|
marginBottom: 8,
|
|
|
|
|
paddingBottom: 8,
|
|
|
|
|
borderBottom: '1px solid #f0f0f0',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<strong>{item.BrName || 'N/A'}</strong>
|
|
|
|
|
<br />
|
|
|
|
|
Orders:{' '}
|
|
|
|
|
{(item.DineInOrderCount || 0) +
|
|
|
|
|
(item.TakeAwayOrderCount || 0)}
|
|
|
|
|
<br />
|
|
|
|
|
Revenue: ₹{item.OverAllSalesAmt || 0}
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
placement="bottom"
|
|
|
|
|
>
|
|
|
|
|
{!isCheckSportsApp && (
|
|
|
|
|
<div className="todaySnapshotBox revenue">
|
|
|
|
|
{ApiData?.[0]?.OverAllSalesAmt -
|
|
|
|
|
ApiData?.[0]?.OverAllOfferAmount || 0}{' '}
|
|
|
|
|
<div>Revenue</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</Tooltip>
|
|
|
|
|
<Tooltip
|
|
|
|
|
title={`Total New Customers across all branches: ${SalesHdr?.[0]?.NewCustomers || 0}`}
|
|
|
|
|
placement="bottom"
|
|
|
|
|
>
|
|
|
|
|
<div className="todaySnapshotBox customers">
|
|
|
|
|
{SalesHdr?.[0]?.NewCustomers || 0}{' '}
|
|
|
|
|
<div>New Customers</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
{!isCheckSportsApp && (
|
|
|
|
|
<Tooltip
|
|
|
|
|
title={`Total Pending Bills across all branches: ${SalesHdr?.[0]?.PendingBill || 0}`}
|
|
|
|
|
placement="bottom"
|
|
|
|
|
>
|
|
|
|
|
<div className="todaySnapshotBox pending">
|
|
|
|
|
{SalesHdr?.[0]?.PendingBill || 0}{' '}
|
|
|
|
|
<div>Pending Bills</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
)}
|
2026-01-29 10:15:06 +05:30
|
|
|
</div>
|
2026-01-27 18:27:29 +05:30
|
|
|
) : (
|
2026-01-29 10:15:06 +05:30
|
|
|
<div>
|
2026-01-27 18:27:29 +05:30
|
|
|
<div className="todaySnapshotBox orders">
|
|
|
|
|
{ApiData?.[0]?.DineInOrderCount +
|
|
|
|
|
ApiData?.[0]?.TakeAwayOrderCount +
|
|
|
|
|
ApiData?.[0]?.DineIn_TakeAwayOrderCount || 0}{' '}
|
|
|
|
|
<div>Orders</div>
|
|
|
|
|
</div>
|
|
|
|
|
{!isCheckSportsApp && (
|
|
|
|
|
<div className="todaySnapshotBox revenue">
|
|
|
|
|
{(
|
|
|
|
|
(ApiData?.[0]?.OverAllSalesAmt || 0) -
|
|
|
|
|
(ApiData?.[0]?.OverAllOfferAmount || 0)
|
|
|
|
|
).toFixed(2)}{' '}
|
|
|
|
|
<div>Revenue </div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
<div className="todaySnapshotBox customers">
|
|
|
|
|
{SalesHdr?.[0]?.NewCustomers || 0}{' '}
|
|
|
|
|
<div>New Customers</div>
|
|
|
|
|
</div>
|
|
|
|
|
{!isCheckSportsApp && (
|
|
|
|
|
<div className="todaySnapshotBox pending">
|
|
|
|
|
{SalesHdr?.[0]?.PendingBill || 0}{' '}
|
|
|
|
|
<div>Pending Bills</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
2026-01-29 10:15:06 +05:30
|
|
|
</div>
|
2026-01-27 18:27:29 +05:30
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
<div className="quickActionsRow">
|
|
|
|
|
<div
|
|
|
|
|
onClick={() => {
|
|
|
|
|
const hasEmpAccess = EmpData?.find(
|
2026-01-29 10:15:06 +05:30
|
|
|
(item) =>
|
|
|
|
|
item.ConfigName === 'Add Product' &&
|
|
|
|
|
item.ReadAccess === 'Y'
|
2026-01-27 18:27:29 +05:30
|
|
|
);
|
2026-01-29 10:15:06 +05:30
|
|
|
if (!hasEmpAccess && UserType === 'Employee') {
|
|
|
|
|
setMessageData('Please contact your admin to get access');
|
2026-01-27 18:27:29 +05:30
|
|
|
setMessageType('error');
|
|
|
|
|
}
|
|
|
|
|
if (isCheckSportsApp) {
|
|
|
|
|
navigate(`${subDirectory}setting/products-master/new`);
|
|
|
|
|
}
|
|
|
|
|
if (
|
2026-01-29 10:15:06 +05:30
|
|
|
(UserType === 'Employee' && hasEmpAccess) ||
|
|
|
|
|
UserType === 'Admin' ||
|
|
|
|
|
UserType === 'Super Admin' ||
|
|
|
|
|
UserType === 'Super Admin User'
|
2026-01-27 18:27:29 +05:30
|
|
|
) {
|
|
|
|
|
navigate(`${subDirectory}setting/product-master/new`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// setting/product-master/new
|
|
|
|
|
}}
|
|
|
|
|
className="quickActionBox"
|
|
|
|
|
>
|
|
|
|
|
<img src={Add} alt="" />
|
|
|
|
|
{!isCheckSportsApp ? (
|
|
|
|
|
<div>Add Product</div>
|
|
|
|
|
) : (
|
|
|
|
|
<div>Add Slot</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
{!isCheckSportsApp && (
|
|
|
|
|
<div
|
|
|
|
|
onClick={() => {
|
|
|
|
|
const hasEmpAccess = EmpData?.find(
|
2026-01-29 10:15:06 +05:30
|
|
|
(item) =>
|
|
|
|
|
item.ConfigName === 'Product Receipt' &&
|
|
|
|
|
item.ReadAccess === 'Y'
|
2026-01-27 18:27:29 +05:30
|
|
|
);
|
2026-01-29 10:15:06 +05:30
|
|
|
if (!hasEmpAccess && UserType === 'Employee') {
|
|
|
|
|
setMessageData(
|
|
|
|
|
'Please contact your admin to get access'
|
|
|
|
|
);
|
2026-01-27 18:27:29 +05:30
|
|
|
setMessageType('error');
|
|
|
|
|
}
|
|
|
|
|
if (
|
2026-01-29 10:15:06 +05:30
|
|
|
(UserType === 'Employee' && hasEmpAccess) ||
|
|
|
|
|
UserType === 'Admin' ||
|
|
|
|
|
UserType === 'Super Admin' ||
|
|
|
|
|
UserType === 'Super Admin User'
|
2026-01-27 18:27:29 +05:30
|
|
|
) {
|
|
|
|
|
navigate(`${subDirectory}setting/purchase-entry/new`);
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
className="quickActionBox"
|
|
|
|
|
>
|
|
|
|
|
<img src={AddPurchase} alt="" />
|
|
|
|
|
<div>Add Purchase</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
<div
|
|
|
|
|
onClick={() => {
|
|
|
|
|
const hasEmpAccess = EmpData?.find(
|
2026-01-29 10:15:06 +05:30
|
|
|
(item) =>
|
|
|
|
|
item.ConfigName === 'Daily Sales' &&
|
|
|
|
|
item.ReadAccess === 'Y'
|
2026-01-27 18:27:29 +05:30
|
|
|
);
|
2026-01-29 10:15:06 +05:30
|
|
|
if (!hasEmpAccess && UserType === 'Employee') {
|
|
|
|
|
setMessageData('Please contact your admin to get access');
|
2026-01-27 18:27:29 +05:30
|
|
|
setMessageType('error');
|
|
|
|
|
}
|
|
|
|
|
if (
|
2026-01-29 10:15:06 +05:30
|
|
|
(UserType === 'Employee' && hasEmpAccess) ||
|
|
|
|
|
UserType === 'Admin' ||
|
|
|
|
|
UserType === 'Super Admin' ||
|
|
|
|
|
UserType === 'Super Admin User'
|
2026-01-27 18:27:29 +05:30
|
|
|
) {
|
|
|
|
|
navigate(`${subDirectory}report/datewisereport`);
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
className="quickActionBox"
|
|
|
|
|
>
|
|
|
|
|
<img src={report} alt="" width="45px" />
|
|
|
|
|
<div>Report</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
className="quickActionBox"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
const hasEmpAccess = EmpData?.find(
|
2026-01-29 10:15:06 +05:30
|
|
|
(item) =>
|
|
|
|
|
item.ConfigName === 'Sales' && item.ReadAccess === 'Y'
|
2026-01-27 18:27:29 +05:30
|
|
|
);
|
2026-01-29 10:15:06 +05:30
|
|
|
if (!hasEmpAccess && UserType === 'Employee') {
|
|
|
|
|
setMessageData('Please contact your admin to get access');
|
2026-01-27 18:27:29 +05:30
|
|
|
setMessageType('error');
|
|
|
|
|
}
|
|
|
|
|
if (
|
2026-01-29 10:15:06 +05:30
|
|
|
(UserType === 'Employee' && hasEmpAccess) ||
|
|
|
|
|
UserType === 'Admin' ||
|
|
|
|
|
UserType === 'Super Admin' ||
|
|
|
|
|
UserType === 'Super Admin User'
|
2026-01-27 18:27:29 +05:30
|
|
|
) {
|
|
|
|
|
navigate(`${subDirectory}sales`);
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<img src={invoice} alt="" />
|
|
|
|
|
<div>New Bill</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* ------------------------Dont Delete----------------------------- */}
|
|
|
|
|
{/* <div className="expensesSalesRow">
|
|
|
|
|
<div className="expenseBox">Electricity<div>₹1,500</div></div>
|
|
|
|
|
<div className="expenseBox">Purchases<div>₹12,150</div></div>
|
|
|
|
|
<div className="expenseBox">Salaries<div className="red">₹7,500</div></div>
|
|
|
|
|
</div> */}
|
|
|
|
|
{/* <div className="salesBreakdownRow">
|
|
|
|
|
<div className="salesBreakdownBox">
|
|
|
|
|
DineIn <div>{ApiData?.[0]?.DineInOrderCount}</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="salesBreakdownBox">
|
|
|
|
|
Takeaway<div>{ApiData?.[0]?.TakeAwayOrderCount}</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="salesBreakdownBox">
|
|
|
|
|
Delivery<div>{ApiData?.[0]?.SelfTakeAwayOrderCount}</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div> */}
|
|
|
|
|
<div className="salesBreakdownRow">
|
|
|
|
|
{dinePreference &&
|
|
|
|
|
(ApiData?.[0]?.BranchDtl?.length > 1 ? (
|
|
|
|
|
<Tooltip
|
|
|
|
|
title={
|
|
|
|
|
<div
|
|
|
|
|
className="tooltip-scrollable"
|
|
|
|
|
style={{
|
|
|
|
|
maxHeight: 300,
|
|
|
|
|
overflowY: 'auto',
|
|
|
|
|
overflowX: 'hidden',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{ApiData[0].BranchDtl.map((item, index) => (
|
|
|
|
|
<div
|
|
|
|
|
key={index}
|
|
|
|
|
style={{
|
|
|
|
|
marginBottom: 8,
|
|
|
|
|
paddingBottom: 8,
|
|
|
|
|
borderBottom: '1px solid #f0f0f0',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<strong>{item.BrName || 'N/A'}</strong>
|
|
|
|
|
<br />
|
|
|
|
|
Orders: {item.DineInOrderCount || 0}
|
|
|
|
|
<br />
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
placement="bottom"
|
|
|
|
|
>
|
|
|
|
|
<div className="salesBreakdownBox">
|
|
|
|
|
DineIn <div>{ApiData?.[0]?.DineInOrderCount || 0}</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
) : (
|
|
|
|
|
<div className="salesBreakdownBox">
|
|
|
|
|
DineIn <div>{ApiData?.[0]?.DineInOrderCount || 0}</div>
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
|
|
<div className="salesBreakdownBox">
|
|
|
|
|
{takeAwayPreference ? 'Takeaway' : 'Sales'}
|
|
|
|
|
|
|
|
|
|
{ApiData?.[0]?.BranchDtl?.length > 1 ? (
|
|
|
|
|
<Tooltip
|
|
|
|
|
title={
|
|
|
|
|
<div
|
|
|
|
|
className="tooltip-scrollable"
|
|
|
|
|
style={{
|
|
|
|
|
maxHeight: 300,
|
|
|
|
|
overflowY: 'auto',
|
|
|
|
|
overflowX: 'hidden', // Moves scrollbar to far right edge of tooltip
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{ApiData[0].BranchDtl.map((item, index) => (
|
|
|
|
|
<div
|
|
|
|
|
key={index}
|
|
|
|
|
style={{
|
|
|
|
|
marginBottom: 8,
|
|
|
|
|
paddingBottom: 8,
|
|
|
|
|
borderBottom: '1px solid #f0f0f0',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<strong>{item.BrName || 'N/A'}</strong>
|
|
|
|
|
<br />
|
|
|
|
|
Orders: {item.TakeAwayOrderCount || 0}
|
|
|
|
|
<br />
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
placement="bottom"
|
|
|
|
|
>
|
|
|
|
|
<div>{ApiData?.[0]?.TakeAwayOrderCount || 0}</div>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
) : (
|
|
|
|
|
<div>{ApiData?.[0]?.TakeAwayOrderCount || 0}</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{dinePreference && takeAwayPreference && (
|
|
|
|
|
<div className="salesBreakdownBox">
|
|
|
|
|
{'DineIn + Takeaway'}
|
|
|
|
|
|
|
|
|
|
{ApiData?.[0]?.BranchDtl?.length > 1 ? (
|
|
|
|
|
<Tooltip
|
|
|
|
|
title={
|
|
|
|
|
<div
|
|
|
|
|
className="tooltip-scrollable"
|
|
|
|
|
style={{
|
|
|
|
|
maxHeight: 300,
|
|
|
|
|
overflowY: 'auto',
|
|
|
|
|
overflowX: 'hidden', // Moves scrollbar to far right edge of tooltip
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{ApiData[0].BranchDtl.map((item, index) => (
|
|
|
|
|
<div
|
|
|
|
|
key={index}
|
|
|
|
|
style={{
|
|
|
|
|
marginBottom: 8,
|
|
|
|
|
paddingBottom: 8,
|
|
|
|
|
borderBottom: '1px solid #f0f0f0',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<strong>{item.BrName || 'N/A'}</strong>
|
|
|
|
|
<br />
|
|
|
|
|
Orders: {item.DineIn_TakeAwayOrderCount || 0}
|
|
|
|
|
<br />
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
placement="bottom"
|
|
|
|
|
>
|
|
|
|
|
<div>
|
|
|
|
|
{ApiData?.[0]?.DineIn_TakeAwayOrderCount || 0}
|
|
|
|
|
</div>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
) : (
|
|
|
|
|
<div>{ApiData?.[0]?.DineIn_TakeAwayOrderCount || 0}</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{!isCheckSportsApp && (
|
|
|
|
|
<div className="salesBreakdownBox">
|
|
|
|
|
{ApiData?.[0]?.BranchDtl?.length > 1 ? (
|
|
|
|
|
<Tooltip
|
|
|
|
|
title={
|
|
|
|
|
<div
|
|
|
|
|
className="tooltip-scrollable"
|
|
|
|
|
style={{
|
|
|
|
|
maxHeight: 300,
|
|
|
|
|
overflowY: 'auto',
|
|
|
|
|
overflowX: 'hidden', // Moves scrollbar to far right edge of tooltip
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{ApiData[0].BranchDtl.map((item, index) => (
|
|
|
|
|
<div
|
|
|
|
|
key={index}
|
|
|
|
|
style={{
|
|
|
|
|
marginBottom: 8,
|
|
|
|
|
paddingBottom: 8,
|
|
|
|
|
borderBottom: '1px solid #f0f0f0',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<strong>{item.BrName || 'N/A'}</strong>
|
|
|
|
|
<br />
|
|
|
|
|
Delivery: {item.SelfTakeAwayOrderCount || 0}
|
|
|
|
|
<br />
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
placement="bottom"
|
|
|
|
|
>
|
|
|
|
|
Delivery
|
|
|
|
|
<div>{ApiData?.[0]?.SelfTakeAwayOrderCount || 0}</div>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
) : (
|
|
|
|
|
<>
|
|
|
|
|
Delivery
|
|
|
|
|
<div>{ApiData?.[0]?.SelfTakeAwayOrderCount || 0}</div>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{!isCheckSportsApp && (
|
|
|
|
|
<div className="dashboardMainRight">
|
|
|
|
|
<div className="productSummaryTitle">Product Summary</div>
|
|
|
|
|
<div className="productSummaryCard">
|
|
|
|
|
<div className="productSummaryRow">
|
|
|
|
|
<div className="productSummaryBox total">
|
|
|
|
|
{AllProdIds?.[0]?.BranchDtl?.length > 1 ? (
|
|
|
|
|
<Tooltip
|
|
|
|
|
title={
|
|
|
|
|
<div
|
|
|
|
|
className="tooltip-scrollable"
|
|
|
|
|
style={{
|
|
|
|
|
maxHeight: 300,
|
|
|
|
|
overflowY: 'auto',
|
|
|
|
|
overflowX: 'hidden', // Moves scrollbar to far right edge of tooltip
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{AllProdIds[0].BranchDtl.map((item, index) => (
|
|
|
|
|
<div
|
|
|
|
|
key={index}
|
|
|
|
|
style={{
|
|
|
|
|
marginBottom: 8,
|
|
|
|
|
paddingBottom: 8,
|
|
|
|
|
borderBottom: '1px solid #f0f0f0',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<strong>{item?.BranchName || 'N/A'}</strong>
|
|
|
|
|
<br />
|
|
|
|
|
TOTAL PRODUCTS: {item?.ProductCount || 0}
|
|
|
|
|
<br />
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
placement="bottom"
|
|
|
|
|
>
|
|
|
|
|
<div>
|
2026-01-29 10:15:06 +05:30
|
|
|
<p>{AllProdIds?.[0]?.TotalProductCount}</p>
|
2026-01-27 18:27:29 +05:30
|
|
|
<div>TOTAL PRODUCTS</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
) : (
|
|
|
|
|
<div>
|
2026-01-29 10:15:06 +05:30
|
|
|
<p>
|
|
|
|
|
{AllProdIds?.[0]?.TotalProductCount ||
|
|
|
|
|
AllProdIds?.length}
|
|
|
|
|
</p>
|
2026-01-27 18:27:29 +05:30
|
|
|
<div>TOTAL PRODUCTS</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
<div className="productSummaryBox live">
|
|
|
|
|
{expiredList?.[0]?.Branchdtl?.length > 1 ? (
|
|
|
|
|
<Tooltip
|
|
|
|
|
title={
|
|
|
|
|
<div
|
|
|
|
|
className="tooltip-scrollable"
|
|
|
|
|
style={{
|
|
|
|
|
maxHeight: 300,
|
|
|
|
|
overflowY: 'auto',
|
|
|
|
|
overflowX: 'hidden', // Moves scrollbar to far right edge of tooltip
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{expiredList[0].Branchdtl.map((item, index) => (
|
|
|
|
|
<div
|
|
|
|
|
key={index}
|
|
|
|
|
style={{
|
|
|
|
|
marginBottom: 8,
|
|
|
|
|
paddingBottom: 8,
|
|
|
|
|
borderBottom: '1px solid #f0f0f0',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<strong>{item.BranchName || 'N/A'}</strong>
|
|
|
|
|
<br />
|
|
|
|
|
Expiry Stock: {item.ProductsDtl?.length || 0}
|
|
|
|
|
<br />
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
placement="bottom"
|
|
|
|
|
>
|
|
|
|
|
<div>
|
|
|
|
|
<p> {expiredList?.length}</p>
|
|
|
|
|
<div>EXPIRY STOCK</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
) : (
|
|
|
|
|
<div>
|
|
|
|
|
<p> {expiredList?.length}</p>
|
|
|
|
|
<div>EXPIRY STOCK</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="productSummaryBox low">
|
|
|
|
|
{lowStockList?.[0]?.BranchDtl?.length > 1 ? (
|
|
|
|
|
<Tooltip
|
|
|
|
|
title={
|
|
|
|
|
<div
|
|
|
|
|
className="tooltip-scrollable"
|
|
|
|
|
style={{
|
|
|
|
|
maxHeight: 300,
|
|
|
|
|
overflowY: 'auto',
|
|
|
|
|
overflowX: 'hidden', // Moves scrollbar to far right edge of tooltip
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{lowStockList[0].BranchDtl.map((item, index) => (
|
|
|
|
|
<div
|
|
|
|
|
key={index}
|
|
|
|
|
style={{
|
|
|
|
|
marginBottom: 8,
|
|
|
|
|
paddingBottom: 8,
|
|
|
|
|
borderBottom: '1px solid #f0f0f0',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<strong>{item.BranchName || 'N/A'}</strong>
|
|
|
|
|
<br />
|
|
|
|
|
LOW STOCK: {item.lowStockList?.length || 0}
|
|
|
|
|
<br />
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
placement="bottom"
|
|
|
|
|
>
|
|
|
|
|
<div>
|
|
|
|
|
<p>{lowStockList?.length}</p>
|
|
|
|
|
<div>LOW STOCK</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
) : (
|
|
|
|
|
<div>
|
|
|
|
|
<p> {lowStockList?.length}</p>
|
|
|
|
|
<div>LOW STOCK</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
<div className="productSummaryBox nostock">
|
|
|
|
|
{SalesHdr?.[0]?.BranchDetails?.length > 1 ? (
|
|
|
|
|
<Tooltip
|
|
|
|
|
title={
|
|
|
|
|
<div
|
|
|
|
|
className="tooltip-scrollable"
|
|
|
|
|
style={{
|
|
|
|
|
maxHeight: 300,
|
|
|
|
|
overflowY: 'auto',
|
|
|
|
|
overflowX: 'hidden', // Moves scrollbar to far right edge of tooltip
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{SalesHdr[0].BranchDetails.map((item, index) => (
|
|
|
|
|
<div
|
|
|
|
|
key={index}
|
|
|
|
|
style={{
|
|
|
|
|
marginBottom: 8,
|
|
|
|
|
paddingBottom: 8,
|
|
|
|
|
borderBottom: '1px solid #f0f0f0',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<strong>{item.BranchName || 'N/A'}</strong>
|
|
|
|
|
<br />
|
|
|
|
|
NO STOCK: {item.NoStockProduct || 0}
|
|
|
|
|
<br />
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
placement="bottom"
|
|
|
|
|
>
|
|
|
|
|
<div>
|
|
|
|
|
<p>{SalesHdr?.[0]?.NoStockProduct || 0}</p>
|
|
|
|
|
<div>NO STOCK</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
) : (
|
|
|
|
|
<div>
|
|
|
|
|
<p> {SalesHdr?.[0]?.NoStockProduct || 0}</p>
|
|
|
|
|
<div>NO STOCK</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="notificationCenterTitle">
|
|
|
|
|
Notification Center
|
|
|
|
|
</div>
|
|
|
|
|
<div className="notificationCenterCard">
|
|
|
|
|
{expiredList?.length > 0 && (
|
|
|
|
|
<div className="notificationStock">
|
2026-01-29 10:15:06 +05:30
|
|
|
{expiredList.length} Products expiry today!
|
2026-01-27 18:27:29 +05:30
|
|
|
</div>
|
|
|
|
|
)}
|
2026-01-29 10:15:06 +05:30
|
|
|
|
2026-01-27 18:27:29 +05:30
|
|
|
{lowStockList?.length > 0 && (
|
|
|
|
|
<div className="notificationStock">
|
2026-01-29 10:15:06 +05:30
|
|
|
Low Stock count {lowStockList.length}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{!expiredList?.length && !lowStockList?.length && (
|
|
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
fontSize: '12px',
|
|
|
|
|
width: '100%',
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Notification Empty
|
2026-01-27 18:27:29 +05:30
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{!isCheckSportsApp && (
|
|
|
|
|
<div className="dashboardSecondaryGrid">
|
|
|
|
|
<div className="topSellingProductCard">
|
|
|
|
|
<div className="topSellingHeader">
|
|
|
|
|
<div>Top Selling Product</div>
|
|
|
|
|
<div className="topSellingMonth">This Month</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{topSellingProducts.map((product, idx) => (
|
|
|
|
|
<div className="TopSellingProduct-list" key={idx}>
|
|
|
|
|
<img src={product.ProdLogo} alt={product.name} />
|
|
|
|
|
<div>
|
|
|
|
|
{product.ProdName} - {product.TotalSoldQty}{' '}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
<div className="preOrderSummaryCardMain">
|
|
|
|
|
<div className="preOrderSummaryCard">
|
|
|
|
|
<div className="preOrderSummaryTitle">Pre Order Summary</div>
|
|
|
|
|
<div className="preOrderSummaryRow">
|
|
|
|
|
<div className="preOrderSummaryBox total">
|
|
|
|
|
<Tooltip
|
|
|
|
|
title={
|
|
|
|
|
<div
|
|
|
|
|
className="tooltip-scrollable"
|
|
|
|
|
style={{
|
|
|
|
|
maxHeight: 300,
|
|
|
|
|
overflowY: 'auto',
|
|
|
|
|
overflowX: 'hidden', // Moves scrollbar to far right edge of tooltip
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{preorderData?.[0]?.BranchDtl
|
|
|
|
|
? preorderData?.[0]?.BranchDtl?.map(
|
|
|
|
|
(item, index) => (
|
|
|
|
|
<div
|
|
|
|
|
key={index}
|
|
|
|
|
style={{
|
|
|
|
|
marginBottom: 8,
|
|
|
|
|
paddingBottom: 8,
|
|
|
|
|
borderBottom: '1px solid #f0f0f0',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<strong>
|
|
|
|
|
{item.BranchName || 'N/A'}
|
|
|
|
|
</strong>
|
|
|
|
|
<br />
|
|
|
|
|
Total Orders: {item.TotalOrders || 0}
|
|
|
|
|
<br />
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
: 'No Data'}
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
placement="bottom"
|
|
|
|
|
>
|
|
|
|
|
{preorderData?.[0]?.TotalOrders || 0}
|
|
|
|
|
<div>Total Orders</div>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="preOrderSummaryBox pending">
|
|
|
|
|
<Tooltip
|
|
|
|
|
title={
|
|
|
|
|
<div
|
|
|
|
|
className="tooltip-scrollable"
|
|
|
|
|
style={{
|
|
|
|
|
maxHeight: 300,
|
|
|
|
|
overflowY: 'auto',
|
|
|
|
|
overflowX: 'hidden', // Moves scrollbar to far right edge of tooltip
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{preorderData?.[0]?.BranchDtl
|
|
|
|
|
? preorderData?.[0]?.BranchDtl?.map(
|
|
|
|
|
(item, index) => (
|
|
|
|
|
<div
|
|
|
|
|
key={index}
|
|
|
|
|
style={{
|
|
|
|
|
marginBottom: 8,
|
|
|
|
|
paddingBottom: 8,
|
|
|
|
|
borderBottom: '1px solid #f0f0f0',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<strong>
|
|
|
|
|
{item.BranchName || 'N/A'}
|
|
|
|
|
</strong>
|
|
|
|
|
<br />
|
|
|
|
|
Total Orders: {item.PendingOrders || 0}
|
|
|
|
|
<br />
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
: 'No Data'}
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
placement="bottom"
|
|
|
|
|
>
|
|
|
|
|
{preorderData?.[0]?.PendingOrders || 0}
|
|
|
|
|
<div>Pending</div>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="preOrderSummaryBox completed">
|
|
|
|
|
<Tooltip
|
|
|
|
|
title={
|
|
|
|
|
<div
|
|
|
|
|
className="tooltip-scrollable"
|
|
|
|
|
style={{
|
|
|
|
|
maxHeight: 300,
|
|
|
|
|
overflowY: 'auto',
|
|
|
|
|
overflowX: 'hidden', // Moves scrollbar to far right edge of tooltip
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{preorderData?.[0]?.BranchDtl
|
|
|
|
|
? preorderData?.[0]?.BranchDtl?.map(
|
|
|
|
|
(item, index) => (
|
|
|
|
|
<div
|
|
|
|
|
key={index}
|
|
|
|
|
style={{
|
|
|
|
|
marginBottom: 8,
|
|
|
|
|
paddingBottom: 8,
|
|
|
|
|
borderBottom: '1px solid #f0f0f0',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<strong>
|
|
|
|
|
{item.BranchName || 'N/A'}
|
|
|
|
|
</strong>
|
|
|
|
|
<br />
|
|
|
|
|
Total Orders: {item.CompletedOrders || 0}
|
|
|
|
|
<br />
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
: 'No Data'}
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
placement="bottom"
|
|
|
|
|
>
|
|
|
|
|
{preorderData?.[0]?.CompletedOrders || 0}
|
|
|
|
|
<div>Completed</div>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="creditListCardMain">
|
|
|
|
|
<div className="creditListTitle">Credit List</div>
|
|
|
|
|
<div className="creditListCard">
|
|
|
|
|
<div className="creditListHeader">
|
|
|
|
|
<div>Customer</div>
|
|
|
|
|
<div>Amount</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{customerPendingBalance?.length > 0 ? (
|
|
|
|
|
customerPendingBalance.map((customer, idx) => (
|
|
|
|
|
<div className="creditListRow" key={idx}>
|
|
|
|
|
<div className="">
|
|
|
|
|
{customer?.CustName || customer.CustMobile}
|
|
|
|
|
</div>
|
|
|
|
|
<div>₹{customer.creditBal.toFixed(2)}</div>
|
|
|
|
|
</div>
|
|
|
|
|
))
|
|
|
|
|
) : (
|
|
|
|
|
<div className="creditListRow">
|
|
|
|
|
<div>No Pending Balance</div>
|
|
|
|
|
<div>₹0.00</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
{/* <div className="creditListViewAll">View All</div> */}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="stockAlertsCard">
|
|
|
|
|
<div className="stockAlertsTitle">Stock Alerts</div>
|
|
|
|
|
<div className="stockAlertsTable">
|
|
|
|
|
<div className="stockAlertsHeaderRow">
|
|
|
|
|
<div className="stockAlertsCol slno">Sl.No</div>
|
|
|
|
|
<div className="stockAlertsCol product">Product</div>
|
|
|
|
|
<div className="stockAlertsCol count">Stock Count</div>
|
|
|
|
|
</div>
|
|
|
|
|
{lowStockList?.length > 0 ? (
|
|
|
|
|
lowStockList?.map((item, index) => (
|
|
|
|
|
<div className="stockAlertsRow" key={index}>
|
|
|
|
|
<div className="stockAlertsCol slno">{index + 1}</div>
|
|
|
|
|
<div className="stockAlertsCol product">
|
|
|
|
|
<div className="stockAlertsProductLink">
|
|
|
|
|
{item?.ProdName || item?.ProdId}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="stockAlertsCol count">
|
|
|
|
|
{item?.BalanceQty}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
))
|
|
|
|
|
) : (
|
2026-01-29 10:15:06 +05:30
|
|
|
<div style={{ textAlign: 'center', fontSize: '12px' }}>
|
2026-01-27 18:27:29 +05:30
|
|
|
No Low Stock Product
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{/* <div className="stockAlertsRow">
|
|
|
|
|
<div className="stockAlertsCol slno">2</div>
|
|
|
|
|
<div className="stockAlertsCol product">
|
|
|
|
|
<div className="stockAlertsProductLink">
|
|
|
|
|
Cotton Blend Mandarin Collar Self One Design Kurta
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="stockAlertsCol count">4</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="stockAlertsRow">
|
|
|
|
|
<div className="stockAlertsCol slno">3</div>
|
|
|
|
|
<div className="stockAlertsCol product">
|
|
|
|
|
<div className="stockAlertsProductLink">
|
|
|
|
|
Cotton Blend Mandarin Collar Self One Design Kurta
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="stockAlertsCol count">1</div>
|
|
|
|
|
</div> */}
|
|
|
|
|
{/* <div className="stockAlertsViewAll">
|
|
|
|
|
<a href="#">View All</a>
|
|
|
|
|
</div> */}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</>
|
|
|
|
|
) : (
|
|
|
|
|
<>
|
|
|
|
|
<TopSellingProductsChart
|
|
|
|
|
dates={dates}
|
|
|
|
|
products={products}
|
|
|
|
|
loading={loading}
|
|
|
|
|
totalPages={totalPages}
|
|
|
|
|
page={page}
|
|
|
|
|
setPage={setPage}
|
|
|
|
|
fetchProducts={fetchProducts}
|
|
|
|
|
initialDate={initialDate}
|
|
|
|
|
/>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
<DefaultModal
|
|
|
|
|
open={modal}
|
|
|
|
|
title="Authentication"
|
|
|
|
|
width={500}
|
|
|
|
|
footer={false}
|
|
|
|
|
handleCancel={handlePageChange}
|
|
|
|
|
children={
|
|
|
|
|
<>
|
|
|
|
|
<div className="modalContentsadminuser">
|
|
|
|
|
<DropDowns
|
|
|
|
|
options={userDropDown?.map((option) => ({
|
|
|
|
|
value: option?.UserId,
|
|
|
|
|
label: option?.UserName,
|
|
|
|
|
}))}
|
|
|
|
|
label={<label class="required">User Name</label>}
|
|
|
|
|
className="field-DropDown"
|
|
|
|
|
onChangeFunction={(e) => UserDropDownChange(e)}
|
|
|
|
|
isOnchanges={selectedUserData ? true : false}
|
|
|
|
|
valueData={selectedUserData}
|
|
|
|
|
disabled={disabled}
|
|
|
|
|
/>
|
|
|
|
|
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
|
|
|
|
<div className="RadioButton">
|
|
|
|
|
<RadioGrpButton
|
|
|
|
|
content={[
|
|
|
|
|
{ value: 'O', label: 'OTP' },
|
|
|
|
|
{ value: 'P', label: 'PIN' },
|
|
|
|
|
]}
|
|
|
|
|
fieldState={true}
|
|
|
|
|
defaultSelect={SelectType}
|
|
|
|
|
onSelectFuntion={(e) => ChangeMethod(e)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{pinInput && (
|
|
|
|
|
<div className="otpInputsadminuser">
|
|
|
|
|
{[0, 1, 2, 3].map((i) => (
|
|
|
|
|
<input
|
|
|
|
|
key={i}
|
|
|
|
|
ref={(el) => (inputRefs.current[i] = el)}
|
|
|
|
|
className="inputNumber"
|
|
|
|
|
type="text"
|
|
|
|
|
inputMode="numeric"
|
|
|
|
|
pattern="[0-9]"
|
|
|
|
|
maxLength={1}
|
|
|
|
|
onChange={(e) => handleChange(i, e)}
|
|
|
|
|
onKeyDown={(e) => handleKeyDown(i, e)}
|
|
|
|
|
style={{
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
width: '40px',
|
|
|
|
|
fontSize: '20px',
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
width: '100%',
|
|
|
|
|
display: 'flex',
|
|
|
|
|
justifyContent: 'flex-end',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<button
|
|
|
|
|
className="size-save-button-retail"
|
|
|
|
|
onClick={handleClick}
|
|
|
|
|
disabled={disabled}
|
|
|
|
|
>
|
|
|
|
|
{SelectTypeName === 'OTP'
|
|
|
|
|
? !FirstTimeOtp
|
|
|
|
|
? `send ${SelectTypeName.toLocaleLowerCase()}`
|
|
|
|
|
: `resend ${SelectTypeName.toLocaleLowerCase()}${
|
|
|
|
|
seconds > 0 ? ` in ${seconds}s` : ''
|
|
|
|
|
}`
|
|
|
|
|
: !FirstTimePin
|
|
|
|
|
? `send ${SelectTypeName.toLocaleLowerCase()}`
|
|
|
|
|
: `resend ${SelectTypeName.toLocaleLowerCase()}${
|
|
|
|
|
seconds > 0 ? ` in ${seconds}s` : ''
|
|
|
|
|
}`}
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default RetailDashboard;
|