updates on the dead codes removal
This commit is contained in:
@@ -8,7 +8,7 @@ import Notistack from 'components/third-party/Notistack';
|
|||||||
import { useNavigate } from 'react-router';
|
import { useNavigate } from 'react-router';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import InternetStatus from 'components/nearle_components/updateNetworkStatus';
|
import InternetStatus from 'components/nearle_components/updateNetworkStatus';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
|
|
||||||
// auth-provider
|
// auth-provider
|
||||||
// import { JWTProvider as AuthProvider } from 'contexts/JWTContext';
|
// import { JWTProvider as AuthProvider } from 'contexts/JWTContext';
|
||||||
|
|||||||
@@ -25,14 +25,13 @@ const AppSideNav = ({ isCollapsed, onCollapsedChange }) => {
|
|||||||
// Wrap explicitly in Astryx's own <Icon> rather than passing the bare
|
// Wrap explicitly in Astryx's own <Icon> rather than passing the bare
|
||||||
// component and letting SideNavItem's renderIconSlot auto-detect it:
|
// component and letting SideNavItem's renderIconSlot auto-detect it:
|
||||||
// that detection only matches plain functions/forwardRef objects, not
|
// that detection only matches plain functions/forwardRef objects, not
|
||||||
// React.memo-wrapped ones (several @ant-design/icons v5 icons, as well
|
// React.memo-wrapped ones (several @ant-design/icons v5 icons are
|
||||||
// as @mui/icons-material icons, are memo-wrapped) — those fell through
|
// memo-wrapped) — those fell through
|
||||||
// and got returned as a raw, uninstantiated element, crashing with
|
// and got returned as a raw, uninstantiated element, crashing with
|
||||||
// "Objects are not valid as a React child". Wrapping here always
|
// "Objects are not valid as a React child". Wrapping here always
|
||||||
// renders through Icon's own component-mode path, which handles any
|
// renders through Icon's own component-mode path, which handles any
|
||||||
// component type and gives every icon the same normalised size/colour
|
// component type and gives every icon the same normalised size/colour
|
||||||
// regardless of source library (this menu mixes @ant-design/icons and
|
// regardless of source library.
|
||||||
// @mui/icons-material).
|
|
||||||
const icon = item.icon ? <Icon icon={item.icon} /> : undefined;
|
const icon = item.icon ? <Icon icon={item.icon} /> : undefined;
|
||||||
|
|
||||||
if (item.type === 'collapse') {
|
if (item.type === 'collapse') {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { TopNav, TopNavHeading } from '@astryxdesign/core/TopNav';
|
|||||||
import { DropdownMenu } from '@astryxdesign/core/DropdownMenu';
|
import { DropdownMenu } from '@astryxdesign/core/DropdownMenu';
|
||||||
import { Avatar } from '@astryxdesign/core/Avatar';
|
import { Avatar } from '@astryxdesign/core/Avatar';
|
||||||
import { HStack } from '@astryxdesign/core/HStack';
|
import { HStack } from '@astryxdesign/core/HStack';
|
||||||
import { Text } from '@astryxdesign/core/Text';
|
|
||||||
|
|
||||||
import { WindowsOutlined, EditOutlined, LogoutOutlined } from '@ant-design/icons';
|
import { WindowsOutlined, EditOutlined, LogoutOutlined } from '@ant-design/icons';
|
||||||
import { TbBoxMultiple1 } from 'react-icons/tb';
|
import { TbBoxMultiple1 } from 'react-icons/tb';
|
||||||
@@ -31,7 +30,6 @@ const AppTopNav = () => {
|
|||||||
const topNavRef = useRef(null);
|
const topNavRef = useRef(null);
|
||||||
const [headerHeight, setHeaderHeight] = useState(null);
|
const [headerHeight, setHeaderHeight] = useState(null);
|
||||||
|
|
||||||
const tenantname = localStorage.getItem('tenantname') || '';
|
|
||||||
const fullname = localStorage.getItem('fullname') || '';
|
const fullname = localStorage.getItem('fullname') || '';
|
||||||
|
|
||||||
const handleLogout = () => {
|
const handleLogout = () => {
|
||||||
|
|||||||
@@ -6,42 +6,8 @@ import { TbListDetails } from 'react-icons/tb';
|
|||||||
import { LiaFileInvoiceSolid } from 'react-icons/lia';
|
import { LiaFileInvoiceSolid } from 'react-icons/lia';
|
||||||
import { MdDirectionsBike as DirectionsBikeOutlinedIcon, MdRoute as RouteOutlinedIcon, MdMoped as MopedOutlinedIcon } from 'react-icons/md';
|
import { MdDirectionsBike as DirectionsBikeOutlinedIcon, MdRoute as RouteOutlinedIcon, MdMoped as MopedOutlinedIcon } from 'react-icons/md';
|
||||||
|
|
||||||
// assets
|
|
||||||
import {
|
|
||||||
BorderOutlined,
|
|
||||||
BoxPlotOutlined,
|
|
||||||
ChromeOutlined,
|
|
||||||
DeploymentUnitOutlined,
|
|
||||||
GatewayOutlined,
|
|
||||||
MenuUnfoldOutlined,
|
|
||||||
QuestionOutlined,
|
|
||||||
SmileOutlined,
|
|
||||||
StopOutlined,
|
|
||||||
DashboardOutlined,
|
|
||||||
ClockCircleOutlined,
|
|
||||||
UserOutlined,
|
|
||||||
SettingOutlined
|
|
||||||
} from '@ant-design/icons';
|
|
||||||
import { Path } from 'leaflet';
|
|
||||||
import { MdLocationOn as LocationOnOutlined } from 'react-icons/md';
|
import { MdLocationOn as LocationOnOutlined } from 'react-icons/md';
|
||||||
|
|
||||||
// icons
|
|
||||||
const icons = {
|
|
||||||
ChromeOutlined,
|
|
||||||
MenuUnfoldOutlined,
|
|
||||||
BoxPlotOutlined,
|
|
||||||
StopOutlined,
|
|
||||||
BorderOutlined,
|
|
||||||
SmileOutlined,
|
|
||||||
GatewayOutlined,
|
|
||||||
QuestionOutlined,
|
|
||||||
DeploymentUnitOutlined,
|
|
||||||
DashboardOutlined,
|
|
||||||
ClockCircleOutlined,
|
|
||||||
UserOutlined,
|
|
||||||
SettingOutlined
|
|
||||||
};
|
|
||||||
|
|
||||||
// ==============================|| MENU ITEMS - SUPPORT ||============================== //
|
// ==============================|| MENU ITEMS - SUPPORT ||============================== //
|
||||||
|
|
||||||
const nearle = {
|
const nearle = {
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ export const fetchDeliveryLocationSummary = async () => {
|
|||||||
// fetchOrders.js
|
// fetchOrders.js
|
||||||
|
|
||||||
export const fetchOrders1 = async ({ pageParam = 1, queryKey }) => {
|
export const fetchOrders1 = async ({ pageParam = 1, queryKey }) => {
|
||||||
const [_key, tenantid, locationid, status, startdate, enddate, searchword, rowsPerPage] = queryKey;
|
const [, tenantid, locationid, status, startdate, enddate, searchword, rowsPerPage] = queryKey;
|
||||||
|
|
||||||
const res = await axios.get(
|
const res = await axios.get(
|
||||||
`${process.env.REACT_APP_URL}/orders/tenant/getorders/?tenantid=${tenantid}&locationid=${locationid}&status=${status}&fromdate=${startdate}&todate=${enddate}&pageno=${pageParam}&pagesize=${rowsPerPage}&keyword=${searchword}`
|
`${process.env.REACT_APP_URL}/orders/tenant/getorders/?tenantid=${tenantid}&locationid=${locationid}&status=${status}&fromdate=${startdate}&todate=${enddate}&pageno=${pageParam}&pagesize=${rowsPerPage}&keyword=${searchword}`
|
||||||
@@ -224,7 +224,7 @@ export const gettenantlocations = async ({ queryKey }) => {
|
|||||||
|
|
||||||
// ==============================|| fetchDeliverySummary (orders summary)||============================== //
|
// ==============================|| fetchDeliverySummary (orders summary)||============================== //
|
||||||
export const fetchDeliverySummary = async ({ queryKey }) => {
|
export const fetchDeliverySummary = async ({ queryKey }) => {
|
||||||
const [, startdate, enddate, currentStatus, locationId] = queryKey;
|
const [, startdate, enddate, , locationId] = queryKey;
|
||||||
const response = await axios.get(
|
const response = await axios.get(
|
||||||
`${process.env.REACT_APP_URL}/deliveries/deliverysummary?tenantid=${tenid}&locationid=${locationId}&fromdate=${startdate}&todate=${enddate}`
|
`${process.env.REACT_APP_URL}/deliveries/deliverysummary?tenantid=${tenid}&locationid=${locationId}&fromdate=${startdate}&todate=${enddate}`
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -24,37 +24,22 @@ const FieldGrid = ({ children }) => (
|
|||||||
|
|
||||||
const CreateCustomer = () => {
|
const CreateCustomer = () => {
|
||||||
const appId = localStorage.getItem('applocationid');
|
const appId = localStorage.getItem('applocationid');
|
||||||
const [selectedImage, setSelectedImage] = useState(undefined);
|
const [selectedImage] = useState(undefined);
|
||||||
const [avatar, setAvatar] = useState();
|
const [, setAvatar] = useState();
|
||||||
const [businessname, setBusinessname] = useState('');
|
|
||||||
const [businessno, setBusinessno] = useState('');
|
|
||||||
const [mobilenumber, setMobilenumber] = useState('');
|
const [mobilenumber, setMobilenumber] = useState('');
|
||||||
const [emailaddress, setEmailaddress] = useState('');
|
const [emailaddress, setEmailaddress] = useState('');
|
||||||
const [city, setCity] = useState('');
|
|
||||||
const [zipcode, setZipcode] = useState('');
|
|
||||||
const [address, setAddress] = useState('');
|
const [address, setAddress] = useState('');
|
||||||
const [suburb, setSuburb] = useState('');
|
|
||||||
const [latlong, setLatlong] = useState({});
|
|
||||||
const [firstname, setFirstname] = useState('');
|
const [firstname, setFirstname] = useState('');
|
||||||
const [doorno, setDoorno] = useState('');
|
const [doorno, setDoorno] = useState('');
|
||||||
const [landmark, setLandmark] = useState('');
|
const [landmark, setLandmark] = useState('');
|
||||||
const [tenantinfo, setTenantinfo] = useState({});
|
const [, setTenantinfo] = useState({});
|
||||||
const [inputValue2, setInputValue2] = useState('');
|
const [inputValue2, setInputValue2] = useState('');
|
||||||
const [appLocaLat, setAppLocaLat] = useState();
|
const [appLocaLat, setAppLocaLat] = useState();
|
||||||
const [appLocaLng, setAppLocaLng] = useState();
|
const [appLocaLng, setAppLocaLng] = useState();
|
||||||
const [appLocaRadius, setAppLocaRadius] = useState();
|
const [appLocaRadius, setAppLocaRadius] = useState();
|
||||||
const [locaName, setLocoName] = useState('Select Location');
|
const [, setLocations] = useState('Select Location');
|
||||||
const [locations, setLocations] = useState('Select Location');
|
|
||||||
const [tenantlist, setTenantlist] = useState([]);
|
|
||||||
const userid = localStorage.getItem('userid');
|
const userid = localStorage.getItem('userid');
|
||||||
const [isAppLocation, setIsAppLocation] = useState(false);
|
const [tid] = useState(0);
|
||||||
const [tenantLocations, setTenantlocations] = useState([]);
|
|
||||||
const [isClient, setisclient] = useState(false);
|
|
||||||
const [tid, setTid] = useState(0);
|
|
||||||
const [isBusiness, setIsBusiness] = useState(false);
|
|
||||||
const [tenanatLocoId, setTenanatLocoId] = useState(localStorage.getItem('locationid'));
|
|
||||||
const [tenantlocation, setTenantlocation] = useState('');
|
|
||||||
const [isLocation, setIsLocation] = useState(false);
|
|
||||||
const [pickCust, setPickCust] = useState({});
|
const [pickCust, setPickCust] = useState({});
|
||||||
const [startPoint, setStartPoint] = useState({ latitude: 0, longitude: 0 });
|
const [startPoint, setStartPoint] = useState({ latitude: 0, longitude: 0 });
|
||||||
|
|
||||||
@@ -86,7 +71,6 @@ const CreateCustomer = () => {
|
|||||||
radius: appLocaRadius * 1000
|
radius: appLocaRadius * 1000
|
||||||
}).getBounds()
|
}).getBounds()
|
||||||
});
|
});
|
||||||
let arr = [];
|
|
||||||
// Event listener for autocomplete place changed
|
// Event listener for autocomplete place changed
|
||||||
autocomplete.addListener('place_changed', () => {
|
autocomplete.addListener('place_changed', () => {
|
||||||
const place = autocomplete.getPlace();
|
const place = autocomplete.getPlace();
|
||||||
@@ -163,7 +147,7 @@ const CreateCustomer = () => {
|
|||||||
.get(`${process.env.REACT_APP_URL}/utils/getapplocations/?applocationid=${appId}`)
|
.get(`${process.env.REACT_APP_URL}/utils/getapplocations/?applocationid=${appId}`)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
logger.info('getapplocations', res);
|
logger.info('getapplocations', res);
|
||||||
const { opentime, closetime, latitude, longitude, radius } = res.data.details?.[0] || {};
|
const { latitude, longitude, radius } = res.data.details?.[0] || {};
|
||||||
if (res.data.status) {
|
if (res.data.status) {
|
||||||
setAppLocaLat(latitude);
|
setAppLocaLat(latitude);
|
||||||
setAppLocaLng(longitude);
|
setAppLocaLng(longitude);
|
||||||
@@ -202,50 +186,6 @@ const CreateCustomer = () => {
|
|||||||
|
|
||||||
// ===================================================== || fetchtenantinfolist || =====================================================
|
// ===================================================== || fetchtenantinfolist || =====================================================
|
||||||
|
|
||||||
const fetchtenantinfolist = async (id) => {
|
|
||||||
setLoading(true);
|
|
||||||
await axios
|
|
||||||
.get(`${process.env.REACT_APP_URL}/tenants/gettenants/?applocationid=${id}&status=active`)
|
|
||||||
|
|
||||||
.then((res) => {
|
|
||||||
logger.info(res);
|
|
||||||
if (res.data.status) {
|
|
||||||
let arr = [];
|
|
||||||
res.data.details.map((val) => {
|
|
||||||
arr.push({
|
|
||||||
...val,
|
|
||||||
label: `${val.tenantname}`
|
|
||||||
});
|
|
||||||
});
|
|
||||||
setTenantlist(arr);
|
|
||||||
}
|
|
||||||
setLoading(false);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
logger.error(err);
|
|
||||||
setLoading(false);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// ============================================= || gettenantlocations (branches) || =============================================
|
|
||||||
const gettenantlocations = async (id) => {
|
|
||||||
try {
|
|
||||||
const res = await axios.get(`${process.env.REACT_APP_URL}/tenants/gettenantlocations/?tenantid=${id}`);
|
|
||||||
logger.info('gettenantlocations', res.data.details);
|
|
||||||
if (res.data.details.length == 1) {
|
|
||||||
setIsLocation(true);
|
|
||||||
setTenantlocations(res.data.details);
|
|
||||||
setTenanatLocoId(res.data.details[0].locationid);
|
|
||||||
setTenantlocation(res.data.details[0].locationaddress); //client address
|
|
||||||
setIsBusiness(true);
|
|
||||||
} else {
|
|
||||||
setTenantlocations(res.data.details);
|
|
||||||
setIsBusiness(false); // became true after select from tenanatLocations
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
logger.error('gettenantlocations', err);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const opentoast = (message) => {
|
const opentoast = (message) => {
|
||||||
enqueueSnackbar(message, {
|
enqueueSnackbar(message, {
|
||||||
variant: 'error',
|
variant: 'error',
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import { useHotkeyFocus } from 'components/nearle_components/useHotkeyFocus';
|
|||||||
import DateFilterDialog from 'components/nearle_components/DateFilterDialog';
|
import DateFilterDialog from 'components/nearle_components/DateFilterDialog';
|
||||||
import CircularLoader from 'components/nearle_components/CircularLoader';
|
import CircularLoader from 'components/nearle_components/CircularLoader';
|
||||||
import { useQuery, useInfiniteQuery } from '@tanstack/react-query';
|
import { useQuery, useInfiniteQuery } from '@tanstack/react-query';
|
||||||
import { useNavigate } from 'react-router-dom';
|
|
||||||
|
|
||||||
import logger from 'utils/logger';
|
import logger from 'utils/logger';
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -201,7 +200,6 @@ const MetricCell = ({ value, color, icon, isMoney = false }) => {
|
|||||||
const noWrapStyle = { whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' };
|
const noWrapStyle = { whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' };
|
||||||
|
|
||||||
const Deliveries = () => {
|
const Deliveries = () => {
|
||||||
const navigate = useNavigate();
|
|
||||||
const tid = localStorage.getItem('tenantid');
|
const tid = localStorage.getItem('tenantid');
|
||||||
const loadMoreRef = useRef();
|
const loadMoreRef = useRef();
|
||||||
const containerRef = useRef();
|
const containerRef = useRef();
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ const ActiveSection = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderActiveDeliveryCard = (o, i) => {
|
const renderActiveDeliveryCard = (o) => {
|
||||||
const rid = o.rider_id || o.userid;
|
const rid = o.rider_id || o.userid;
|
||||||
const rider = riders.find((r) => String(r.id) === String(rid));
|
const rider = riders.find((r) => String(r.id) === String(rid));
|
||||||
const color = getRiderColor(rid);
|
const color = getRiderColor(rid);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useEffect, useMemo, useCallback, useRef } from 'react';
|
import React, { useState, useEffect, useMemo, useCallback, useRef } from 'react';
|
||||||
import { MapContainer, TileLayer, Marker, Popup, Polyline, Tooltip, useMap, useMapEvents, ZoomControl } from 'react-leaflet';
|
import { MapContainer, TileLayer, Marker, Popup, Polyline, Tooltip, useMap, ZoomControl } from 'react-leaflet';
|
||||||
import L from 'leaflet';
|
import L from 'leaflet';
|
||||||
import 'leaflet/dist/leaflet.css';
|
import 'leaflet/dist/leaflet.css';
|
||||||
// Side-effect import: patches L.Polyline so pathOptions.offset (in screen px)
|
// Side-effect import: patches L.Polyline so pathOptions.offset (in screen px)
|
||||||
@@ -20,7 +20,6 @@ import {
|
|||||||
MdStraighten,
|
MdStraighten,
|
||||||
MdLocationOn,
|
MdLocationOn,
|
||||||
MdMarkunreadMailbox,
|
MdMarkunreadMailbox,
|
||||||
MdMoveToInbox,
|
|
||||||
MdPerson,
|
MdPerson,
|
||||||
MdPlace,
|
MdPlace,
|
||||||
MdTwoWheeler,
|
MdTwoWheeler,
|
||||||
@@ -40,10 +39,7 @@ import {
|
|||||||
MdChevronLeft,
|
MdChevronLeft,
|
||||||
MdChevronRight,
|
MdChevronRight,
|
||||||
MdLocalMall,
|
MdLocalMall,
|
||||||
MdCheckCircle,
|
|
||||||
MdErrorOutline,
|
MdErrorOutline,
|
||||||
MdWarning,
|
|
||||||
MdClose,
|
|
||||||
MdFormatListBulleted,
|
MdFormatListBulleted,
|
||||||
MdTimer,
|
MdTimer,
|
||||||
MdCalendarToday,
|
MdCalendarToday,
|
||||||
@@ -52,7 +48,6 @@ import {
|
|||||||
} from 'react-icons/md';
|
} from 'react-icons/md';
|
||||||
import { fetchDeliveries, fetchAppLocations, getRiderPeriodicLogs, fetchRidersLogs, fetchBatchEfficiency } from '../api/api';
|
import { fetchDeliveries, fetchAppLocations, getRiderPeriodicLogs, fetchRidersLogs, fetchBatchEfficiency } from '../api/api';
|
||||||
import {
|
import {
|
||||||
STATUS_STYLES,
|
|
||||||
getStatusStyle,
|
getStatusStyle,
|
||||||
FINAL_STATUSES,
|
FINAL_STATUSES,
|
||||||
SKIPPED_STATUSES,
|
SKIPPED_STATUSES,
|
||||||
@@ -229,11 +224,6 @@ const getRowBatch = (r, fieldId = 'all', batches = BATCHES_DEFAULT) => {
|
|||||||
// the operator clicks empty map space. Markers' click events do NOT bubble
|
// the operator clicks empty map space. Markers' click events do NOT bubble
|
||||||
// to the map, so this only fires on background clicks (which is what we
|
// to the map, so this only fires on background clicks (which is what we
|
||||||
// want — clicking elsewhere should release the pin).
|
// want — clicking elsewhere should release the pin).
|
||||||
function CompareMapClickUnpin({ onUnpin }) {
|
|
||||||
useMapEvents({ click: () => onUnpin() });
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Captures the Leaflet map instance for the parent component via a ref. Kept
|
// Captures the Leaflet map instance for the parent component via a ref. Kept
|
||||||
// available even after the two-map Compare layout was unified into one map,
|
// available even after the two-map Compare layout was unified into one map,
|
||||||
// since future per-step imperative zoom logic still needs a handle on the
|
// since future per-step imperative zoom logic still needs a handle on the
|
||||||
@@ -751,14 +741,6 @@ const ANALYSIS_BATCH_WINDOWS = [
|
|||||||
{ key: 'evening', label: 'Evening', timeRange: '4:00 PM – 7:00 PM', sub: 'Dinner & end-of-day', color: '#6366f1', bg: '#eef2ff', border: '#c7d2fe' }
|
{ key: 'evening', label: 'Evening', timeRange: '4:00 PM – 7:00 PM', sub: 'Dinner & end-of-day', color: '#6366f1', bg: '#eef2ff', border: '#c7d2fe' }
|
||||||
];
|
];
|
||||||
|
|
||||||
// Tolerant field-name lookup so the Analysis card still renders cleanly even
|
|
||||||
// if the API response uses slightly different keys than expected.
|
|
||||||
const analysisPick = (obj, keys) => {
|
|
||||||
for (const k of keys) {
|
|
||||||
if (obj && obj[k] != null && obj[k] !== '') return obj[k];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
const analysisFormatNum = (v) => {
|
const analysisFormatNum = (v) => {
|
||||||
if (v == null) return '—';
|
if (v == null) return '—';
|
||||||
if (typeof v === 'number') return v.toLocaleString('en-IN');
|
if (typeof v === 'number') return v.toLocaleString('en-IN');
|
||||||
@@ -766,14 +748,6 @@ const analysisFormatNum = (v) => {
|
|||||||
if (Number.isFinite(n)) return n.toLocaleString('en-IN');
|
if (Number.isFinite(n)) return n.toLocaleString('en-IN');
|
||||||
return String(v);
|
return String(v);
|
||||||
};
|
};
|
||||||
const analysisFormatKm = (v) => (v == null ? '—' : `${parseFloat(v).toFixed(1)} km`);
|
|
||||||
const analysisFormatRupees = (v) => (v == null ? '—' : `₹${parseFloat(v).toFixed(0)}`);
|
|
||||||
const analysisFormatPct = (v) => {
|
|
||||||
if (v == null) return '—';
|
|
||||||
const n = parseFloat(v);
|
|
||||||
if (!Number.isFinite(n)) return '—';
|
|
||||||
return `${n > 1 ? n.toFixed(1) : (n * 100).toFixed(1)}%`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const Dispatch = ({
|
const Dispatch = ({
|
||||||
data,
|
data,
|
||||||
@@ -795,7 +769,7 @@ const Dispatch = ({
|
|||||||
// map + sidebar UI) or 'analysis' (batch efficiency panel). Embedded use
|
// map + sidebar UI) or 'analysis' (batch efficiency panel). Embedded use
|
||||||
// (Preview) never reaches the Analysis switcher, so default doesn't matter
|
// (Preview) never reaches the Analysis switcher, so default doesn't matter
|
||||||
// there.
|
// there.
|
||||||
const [topView, setTopView] = useState('live');
|
const [topView] = useState('live');
|
||||||
const [analysisResults, setAnalysisResults] = useState({});
|
const [analysisResults, setAnalysisResults] = useState({});
|
||||||
const [analysisLoadingWindow, setAnalysisLoadingWindow] = useState(null);
|
const [analysisLoadingWindow, setAnalysisLoadingWindow] = useState(null);
|
||||||
const [activeBatchKey, setActiveBatchKey] = useState(null);
|
const [activeBatchKey, setActiveBatchKey] = useState(null);
|
||||||
@@ -833,7 +807,7 @@ const Dispatch = ({
|
|||||||
// Single delivery stop pinned by clicking its sidebar row — overrides the rider's full-route bounds on the map.
|
// Single delivery stop pinned by clicking its sidebar row — overrides the rider's full-route bounds on the map.
|
||||||
const [focusedStop, setFocusedStop] = useState(null);
|
const [focusedStop, setFocusedStop] = useState(null);
|
||||||
// Fly-to target set by ActiveSection card clicks — zooms the map without touching sidebar or popup.
|
// Fly-to target set by ActiveSection card clicks — zooms the map without touching sidebar or popup.
|
||||||
const [activeFlyTo, setActiveFlyTo] = useState(null);
|
const [activeFlyTo] = useState(null);
|
||||||
// How the stops inside each trip block are ordered in the focused-rider sidebar:
|
// How the stops inside each trip block are ordered in the focused-rider sidebar:
|
||||||
// 'planned' → the dispatched route order (by step) — the default.
|
// 'planned' → the dispatched route order (by step) — the default.
|
||||||
// 'time' → re-sorted by when each delivery was actually completed, so the
|
// 'time' → re-sorted by when each delivery was actually completed, so the
|
||||||
@@ -863,7 +837,6 @@ const Dispatch = ({
|
|||||||
// Short-lived close timer for the general map order/marker popups.
|
// Short-lived close timer for the general map order/marker popups.
|
||||||
// Gives the cursor a ~200ms window to travel from the marker onto the popup
|
// Gives the cursor a ~200ms window to travel from the marker onto the popup
|
||||||
// or vice versa without immediately triggering a close.
|
// or vice versa without immediately triggering a close.
|
||||||
const activePopupMarkerRef = useRef(null);
|
|
||||||
const popupHoverTimerRef = useRef(null);
|
const popupHoverTimerRef = useRef(null);
|
||||||
// Order shown in the centered popup overlay. Rendered outside the leaflet
|
// Order shown in the centered popup overlay. Rendered outside the leaflet
|
||||||
// map (see `dispatch-popup-center` overlay near the bottom of the JSX) so
|
// map (see `dispatch-popup-center` overlay near the bottom of the JSX) so
|
||||||
@@ -887,9 +860,7 @@ const Dispatch = ({
|
|||||||
// The user's last-picked location is mirrored into localStorage so it
|
// The user's last-picked location is mirrored into localStorage so it
|
||||||
// survives reloads and stays in sync with other pages that read it.
|
// survives reloads and stays in sync with other pages that read it.
|
||||||
const initialAppLocationId = typeof window !== 'undefined' ? localStorage.getItem('applocationid') : null;
|
const initialAppLocationId = typeof window !== 'undefined' ? localStorage.getItem('applocationid') : null;
|
||||||
const [selectedAppLocationId, setSelectedAppLocationId] = useState(
|
const [selectedAppLocationId] = useState(initialAppLocationId != null ? Number(initialAppLocationId) : 0);
|
||||||
initialAppLocationId != null ? Number(initialAppLocationId) : 0
|
|
||||||
);
|
|
||||||
const [locationMenuOpen, setLocationMenuOpen] = useState(false);
|
const [locationMenuOpen, setLocationMenuOpen] = useState(false);
|
||||||
const locationMenuRef = useRef(null);
|
const locationMenuRef = useRef(null);
|
||||||
|
|
||||||
@@ -897,7 +868,7 @@ const Dispatch = ({
|
|||||||
// orders bucket into Morning/Afternoon/Evening by when they were assigned,
|
// orders bucket into Morning/Afternoon/Evening by when they were assigned,
|
||||||
// per current spec. The status-wise time-field dropdown is hidden for now
|
// per current spec. The status-wise time-field dropdown is hidden for now
|
||||||
// (see commented-out block in JSX), so this stays fixed at 'assigned'.
|
// (see commented-out block in JSX), so this stays fixed at 'assigned'.
|
||||||
const [selectedTimeField, setSelectedTimeField] = useState('assigned');
|
const [selectedTimeField] = useState('assigned');
|
||||||
const [timeFieldMenuOpen, setTimeFieldMenuOpen] = useState(false);
|
const [timeFieldMenuOpen, setTimeFieldMenuOpen] = useState(false);
|
||||||
const timeFieldMenuRef = useRef(null);
|
const timeFieldMenuRef = useRef(null);
|
||||||
|
|
||||||
@@ -906,7 +877,7 @@ const Dispatch = ({
|
|||||||
// id/label/range/startHour/endHour just like the default list — the rest
|
// id/label/range/startHour/endHour just like the default list — the rest
|
||||||
// of the file reads BATCHES (derived below) without caring whether the
|
// of the file reads BATCHES (derived below) without caring whether the
|
||||||
// values came from defaults or from operator edits.
|
// values came from defaults or from operator edits.
|
||||||
const [slotsConfig, setSlotsConfig] = useState(() => {
|
const [slotsConfig] = useState(() => {
|
||||||
if (typeof window === 'undefined') return BATCHES_DEFAULT;
|
if (typeof window === 'undefined') return BATCHES_DEFAULT;
|
||||||
try {
|
try {
|
||||||
const raw = window.localStorage.getItem(SLOTS_STORAGE_KEY);
|
const raw = window.localStorage.getItem(SLOTS_STORAGE_KEY);
|
||||||
@@ -1064,21 +1035,6 @@ const Dispatch = ({
|
|||||||
return match?.locationname || null;
|
return match?.locationname || null;
|
||||||
}, [appLocations, selectedAppLocationId]);
|
}, [appLocations, selectedAppLocationId]);
|
||||||
|
|
||||||
const handleLocationPick = (id) => {
|
|
||||||
logger.info('Switching hub/location ID:', id);
|
|
||||||
setSelectedAppLocationId(Number(id));
|
|
||||||
setLocationMenuOpen(false);
|
|
||||||
if (typeof window !== 'undefined') {
|
|
||||||
try { localStorage.setItem('applocationid', String(id)); } catch (e) { /* ignore quota errors */ }
|
|
||||||
}
|
|
||||||
// Switching hubs invalidates the current focused rider/kitchen/zone since
|
|
||||||
// they belong to the previous hub's data. handleRiderFocus is declared
|
|
||||||
// further down the component but the closure is only called after click,
|
|
||||||
// so the reference resolves cleanly.
|
|
||||||
handleRiderFocus(null);
|
|
||||||
setFocusedKitchen(null);
|
|
||||||
setFocusedZone(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
const [osrmRoutes, setOsrmRoutes] = useState({});
|
const [osrmRoutes, setOsrmRoutes] = useState({});
|
||||||
// Mirror of osrmRoutes held in a ref so fetchRoute can check the cache without
|
// Mirror of osrmRoutes held in a ref so fetchRoute can check the cache without
|
||||||
@@ -1777,13 +1733,6 @@ const Dispatch = ({
|
|||||||
};
|
};
|
||||||
}, [focusedRider, focusedKitchen, isAllActiveView, activeViewRiders, stats]);
|
}, [focusedRider, focusedKitchen, isAllActiveView, activeViewRiders, stats]);
|
||||||
|
|
||||||
// Count of in-progress deliveries shown in the Active view list. Derives from
|
|
||||||
// the sticky cache (via activeViewRiders) so header and card list always agree.
|
|
||||||
const activeDeliveryCount = useMemo(
|
|
||||||
() => (isAllActiveView ? activeViewRiders.reduce((sum, r) => sum + r.orders.length, 0) : 0),
|
|
||||||
[isAllActiveView, activeViewRiders]
|
|
||||||
);
|
|
||||||
|
|
||||||
// List of deliveryids we want GPS logs for. Drives two pipelines:
|
// List of deliveryids we want GPS logs for. Drives two pipelines:
|
||||||
// • renderRoutes() — actual-route polylines on the main map for
|
// • renderRoutes() — actual-route polylines on the main map for
|
||||||
// every visible rider/trip
|
// every visible rider/trip
|
||||||
@@ -1850,6 +1799,7 @@ const Dispatch = ({
|
|||||||
// _ts on each ping to compute per-step dt, so we run it BEFORE
|
// _ts on each ping to compute per-step dt, so we run it BEFORE
|
||||||
// stripping _ts on the way out.
|
// stripping _ts on the way out.
|
||||||
const smoothed = kalmanSmoothGps(sorted);
|
const smoothed = kalmanSmoothGps(sorted);
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
return smoothed.map(({ _ts, ...p }) => p);
|
return smoothed.map(({ _ts, ...p }) => p);
|
||||||
},
|
},
|
||||||
// Always-on so the main map can render actual-route polylines (not just
|
// Always-on so the main map can render actual-route polylines (not just
|
||||||
@@ -2787,7 +2737,7 @@ const Dispatch = ({
|
|||||||
? new Map(riderActualTracks.map((t) => [String(t.deliveryid), t.sequenceStep]))
|
? new Map(riderActualTracks.map((t) => [String(t.deliveryid), t.sequenceStep]))
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return ordersToRender.map((o, idx) => {
|
return ordersToRender.map((o) => {
|
||||||
const rid = o.rider_id;
|
const rid = o.rider_id;
|
||||||
const active = rid ? activeRiders.has(rid) : true;
|
const active = rid ? activeRiders.has(rid) : true;
|
||||||
let color = getRiderColor(rid);
|
let color = getRiderColor(rid);
|
||||||
@@ -3180,13 +3130,6 @@ const Dispatch = ({
|
|||||||
return routes;
|
return routes;
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleRider = (rid) => {
|
|
||||||
const newActive = new Set(activeRiders);
|
|
||||||
if (newActive.has(rid)) newActive.delete(rid);
|
|
||||||
else newActive.add(rid);
|
|
||||||
setActiveRiders(newActive);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`dispatch-container${embedded ? ' embedded' : ''}${compareOpen ? ' compare-open' : ''}`}>
|
<div className={`dispatch-container${embedded ? ' embedded' : ''}${compareOpen ? ' compare-open' : ''}`}>
|
||||||
{!embedded && (
|
{!embedded && (
|
||||||
@@ -4928,15 +4871,6 @@ const Dispatch = ({
|
|||||||
(o) => o.deliveryid != null && String(o.deliveryid) === String(t.deliveryid)
|
(o) => o.deliveryid != null && String(o.deliveryid) === String(t.deliveryid)
|
||||||
);
|
);
|
||||||
|
|
||||||
const statusStyle = getStatusStyle(t.orderstatus);
|
|
||||||
const flagSvg = t.orderstatus
|
|
||||||
? `<svg class="cmark-flag" viewBox="0 0 18 22" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<line x1="1.5" y1="0" x2="1.5" y2="22" stroke="#0f172a" stroke-width="1.6" stroke-linecap="round"/>
|
|
||||||
<polygon points="2,1 17,1 13.5,5.5 17,10 2,10" fill="${statusStyle.bg}" stroke="#0f172a" stroke-width="0.6" stroke-linejoin="round"/>
|
|
||||||
${isDelivered ? '<polyline points="5,5.5 7,7.5 11,3.5" fill="none" stroke="#fff" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/>' : ''}
|
|
||||||
</svg>`
|
|
||||||
: '';
|
|
||||||
|
|
||||||
const dropClasses = ['compare-step-pin'];
|
const dropClasses = ['compare-step-pin'];
|
||||||
if (isFocusedStep) dropClasses.push('is-focused');
|
if (isFocusedStep) dropClasses.push('is-focused');
|
||||||
if (isDelivered) dropClasses.push('is-delivered');
|
if (isDelivered) dropClasses.push('is-delivered');
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
import { useMutation } from '@tanstack/react-query';
|
import { useMutation } from '@tanstack/react-query';
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import { HiOutlineArrowLeft } from 'react-icons/hi';
|
import { HiOutlineArrowLeft } from 'react-icons/hi';
|
||||||
import { IoReload } from 'react-icons/io5';
|
|
||||||
import { MdTwoWheeler } from 'react-icons/md';
|
|
||||||
|
|
||||||
import { Button } from '@astryxdesign/core/Button';
|
import { Button } from '@astryxdesign/core/Button';
|
||||||
import { IconButton } from '@astryxdesign/core/IconButton';
|
import { IconButton } from '@astryxdesign/core/IconButton';
|
||||||
@@ -12,27 +9,12 @@ import { Tooltip } from '@astryxdesign/core/Tooltip';
|
|||||||
import { Stack } from '@astryxdesign/core/Stack';
|
import { Stack } from '@astryxdesign/core/Stack';
|
||||||
import { Heading } from '@astryxdesign/core/Heading';
|
import { Heading } from '@astryxdesign/core/Heading';
|
||||||
|
|
||||||
import {
|
import { finalCreatedeliveries, notifyRider } from '../api/api';
|
||||||
createAutomationDeliveries,
|
|
||||||
createOptimisationDeliveries,
|
|
||||||
finalCreatedeliveries,
|
|
||||||
notifyRider,
|
|
||||||
reconcileSteps
|
|
||||||
} from '../api/api';
|
|
||||||
import { OpenToast } from 'components/nearle_components/OpenToast';
|
import { OpenToast } from 'components/nearle_components/OpenToast';
|
||||||
import CSVExport from 'components/third-party/ReactTable';
|
|
||||||
import CircularLoader from 'components/nearle_components/CircularLoader';
|
import CircularLoader from 'components/nearle_components/CircularLoader';
|
||||||
import Dispatch from './Dispatch';
|
import Dispatch from './Dispatch';
|
||||||
import { stepColor } from './dispatchShared';
|
|
||||||
import { BRAND, DT } from '../_shared/ordersDesign';
|
import { BRAND, DT } from '../_shared/ordersDesign';
|
||||||
|
|
||||||
const tuningTypes = [
|
|
||||||
{ tuneid: 1, type: 'Balanced', value: 'balanced' },
|
|
||||||
{ tuneid: 2, type: 'Aggressive Speed', value: 'aggressive_speed' },
|
|
||||||
{ tuneid: 3, type: 'Fuel Saver', value: 'fuel_saver' },
|
|
||||||
{ tuneid: 4, type: 'Zone Strict', value: 'zone_strict' }
|
|
||||||
];
|
|
||||||
|
|
||||||
// Flatten the API's zoned shape into [{ rider_id, rider_name, orders }] for
|
// Flatten the API's zoned shape into [{ rider_id, rider_name, orders }] for
|
||||||
// the Reconcile tab UI and the reconcile-API payload.
|
// the Reconcile tab UI and the reconcile-API payload.
|
||||||
const extractRiders = (previewData) => {
|
const extractRiders = (previewData) => {
|
||||||
@@ -103,91 +85,6 @@ const flattenRiders = (riders) => {
|
|||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Merge a reconcile-API response { riders:[{rider_id, orders}] } back into
|
|
||||||
// dispatchPreviewData. Replaces each rider's orders[] in zones (preserving
|
|
||||||
// zone containment), then rebuilds the flat details list from the new tree.
|
|
||||||
const applyReconcileResponse = (preview, response) => {
|
|
||||||
if (!preview || !Array.isArray(response?.riders)) return preview;
|
|
||||||
const next = JSON.parse(JSON.stringify(preview));
|
|
||||||
|
|
||||||
const newOrdersByRider = new Map(
|
|
||||||
response.riders.map((r) => [String(r.rider_id), r.orders || []])
|
|
||||||
);
|
|
||||||
|
|
||||||
if (Array.isArray(next.zones) && next.zones.length) {
|
|
||||||
// Pass 1: wipe every existing copy of a responding rider's orders across
|
|
||||||
// ALL zones. The server's reconciled list is the single source of truth,
|
|
||||||
// and a rider can be present in multiple zones (one per delivery suburb).
|
|
||||||
// The previous "update first match, delete from map" loop left stale
|
|
||||||
// copies in the other zones, which extractRiders then concatenated into
|
|
||||||
// duplicate orderids — surfacing as duplicate deliveries on Assign.
|
|
||||||
next.zones.forEach((zone) => {
|
|
||||||
if (!Array.isArray(zone.riders)) return;
|
|
||||||
zone.riders.forEach((r) => {
|
|
||||||
const key = String(r.rider_id ?? r.userid);
|
|
||||||
if (newOrdersByRider.has(key)) r.orders = [];
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Pass 2: drop the reconciled orders onto the first zone that already
|
|
||||||
// lists the rider. If the rider isn't anywhere in the tree, append a
|
|
||||||
// fresh rider entry to zone[0].
|
|
||||||
newOrdersByRider.forEach((orders, riderKey) => {
|
|
||||||
let placed = false;
|
|
||||||
for (const zone of next.zones) {
|
|
||||||
if (!Array.isArray(zone.riders)) continue;
|
|
||||||
const target = zone.riders.find(
|
|
||||||
(r) => String(r.rider_id ?? r.userid) === riderKey
|
|
||||||
);
|
|
||||||
if (target) {
|
|
||||||
target.orders = orders;
|
|
||||||
placed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!placed) {
|
|
||||||
const target = next.zones[0];
|
|
||||||
target.riders = target.riders || [];
|
|
||||||
target.riders.push({
|
|
||||||
rider_id: Number(riderKey) || riderKey,
|
|
||||||
rider_name: orders[0]?.rider_name || `Rider ${riderKey}`,
|
|
||||||
orders
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
next.zones = [
|
|
||||||
{
|
|
||||||
zone_name: 'Reconciled',
|
|
||||||
riders: response.riders.map((r) => ({
|
|
||||||
rider_id: r.rider_id,
|
|
||||||
rider_name: r.rider_name || `Rider ${r.rider_id}`,
|
|
||||||
orders: r.orders || []
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rebuild flat details from the updated zones->riders->orders tree.
|
|
||||||
const flatDetails = [];
|
|
||||||
next.zones.forEach((zone) => {
|
|
||||||
(zone.riders || []).forEach((r) => {
|
|
||||||
(r.orders || []).forEach((o) => {
|
|
||||||
flatDetails.push({
|
|
||||||
...o,
|
|
||||||
rider_id: r.rider_id,
|
|
||||||
userid: r.rider_id,
|
|
||||||
rider_name: r.rider_name,
|
|
||||||
rider: r.rider_name
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
next.details = flatDetails;
|
|
||||||
|
|
||||||
return next;
|
|
||||||
};
|
|
||||||
|
|
||||||
const Preview = () => {
|
const Preview = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@@ -197,7 +94,7 @@ const Preview = () => {
|
|||||||
// through this state. The Dispatch tab renders from it, the Reconcile tab
|
// through this state. The Dispatch tab renders from it, the Reconcile tab
|
||||||
// derives its rider list from it, and Assign Orders sends a flattened copy
|
// derives its rider list from it, and Assign Orders sends a flattened copy
|
||||||
// of it to the API.
|
// of it to the API.
|
||||||
const [dispatchPreviewData, setDispatchPreviewData] = useState(stateData.dispatchPreviewData || null);
|
const [dispatchPreviewData] = useState(stateData.dispatchPreviewData || null);
|
||||||
|
|
||||||
// The AI response arrives via location.state, which the browser stores in
|
// The AI response arrives via location.state, which the browser stores in
|
||||||
// history.state and persists across reloads. That means a reload of
|
// history.state and persists across reloads. That means a reload of
|
||||||
@@ -221,34 +118,11 @@ const Preview = () => {
|
|||||||
document.body.style.overflow = 'hidden';
|
document.body.style.overflow = 'hidden';
|
||||||
return () => { document.body.style.overflow = prev; };
|
return () => { document.body.style.overflow = prev; };
|
||||||
}, []);
|
}, []);
|
||||||
const [csvExportData, setCsvExportData] = useState([]);
|
const [, setCsvExportData] = useState([]);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [tabValue, setTabValue] = useState(0);
|
|
||||||
|
|
||||||
const [reconcileLoading, setReconcileLoading] = useState(false);
|
|
||||||
const [hasReconciled, setHasReconciled] = useState(false);
|
|
||||||
|
|
||||||
// Tracks riders whose orders have been edited since the last AI response
|
|
||||||
// or successful reconcile. Only these are sent to the reconcile API — the
|
|
||||||
// server-side step re-ordering only needs to see what actually changed.
|
|
||||||
const [dirtyRiderIds, setDirtyRiderIds] = useState(() => new Set());
|
|
||||||
|
|
||||||
const aiMode = stateData.aiMode ?? 1;
|
|
||||||
const selectedMode = stateData.selectedMode || null;
|
|
||||||
const deliveryData = stateData.deliveryData || [];
|
|
||||||
const autoRiders = stateData.autoRiders || [];
|
|
||||||
const absentRidersPayload = stateData.absentRidersPayload || [];
|
|
||||||
const rider = stateData.rider || null;
|
const rider = stateData.rider || null;
|
||||||
|
|
||||||
const appId = useMemo(() => {
|
|
||||||
if (stateData.appId) return stateData.appId;
|
|
||||||
if (typeof window !== 'undefined') {
|
|
||||||
const v = localStorage.getItem('applocationid');
|
|
||||||
return v ? Number(v) : 0;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}, [stateData.appId]);
|
|
||||||
|
|
||||||
// Derived: rider list for the Reconcile tab. Recomputes whenever the cache
|
// Derived: rider list for the Reconcile tab. Recomputes whenever the cache
|
||||||
// (dispatchPreviewData) changes — so Reconcile reflects here without a separate state.
|
// (dispatchPreviewData) changes — so Reconcile reflects here without a separate state.
|
||||||
const reconcileRiders = useMemo(() => extractRiders(dispatchPreviewData), [dispatchPreviewData]);
|
const reconcileRiders = useMemo(() => extractRiders(dispatchPreviewData), [dispatchPreviewData]);
|
||||||
@@ -293,23 +167,6 @@ const Preview = () => {
|
|||||||
onError: (error) => OpenToast(error.message, 'error', 2000)
|
onError: (error) => OpenToast(error.message, 'error', 2000)
|
||||||
});
|
});
|
||||||
|
|
||||||
const createDeliveryMutation = useMutation({
|
|
||||||
mutationFn: aiMode == 0 ? createOptimisationDeliveries : createAutomationDeliveries,
|
|
||||||
onSuccess: (data) => {
|
|
||||||
OpenToast('Orders Optimised Successfully', 'success', 2000);
|
|
||||||
// Brand new response = brand new source of truth.
|
|
||||||
setDispatchPreviewData(data);
|
|
||||||
setHasReconciled(false);
|
|
||||||
setDirtyRiderIds(new Set());
|
|
||||||
setIsLoading(false);
|
|
||||||
},
|
|
||||||
onError: (error) => {
|
|
||||||
OpenToast(error.message, 'error', 4000);
|
|
||||||
setIsLoading(false);
|
|
||||||
},
|
|
||||||
onSettled: () => setIsLoading(false)
|
|
||||||
});
|
|
||||||
|
|
||||||
const createFinalDeliveryMutation = useMutation({
|
const createFinalDeliveryMutation = useMutation({
|
||||||
mutationFn: finalCreatedeliveries,
|
mutationFn: finalCreatedeliveries,
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
@@ -325,57 +182,6 @@ const Preview = () => {
|
|||||||
onSettled: () => setIsLoading(false)
|
onSettled: () => setIsLoading(false)
|
||||||
});
|
});
|
||||||
|
|
||||||
const reconcileMutation = useMutation({
|
|
||||||
mutationFn: reconcileSteps,
|
|
||||||
onMutate: () => setReconcileLoading(true),
|
|
||||||
onSuccess: (data) => {
|
|
||||||
if (Array.isArray(data?.riders)) {
|
|
||||||
// Merge: applyReconcileResponse replaces orders for riders present
|
|
||||||
// in the response and leaves the rest of the cache untouched.
|
|
||||||
setDispatchPreviewData((prev) => applyReconcileResponse(prev, data));
|
|
||||||
setHasReconciled(true);
|
|
||||||
// Clear only the riders we just reconciled from the dirty set, so
|
|
||||||
// any unrelated edits made meanwhile are preserved.
|
|
||||||
setDirtyRiderIds((prev) => {
|
|
||||||
const next = new Set(prev);
|
|
||||||
data.riders.forEach((r) => next.delete(String(r.rider_id)));
|
|
||||||
return next;
|
|
||||||
});
|
|
||||||
OpenToast('Steps reconciled — preview updated', 'success', 2000);
|
|
||||||
} else {
|
|
||||||
OpenToast('Reconcile returned no rider data', 'warning', 3000);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onError: (error) => {
|
|
||||||
OpenToast(error.message || 'Reconcile failed', 'error', 4000);
|
|
||||||
},
|
|
||||||
onSettled: () => setReconcileLoading(false)
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleCreateDelivery = (tune) => {
|
|
||||||
setIsLoading(true);
|
|
||||||
if (aiMode == 0) {
|
|
||||||
createDeliveryMutation.mutate({ deliveries: deliveryData });
|
|
||||||
} else if (selectedMode && selectedMode?.value == 1) {
|
|
||||||
createDeliveryMutation.mutate({
|
|
||||||
deliveries: deliveryData,
|
|
||||||
hypertuning_params: tune || null,
|
|
||||||
selectedMode,
|
|
||||||
absent_riders: absentRidersPayload
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
createDeliveryMutation.mutate({
|
|
||||||
data: {
|
|
||||||
orders: deliveryData,
|
|
||||||
riders: autoRiders,
|
|
||||||
config: { pay_type: 'hourly', base_pay: 300.0, strategy: 'multi_trip' },
|
|
||||||
absent_riders: absentRidersPayload
|
|
||||||
},
|
|
||||||
selectedMode
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFinalCreateDelivery = () => {
|
const handleFinalCreateDelivery = () => {
|
||||||
if (!finaldeliveryList?.length) {
|
if (!finaldeliveryList?.length) {
|
||||||
OpenToast('No deliveries to assign', 'error', 3000);
|
OpenToast('No deliveries to assign', 'error', 3000);
|
||||||
@@ -385,29 +191,6 @@ const Preview = () => {
|
|||||||
createFinalDeliveryMutation.mutate({ deliveries: finaldeliveryList });
|
createFinalDeliveryMutation.mutate({ deliveries: finaldeliveryList });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleReconcile = () => {
|
|
||||||
if (!reconcileRiders.length) {
|
|
||||||
OpenToast('No riders to reconcile', 'warning', 3000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Only send riders that were edited since the last AI response / reconcile.
|
|
||||||
// Their step ordering is the only thing that can be stale — untouched
|
|
||||||
// riders are skipped to keep the payload small.
|
|
||||||
const dirty = reconcileRiders.filter((r) =>
|
|
||||||
dirtyRiderIds.has(String(r.rider_id))
|
|
||||||
);
|
|
||||||
if (!dirty.length) {
|
|
||||||
OpenToast('No edits to reconcile', 'info', 2500);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
reconcileMutation.mutate({
|
|
||||||
riders: dirty.map((r) => ({
|
|
||||||
rider_id: r.rider_id,
|
|
||||||
orders: r.orders
|
|
||||||
}))
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="dispatch-preview-shell"
|
className="dispatch-preview-shell"
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { useLocation } from 'react-router-dom';
|
|||||||
import logo_nearle1 from '../../../assets/images/doormile-mark.png';
|
import logo_nearle1 from '../../../assets/images/doormile-mark.png';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import Loader from 'components/Loader';
|
|
||||||
import { enqueueSnackbar } from 'notistack';
|
import { enqueueSnackbar } from 'notistack';
|
||||||
import { PrinterFilled } from '@ant-design/icons';
|
import { PrinterFilled } from '@ant-design/icons';
|
||||||
import { useReactToPrint } from 'react-to-print';
|
import { useReactToPrint } from 'react-to-print';
|
||||||
@@ -49,7 +48,6 @@ const InvoicePreview = () => {
|
|||||||
logger.info('previewSelect', location.state);
|
logger.info('previewSelect', location.state);
|
||||||
const componentRef = useRef(null);
|
const componentRef = useRef(null);
|
||||||
const handlePrint = useReactToPrint({ contentRef: componentRef });
|
const handlePrint = useReactToPrint({ contentRef: componentRef });
|
||||||
const [tabletype, settabletype] = useState(true);
|
|
||||||
const [paydialog, setpaydialog] = useState(false);
|
const [paydialog, setpaydialog] = useState(false);
|
||||||
const [refnumber, setRefnumber] = useState('');
|
const [refnumber, setRefnumber] = useState('');
|
||||||
const [remarks, setRemarks] = useState('');
|
const [remarks, setRemarks] = useState('');
|
||||||
|
|||||||
@@ -66,9 +66,9 @@ const ResponsiveLocationDrawer = () => {
|
|||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [page, setPage] = React.useState(0);
|
const [page, setPage] = React.useState(0);
|
||||||
const [rowsPerPage, setRowsPerPage] = React.useState(10);
|
const [rowsPerPage, setRowsPerPage] = React.useState(10);
|
||||||
const [pageCount, setPageCount] = React.useState(0);
|
const [, setPageCount] = React.useState(0);
|
||||||
const [startdate, setStartdate] = useState(dayjs().format('YYYY-MM-DD'));
|
const [startdate] = useState(dayjs().format('YYYY-MM-DD'));
|
||||||
const [enddate, setEnddate] = useState(dayjs().format('YYYY-MM-DD'));
|
const [enddate] = useState(dayjs().format('YYYY-MM-DD'));
|
||||||
const [searchLocation, setSearchLocation] = useState('');
|
const [searchLocation, setSearchLocation] = useState('');
|
||||||
const [debouncedSearchLocation, setDebouncedSearchLocation] = useState('');
|
const [debouncedSearchLocation, setDebouncedSearchLocation] = useState('');
|
||||||
|
|
||||||
@@ -137,9 +137,7 @@ const ResponsiveLocationDrawer = () => {
|
|||||||
data: ordersData,
|
data: ordersData,
|
||||||
fetchNextPage,
|
fetchNextPage,
|
||||||
hasNextPage,
|
hasNextPage,
|
||||||
isFetchingNextPage,
|
isFetchingNextPage
|
||||||
isLoading,
|
|
||||||
error
|
|
||||||
} = useInfiniteQuery({
|
} = useInfiniteQuery({
|
||||||
queryKey: [
|
queryKey: [
|
||||||
'orders',
|
'orders',
|
||||||
|
|||||||
@@ -229,14 +229,6 @@ const OrdersPreview = () => {
|
|||||||
enabled: appId !== 0 // Ensures query runs only when appId is valid
|
enabled: appId !== 0 // Ensures query runs only when appId is valid
|
||||||
});
|
});
|
||||||
|
|
||||||
const getRiderName = async (userid) => {
|
|
||||||
await ridersList.map((rider) => {
|
|
||||||
if (rider.userid == userid) {
|
|
||||||
return rider.firstname;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const paymentOptions = useMemo(
|
const paymentOptions = useMemo(
|
||||||
() => (paymentModes || []).map((v) => ({ value: String(v.apptypeid), label: v.label })),
|
() => (paymentModes || []).map((v) => ({ value: String(v.apptypeid), label: v.label })),
|
||||||
[paymentModes]
|
[paymentModes]
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import { FaLocationDot } from 'react-icons/fa6';
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import Geocode from 'react-geocode';
|
import Geocode from 'react-geocode';
|
||||||
import Loader from 'components/Loader';
|
import Loader from 'components/Loader';
|
||||||
import * as geolib from 'geolib';
|
|
||||||
import { FaUser } from 'react-icons/fa6';
|
import { FaUser } from 'react-icons/fa6';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { enqueueSnackbar } from 'notistack';
|
import { enqueueSnackbar } from 'notistack';
|
||||||
@@ -58,10 +57,10 @@ import {
|
|||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Plain-CSS layout shims — Astryx has no Grid/Stack/Box/Typography/Paper
|
// Plain-CSS layout shims — Astryx has no Grid/Stack/Box/Typography/Paper
|
||||||
// equivalents, so these small local helpers (not @mui) stand in for the MUI
|
// equivalents, so these small local helpers stand in for the
|
||||||
// layout primitives previously used here, translating the same `sx`-shaped
|
// layout primitives previously used here, translating the same `sx`-shaped
|
||||||
// spacing shorthand (p/m/gap/borderRadius are ×8px steps, bgcolor→
|
// spacing shorthand (p/m/gap/borderRadius are ×8px steps, bgcolor→
|
||||||
// backgroundColor) into real inline CSS. MUI pseudo-selector keys (e.g.
|
// backgroundColor) into real inline CSS. Pseudo-selector keys (e.g.
|
||||||
// `'&:hover'`) are not representable inline and are dropped.
|
// `'&:hover'`) are not representable inline and are dropped.
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
const SPACING_KEYS = {
|
const SPACING_KEYS = {
|
||||||
@@ -321,37 +320,13 @@ function loadScript(src, position, id) {
|
|||||||
const Createorder1 = () => {
|
const Createorder1 = () => {
|
||||||
Geocode.setApiKey(process.env.REACT_APP_GOOGLE_MAPS_API_KEY);
|
Geocode.setApiKey(process.env.REACT_APP_GOOGLE_MAPS_API_KEY);
|
||||||
// ================================================= || GoogleMaps (Drawer) || =================================================
|
// ================================================= || GoogleMaps (Drawer) || =================================================
|
||||||
const [value, setValue] = React.useState(null);
|
const [, setValue] = React.useState(null);
|
||||||
const [value1, setValue1] = React.useState(null);
|
const [, setValue1] = React.useState(null);
|
||||||
const [inputValue, setInputValue] = React.useState('');
|
|
||||||
const [inputValue1, setInputValue1] = React.useState('');
|
|
||||||
const [inputValue2, setInputValue2] = React.useState('');
|
const [inputValue2, setInputValue2] = React.useState('');
|
||||||
const [inputValue3, setInputValue3] = React.useState('');
|
const [inputValue3, setInputValue3] = React.useState('');
|
||||||
const [options, setOptions] = React.useState([]);
|
|
||||||
const [options1, setOptions1] = React.useState([]);
|
|
||||||
const loaded = React.useRef(false);
|
const loaded = React.useRef(false);
|
||||||
const loaded1 = React.useRef(false);
|
const [, setAddress] = useState('');
|
||||||
const [mobilenumber, setMobilenumber] = useState('');
|
const [, setAddress1] = useState('');
|
||||||
const [emailaddress, setEmailaddress] = useState('');
|
|
||||||
const [city, setCity] = useState('');
|
|
||||||
const [city1, setCity1] = useState('');
|
|
||||||
const [zipcode, setZipcode] = useState('');
|
|
||||||
const [zipcode1, setZipcode1] = useState('');
|
|
||||||
const [state, setState] = useState('');
|
|
||||||
const [state1, setState1] = useState('');
|
|
||||||
const [suburb, setSuburb] = useState('');
|
|
||||||
const [suburb1, setSuburb1] = useState('');
|
|
||||||
const [pickContactName, setPickContactName] = useState('');
|
|
||||||
const [dropContactName, setDropContactName] = useState('');
|
|
||||||
const [pickdoorno, setPickDoorno] = useState('');
|
|
||||||
const [dropDoorno, setDropDoorno] = useState('');
|
|
||||||
const [pickLandmark, setPickLandmark] = useState('');
|
|
||||||
const [dropLandmark, setDropLandmark] = useState('');
|
|
||||||
const [address, setAddress] = useState('');
|
|
||||||
const [address1, setAddress1] = useState('');
|
|
||||||
const [latlong, setLatlong] = useState({});
|
|
||||||
const [latlong1, setLatlong1] = useState({});
|
|
||||||
const autocompleteService = useRef(null);
|
|
||||||
const [tenanatLocoId, setTenanatLocoId] = useState(localStorage.getItem('locationid'));
|
const [tenanatLocoId, setTenanatLocoId] = useState(localStorage.getItem('locationid'));
|
||||||
const [isLocation, setIsLocation] = useState(false);
|
const [isLocation, setIsLocation] = useState(false);
|
||||||
const textFieldRef1 = useRef(null);
|
const textFieldRef1 = useRef(null);
|
||||||
@@ -359,28 +334,6 @@ const Createorder1 = () => {
|
|||||||
const [collectionamt, setCollectionamt] = useState(0);
|
const [collectionamt, setCollectionamt] = useState(0);
|
||||||
const [quantity, setQuantity] = useState(1);
|
const [quantity, setQuantity] = useState(1);
|
||||||
|
|
||||||
const handleOkClick1 = () => {
|
|
||||||
// Set focus back to the text field after clicking the "OK" chip
|
|
||||||
if (textFieldRef1.current) {
|
|
||||||
textFieldRef1.current.focus();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleOkClick2 = () => {
|
|
||||||
// Set focus back to the text field after clicking the "OK" chip
|
|
||||||
if (textFieldRef2.current) {
|
|
||||||
textFieldRef2.current.focus();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const top100Films = [
|
|
||||||
{ label: 'The Shawshank Redemption', year: 1994 },
|
|
||||||
{ label: 'The Godfather', year: 1972 },
|
|
||||||
{ label: 'The Godfather: Part II', year: 1974 },
|
|
||||||
{ label: 'The Dark Knight', year: 2008 },
|
|
||||||
{ label: '12 Angry Men', year: 1957 }
|
|
||||||
];
|
|
||||||
|
|
||||||
// // // ====================================================== || address (pick)|| ======================================================
|
// // // ====================================================== || address (pick)|| ======================================================
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
// if (address) {
|
// if (address) {
|
||||||
@@ -603,52 +556,28 @@ const Createorder1 = () => {
|
|||||||
|
|
||||||
const appId = localStorage.getItem('applocationid');
|
const appId = localStorage.getItem('applocationid');
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [open, setOpen] = useState({});
|
|
||||||
const [open1, setOpen1] = useState('');
|
|
||||||
const [open2, setOpen2] = useState(false);
|
|
||||||
const [open3, setOpen3] = useState(false);
|
|
||||||
const [open4, setOpen4] = useState(false);
|
const [open4, setOpen4] = useState(false);
|
||||||
const [shift, setShift] = useState(1);
|
|
||||||
const [clientlist, setClientlist] = useState([]);
|
|
||||||
const [clientdetail, setClientdetail] = useState([]);
|
const [clientdetail, setClientdetail] = useState([]);
|
||||||
const [eventname, setEventname] = useState('');
|
|
||||||
const [startdate, setStartdate] = useState(dayjs().format('MM-DD-YYYY'));
|
const [startdate, setStartdate] = useState(dayjs().format('MM-DD-YYYY'));
|
||||||
const [enddate, setEnddate] = useState(dayjs().add(1, 'day').format('MM-DD-YYYY'));
|
const [, setEnddate] = useState(dayjs().add(1, 'day').format('MM-DD-YYYY'));
|
||||||
// const [starttime, setStatrttime] = useState(`${dayjs().format('MM-DD-YYYY')} 08:00:00`);
|
// const [starttime, setStatrttime] = useState(`${dayjs().format('MM-DD-YYYY')} 08:00:00`);
|
||||||
const [starttime, setStatrttime] = useState();
|
const [starttime, setStatrttime] = useState();
|
||||||
// const [endtime, setEndtime] = useState(`${dayjs().format('MM-DD-YYYY')} 20:00:00`);
|
// const [endtime, setEndtime] = useState(`${dayjs().format('MM-DD-YYYY')} 20:00:00`);
|
||||||
const [endtime, setEndtime] = useState();
|
const [endtime, setEndtime] = useState();
|
||||||
const [timeslotarr, setTimeslotarr] = useState([]);
|
const [timeslotarr, setTimeslotarr] = useState([]);
|
||||||
const [currentsno, setCurrentsno] = useState('');
|
|
||||||
const [roleoptions, setRoleoptions] = useState([]);
|
|
||||||
const [otherinstructions, setOtherinstructions] = useState('');
|
const [otherinstructions, setOtherinstructions] = useState('');
|
||||||
const [attireslist, setAttireslist] = useState([]);
|
const [, setLoading2] = useState(false);
|
||||||
const [serviceaddonslist, setServiceaddonslist] = useState([]);
|
|
||||||
const [orderaddonobj, setOrderaddonobj] = useState([]);
|
|
||||||
const [stafflist, setStafflist] = useState([]);
|
|
||||||
const [loading2, setLoading2] = useState(false);
|
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [btnLoading, setBtnLoading] = useState(false);
|
const [btnLoading, setBtnLoading] = useState(false);
|
||||||
const [shiftarr, setShiftarr] = useState([]);
|
const [shiftarr] = useState([]);
|
||||||
const [shiftarr1, setShiftarr1] = useState([]);
|
const [, setOrderarr] = useState([]);
|
||||||
const [orderarr, setOrderarr] = useState([]);
|
|
||||||
const [alertmessage, setAlertmessage] = useState('');
|
const [alertmessage, setAlertmessage] = useState('');
|
||||||
const [tabstatus, setTabstatus] = useState('');
|
const [searchword] = useState('');
|
||||||
const [tenantinfo, setTenantinfo] = useState({});
|
const [, setClientdetailarr] = useState([]);
|
||||||
const [searchword, setSearchword] = useState('');
|
|
||||||
const [clientdetailarr, setClientdetailarr] = useState([]);
|
|
||||||
const [clientdetailbusinessarr, setClientdetailbusinessarr] = useState([]);
|
|
||||||
const [admintoken, setAdmintoken] = useState();
|
const [admintoken, setAdmintoken] = useState();
|
||||||
const [tenantlocationlist, setTenantlocationlist] = useState([]);
|
|
||||||
const [tenant, setTenant] = useState({});
|
const [tenant, setTenant] = useState({});
|
||||||
const [clientinfo, setClientinfo] = useState({});
|
|
||||||
const [selectedtime, setSelectedtime] = useState('');
|
const [selectedtime, setSelectedtime] = useState('');
|
||||||
const [tenantlist, setTenantlist] = useState([]);
|
const [, setTenantid] = useState();
|
||||||
const [tenantid, setTenantid] = useState();
|
|
||||||
const [tenantlocation, setTenantlocation] = useState('');
|
|
||||||
const [pickupswitch, setPickupswitch] = useState(true);
|
|
||||||
const [deliverytype, setDeliverytype] = useState('B');
|
|
||||||
const [dropswitch, setDropswitch] = useState(false);
|
|
||||||
const [startPoint, setStartPoint] = useState({ latitude: 0, longitude: 0 });
|
const [startPoint, setStartPoint] = useState({ latitude: 0, longitude: 0 });
|
||||||
const [endPoint, setEndPoint] = useState({ latitude: 0, longitude: 0 });
|
const [endPoint, setEndPoint] = useState({ latitude: 0, longitude: 0 });
|
||||||
const [showDistance, setShowDistance] = useState(false);
|
const [showDistance, setShowDistance] = useState(false);
|
||||||
@@ -660,7 +589,7 @@ const Createorder1 = () => {
|
|||||||
const [subCat, setSubCat] = useState([]);
|
const [subCat, setSubCat] = useState([]);
|
||||||
const [subCatName, setSubCatName] = useState('Select ');
|
const [subCatName, setSubCatName] = useState('Select ');
|
||||||
const [subCatId, setSubCatId] = useState();
|
const [subCatId, setSubCatId] = useState();
|
||||||
const [weight, setWeight] = useState('');
|
const [, setWeight] = useState('');
|
||||||
const tid = localStorage.getItem('tenantid');
|
const tid = localStorage.getItem('tenantid');
|
||||||
const [selectedCatChip, setSelectedCatChip] = useState(null);
|
const [selectedCatChip, setSelectedCatChip] = useState(null);
|
||||||
const [isCustomerOpen, setIsCustomerOpen] = useState(false);
|
const [isCustomerOpen, setIsCustomerOpen] = useState(false);
|
||||||
@@ -717,26 +646,6 @@ const Createorder1 = () => {
|
|||||||
}
|
}
|
||||||
}, [startPoint, endPoint]);
|
}, [startPoint, endPoint]);
|
||||||
|
|
||||||
const getDistance = () => {
|
|
||||||
const dist = geolib.getPreciseDistance(startPoint, endPoint, 1);
|
|
||||||
logger.info(`Distance: ${dist} meters`);
|
|
||||||
const distanceInKm = (dist / 1000).toFixed(2);
|
|
||||||
const roundedDistance = Math.round(distanceInKm);
|
|
||||||
logger.info('roundedDistance', roundedDistance);
|
|
||||||
setDistance(roundedDistance.toFixed(2));
|
|
||||||
if (roundedDistance < minKm) {
|
|
||||||
setTotalCharge(basePrice);
|
|
||||||
} else {
|
|
||||||
const total = (roundedDistance - minKm) * pricePerKm + basePrice;
|
|
||||||
setTotalCharge(total);
|
|
||||||
}
|
|
||||||
setShowDistance(true);
|
|
||||||
if (roundedDistance > appLocaRadius) {
|
|
||||||
setShowDistance(true);
|
|
||||||
setOpen4(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const calculateDistance = async (pickup, drop) => {
|
const calculateDistance = async (pickup, drop) => {
|
||||||
try {
|
try {
|
||||||
const roundedDistance = await calculateDrivingDistance(pickup, drop);
|
const roundedDistance = await calculateDrivingDistance(pickup, drop);
|
||||||
@@ -904,9 +813,9 @@ const Createorder1 = () => {
|
|||||||
logger.info('endtime', `${dayjs().format('MM-DD-YYYY')} ${closetime} `);
|
logger.info('endtime', `${dayjs().format('MM-DD-YYYY')} ${closetime} `);
|
||||||
let arr = [];
|
let arr = [];
|
||||||
for (
|
for (
|
||||||
let i = `${dayjs().format('MM-DD-YYYY')} ${opentime}`, j = 0;
|
let i = `${dayjs().format('MM-DD-YYYY')} ${opentime}`;
|
||||||
dayjs(`${dayjs().format('MM-DD-YYYY')} ${closetime} `).diff(i, 'm') >= 0;
|
dayjs(`${dayjs().format('MM-DD-YYYY')} ${closetime} `).diff(i, 'm') >= 0;
|
||||||
j++, i = dayjs(i).add(30, 'm')
|
i = dayjs(i).add(30, 'm')
|
||||||
) {
|
) {
|
||||||
arr.push(i);
|
arr.push(i);
|
||||||
}
|
}
|
||||||
@@ -961,14 +870,6 @@ const Createorder1 = () => {
|
|||||||
logger.info(alertmessage);
|
logger.info(alertmessage);
|
||||||
};
|
};
|
||||||
|
|
||||||
function closeAddressModal() {
|
|
||||||
setOpen2(false);
|
|
||||||
}
|
|
||||||
function closetimemodal() {
|
|
||||||
setOpen3(false);
|
|
||||||
setCurrentsno('');
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================== || createsubmitobj1 (create orders) || ===============================================
|
// =============================================== || createsubmitobj1 (create orders) || ===============================================
|
||||||
|
|
||||||
const createsubmitobj2 = async () => {
|
const createsubmitobj2 = async () => {
|
||||||
@@ -1149,17 +1050,6 @@ const Createorder1 = () => {
|
|||||||
logger.info(shiftarr);
|
logger.info(shiftarr);
|
||||||
}, [shiftarr]);
|
}, [shiftarr]);
|
||||||
|
|
||||||
const clicked1 = (e) => {
|
|
||||||
setShift(e);
|
|
||||||
};
|
|
||||||
|
|
||||||
const dialogopen = (i, result) => {
|
|
||||||
logger.info(i, result);
|
|
||||||
setOpen({ shiftsno: result.sno, sno: i.sno });
|
|
||||||
};
|
|
||||||
const dialogclose = () => {
|
|
||||||
setOpen('');
|
|
||||||
};
|
|
||||||
// ========================================================= || clientdetails || =========================================================
|
// ========================================================= || clientdetails || =========================================================
|
||||||
const clientdetails = async () => {
|
const clientdetails = async () => {
|
||||||
setLoading2(true);
|
setLoading2(true);
|
||||||
@@ -1207,78 +1097,6 @@ const Createorder1 = () => {
|
|||||||
clientdetails();
|
clientdetails();
|
||||||
// clientdetailsbusiness();
|
// clientdetailsbusiness();
|
||||||
}, [searchCustList.length > 3, searchCustList == '']);
|
}, [searchCustList.length > 3, searchCustList == '']);
|
||||||
// ========================================================= || clientdetailsbusiness || =========================================================
|
|
||||||
const clientdetailsbusiness = async () => {
|
|
||||||
setLoading2(true);
|
|
||||||
try {
|
|
||||||
await axios
|
|
||||||
.get(`${process.env.REACT_APP_URL}/customers/getbytid/?tenantid=${tid}&locationid=1`)
|
|
||||||
.then((res) => {
|
|
||||||
logger.info('clientdetailsbusiness', res.data.details);
|
|
||||||
if (res.data.status) {
|
|
||||||
setClientdetail(res.data.details);
|
|
||||||
// if (!searchword) {
|
|
||||||
// setClientdetailarr(res.data.details)
|
|
||||||
// }
|
|
||||||
let arr = [];
|
|
||||||
res.data.details.map((val) => {
|
|
||||||
arr.push({
|
|
||||||
label: `${val.firstname} | ${val.contactno}`,
|
|
||||||
...val
|
|
||||||
});
|
|
||||||
});
|
|
||||||
setClientdetailbusinessarr(arr);
|
|
||||||
}
|
|
||||||
setLoading2(false);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
logger.error(err);
|
|
||||||
setLoading2(false);
|
|
||||||
opentoast('server error', 'warning');
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
logger.error(err);
|
|
||||||
setLoading2(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// ================================================== || sendnotifications || ==================================================
|
|
||||||
const sendnotifications = async () => {
|
|
||||||
setLoading(true);
|
|
||||||
await axios
|
|
||||||
.post(`${process.env.REACT_APP_URL}/utils/sendnotifications`, {
|
|
||||||
priority: 'high',
|
|
||||||
registration_ids: admintoken,
|
|
||||||
data: {
|
|
||||||
accessid: process.env.REACT_APP_RIDER_ACCESS_ID
|
|
||||||
},
|
|
||||||
notification: {
|
|
||||||
title: 'Nearle Merchant',
|
|
||||||
body: 'An Order has been placed successfully,kindly process the same',
|
|
||||||
sound: 'ring'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
logger.info(res);
|
|
||||||
if (res.data.message == 'Success') {
|
|
||||||
enqueueSnackbar('Notification sent Successfully', {
|
|
||||||
variant: 'success',
|
|
||||||
anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
||||||
autoHideDuration: 1000
|
|
||||||
});
|
|
||||||
}
|
|
||||||
setLoading(false);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
logger.error(err);
|
|
||||||
enqueueSnackbar(err.message, {
|
|
||||||
variant: 'error',
|
|
||||||
anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
||||||
autoHideDuration: 1000
|
|
||||||
});
|
|
||||||
setLoading(false);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// ============================================= || Google Maps Autocomplete(pick) || =============================================
|
// ============================================= || Google Maps Autocomplete(pick) || =============================================
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Initialize Google Maps Autocomplete
|
// Initialize Google Maps Autocomplete
|
||||||
@@ -1294,7 +1112,6 @@ const Createorder1 = () => {
|
|||||||
radius: appLocaRadius * 1000
|
radius: appLocaRadius * 1000
|
||||||
}).getBounds()
|
}).getBounds()
|
||||||
});
|
});
|
||||||
let arr = [];
|
|
||||||
// Event listener for autocomplete place changed
|
// Event listener for autocomplete place changed
|
||||||
autocomplete.addListener('place_changed', () => {
|
autocomplete.addListener('place_changed', () => {
|
||||||
const place = autocomplete.getPlace();
|
const place = autocomplete.getPlace();
|
||||||
@@ -1380,7 +1197,6 @@ const Createorder1 = () => {
|
|||||||
// radius: 100000 //km to m
|
// radius: 100000 //km to m
|
||||||
}).getBounds()
|
}).getBounds()
|
||||||
});
|
});
|
||||||
let arr = [];
|
|
||||||
// Event listener for autocomplete place changed
|
// Event listener for autocomplete place changed
|
||||||
autocomplete.addListener('place_changed', () => {
|
autocomplete.addListener('place_changed', () => {
|
||||||
const place = autocomplete.getPlace();
|
const place = autocomplete.getPlace();
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ const Details = () => {
|
|||||||
const [tenantaddress, setTenantaddress] = useState('');
|
const [tenantaddress, setTenantaddress] = useState('');
|
||||||
const [dialogopen, setDialogopen] = useState(false);
|
const [dialogopen, setDialogopen] = useState(false);
|
||||||
const [orderstatus, setOrderstatus] = useState('');
|
const [orderstatus, setOrderstatus] = useState('');
|
||||||
const [currentrole, setCurrentrole] = useState('');
|
const [currentrole] = useState('');
|
||||||
const [taxamount, setTaxamount] = useState('');
|
const [taxamount, setTaxamount] = useState('');
|
||||||
const [subtotal, setSubtotal] = useState('');
|
const [subtotal, setSubtotal] = useState('');
|
||||||
const [grandtotal, setGrandtotal] = useState('');
|
const [grandtotal, setGrandtotal] = useState('');
|
||||||
@@ -253,13 +253,13 @@ const Details = () => {
|
|||||||
const [staffarr, setStaffarr] = useState([]);
|
const [staffarr, setStaffarr] = useState([]);
|
||||||
const [orderheaderid, setOrderheaderid] = useState('');
|
const [orderheaderid, setOrderheaderid] = useState('');
|
||||||
const [tenantid, setTenantid] = useState('');
|
const [tenantid, setTenantid] = useState('');
|
||||||
const [starttime, setStarttime] = useState('');
|
const [starttime] = useState('');
|
||||||
const [endtime, setEndtime] = useState('');
|
const [endtime] = useState('');
|
||||||
// const [orderstatus,setOrderstatus]=useStatus('');
|
// const [orderstatus,setOrderstatus]=useStatus('');
|
||||||
const [pendingtime, setPendingtime] = useState('');
|
const [pendingtime, setPendingtime] = useState('');
|
||||||
// const [processdate,setProcessdate]=useState('');
|
// const [processdate,setProcessdate]=useState('');
|
||||||
const [orderdetailid, setOrderdetailid] = useState('');
|
const [orderdetailid] = useState('');
|
||||||
const [productid, setProductid] = useState('');
|
const [productid] = useState('');
|
||||||
const [categoryarr, setcategoryarr] = useState([])
|
const [categoryarr, setcategoryarr] = useState([])
|
||||||
const [currentshiftobj, setCurrentshiftobj] = useState({
|
const [currentshiftobj, setCurrentshiftobj] = useState({
|
||||||
shifts: 0,
|
shifts: 0,
|
||||||
@@ -268,7 +268,7 @@ const Details = () => {
|
|||||||
shiftid: 0,
|
shiftid: 0,
|
||||||
price: 0
|
price: 0
|
||||||
});
|
});
|
||||||
const [tabstatus, setTabstatus] = useState(0)
|
const [, setTabstatus] = useState(0)
|
||||||
const { state } = useLocation();
|
const { state } = useLocation();
|
||||||
const [assignedpendingcount, setAssignedpendingcount] = useState('');
|
const [assignedpendingcount, setAssignedpendingcount] = useState('');
|
||||||
// const [, forceUpdate] = useReducer(x => x + 1, 0);
|
// const [, forceUpdate] = useReducer(x => x + 1, 0);
|
||||||
@@ -409,48 +409,6 @@ const Details = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchroleslist = async (cid, starttime1, endtime1, hid, sid) => {
|
|
||||||
let fromdate = dayjs(starttime1).subtract(59, 'minutes')
|
|
||||||
.format('YYYY-MM-DD HH:mm:ss');
|
|
||||||
// let todate = dayjs(endtime1).utc().format('YYYY-MM-DD HH:mm:ss');
|
|
||||||
// let fromdate = dayjs(starttime1).utc().format('YYYY-MM-DD HH:mm:ss');
|
|
||||||
let todate = dayjs(endtime1)
|
|
||||||
.format('YYYY-MM-DD HH:mm:ss');
|
|
||||||
let url1;
|
|
||||||
if (starttime1) {
|
|
||||||
url1 = `${process.env.REACT_APP_URL2}/staffs/pools/getstaffs/?categoryid=${cid}&headerid=${hid}&shiftid=${sid}&starttime=${fromdate}&endtime=${todate}`;
|
|
||||||
} else {
|
|
||||||
url1 = `${process.env.REACT_APP_URL2}/staffs/pools/getstaffs/?categoryid=${cid}&headerid=${hid}&shiftid=${sid}`
|
|
||||||
}
|
|
||||||
setLoading(true);
|
|
||||||
setStafflist([])
|
|
||||||
await axios
|
|
||||||
// .get(`${process.env.REACT_APP_URL2}/staffs/pools/getstaffs/?categoryid=${cid}&headerid=${hid}&starttime=${fromdate}&endtime=${todate}`)
|
|
||||||
.get(url1)
|
|
||||||
.then((res) => {
|
|
||||||
logger.info('rolelist');
|
|
||||||
logger.info(res);
|
|
||||||
// logger.info(fromdate, todate)
|
|
||||||
// logger.info(dayjs(starttime1).format('YYYY-MM-DD HH:mm:ss'))
|
|
||||||
// logger.info(dayjs(endtime1).format('HH:mm:ss'))
|
|
||||||
|
|
||||||
|
|
||||||
setStafflist(res.data.Details || [])
|
|
||||||
// let result = res.data.Details.find((res1) => res1.orderheaderid == searchParams.get('id'))
|
|
||||||
// orderheaderid
|
|
||||||
// logger.info(result)
|
|
||||||
// setOrderaddons(result.orderaddons);
|
|
||||||
// setVenuetype(result.venuetype)
|
|
||||||
// setOtherinstructions(result.remarks)
|
|
||||||
setLoading(false);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
logger.error(err);
|
|
||||||
setLoading(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const fetchstafflist = async (odid) => {
|
const fetchstafflist = async (odid) => {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
try {
|
try {
|
||||||
@@ -789,88 +747,6 @@ const Details = () => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchassignedstaffs = async () => {
|
|
||||||
|
|
||||||
// logger.info(obj1)
|
|
||||||
await axios.get(`${process.env.REACT_APP_URL2}/orders/getnotificationusers?orderheaderid=${orderheaderid}`)
|
|
||||||
.then((res) => {
|
|
||||||
if (res.data.status) {
|
|
||||||
let arr1 = [];
|
|
||||||
let data2;
|
|
||||||
let tokenarr = []
|
|
||||||
logger.info(res)
|
|
||||||
|
|
||||||
res.data.details.map((val) => {
|
|
||||||
arr1.push({
|
|
||||||
"notificationid": 0,
|
|
||||||
"notificationdate": dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
|
||||||
"Title": "Staff Asigned",
|
|
||||||
"message": `${val.staffname} has been assigned to the order ${orderid}`,
|
|
||||||
"configid": 2,
|
|
||||||
"tenantid": tenantid,
|
|
||||||
"orderheaderid": orderheaderid,
|
|
||||||
"orderprocessid": val.orderprocessid,
|
|
||||||
"shiftid": val.shiftid,
|
|
||||||
"userid": val.userid,
|
|
||||||
"orderid": orderid,
|
|
||||||
"success": 0,
|
|
||||||
"orderstatus": 'assigned',
|
|
||||||
"processing": dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
|
||||||
"notifytype": 1,
|
|
||||||
"notifyreason": 'Staff Assigned'
|
|
||||||
// "sound": "ring",
|
|
||||||
// "click_action": "FLUTTER_NOTIFICATION_CLICK",
|
|
||||||
// "firstname": val.firstname
|
|
||||||
|
|
||||||
});
|
|
||||||
tokenarr.push(val.userfcmtoken);
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
data2 = {
|
|
||||||
"Title": "Staff Asigned",
|
|
||||||
"message": `A Staff has been assigned to the order ${orderid}`,
|
|
||||||
"tenantid": tenantid,
|
|
||||||
"orderheaderid": orderheaderid,
|
|
||||||
"orderid": orderid,
|
|
||||||
"configid": 2,
|
|
||||||
// "click_action": "FLUTTER_NOTIFICATION_CLICK"
|
|
||||||
}
|
|
||||||
let fcmmodel = {
|
|
||||||
"priority": "high",
|
|
||||||
"registration_ids": tokenarr,
|
|
||||||
"data": data2,
|
|
||||||
"notification": {
|
|
||||||
"body": `An order has been assigned ${orderid}`,
|
|
||||||
"title": "Legendary",
|
|
||||||
"sound": "ring",
|
|
||||||
"content_available": true,
|
|
||||||
"click_action": "FLUTTER_NOTIFICATION_CLICK"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let grpnotifyobj = {
|
|
||||||
"notifications": arr1,
|
|
||||||
"fcmmodel": fcmmodel
|
|
||||||
}
|
|
||||||
logger.info("grpnotifyobj")
|
|
||||||
logger.info(grpnotifyobj)
|
|
||||||
sendgroupnotification(grpnotifyobj)
|
|
||||||
// notificationpush(obj2, val.userfcmtoken);
|
|
||||||
// notificationpush(arr1,tokenarr);
|
|
||||||
// enqueueSnackbar('Notifications sent successfully', {
|
|
||||||
// variant: 'success', anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
|
||||||
// autoHideDuration: 2000
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
logger.error(err)
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const sendgroupnotification = async (obj1) => {
|
const sendgroupnotification = async (obj1) => {
|
||||||
|
|
||||||
logger.info(obj1)
|
logger.info(obj1)
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ const MultipleOrders = () => {
|
|||||||
const tenantid = localStorage.getItem('tenantid');
|
const tenantid = localStorage.getItem('tenantid');
|
||||||
|
|
||||||
// ============================== state ==============================
|
// ============================== state ==============================
|
||||||
const [locations, setLocations] = useState([]);
|
const [, setLocations] = useState([]);
|
||||||
const [tenantLocations, setTenantlocations] = useState([]);
|
const [tenantLocations, setTenantlocations] = useState([]);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [btnLoading, setBtnLoading] = useState(false);
|
const [btnLoading, setBtnLoading] = useState(false);
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import { useHotkeyFocus } from 'components/nearle_components/useHotkeyFocus';
|
|||||||
import DateFilterDialog from 'components/nearle_components/DateFilterDialog';
|
import DateFilterDialog from 'components/nearle_components/DateFilterDialog';
|
||||||
import CircularLoader from 'components/nearle_components/CircularLoader';
|
import CircularLoader from 'components/nearle_components/CircularLoader';
|
||||||
import { useQuery, useMutation, useInfiniteQuery } from '@tanstack/react-query';
|
import { useQuery, useMutation, useInfiniteQuery } from '@tanstack/react-query';
|
||||||
import { useNavigate, useLocation } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import logger from 'utils/logger';
|
import logger from 'utils/logger';
|
||||||
import {
|
import {
|
||||||
fetchPercentageData,
|
fetchPercentageData,
|
||||||
@@ -141,7 +141,6 @@ const scrollbarStyle = `
|
|||||||
|
|
||||||
const Orders = () => {
|
const Orders = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const location = useLocation();
|
|
||||||
const tid = localStorage.getItem('tenantid');
|
const tid = localStorage.getItem('tenantid');
|
||||||
const loadMoreRef = useRef();
|
const loadMoreRef = useRef();
|
||||||
const containerRef = useRef();
|
const containerRef = useRef();
|
||||||
@@ -162,7 +161,6 @@ const Orders = () => {
|
|||||||
const [debouncedSearch, setDebouncedSearch] = useState('');
|
const [debouncedSearch, setDebouncedSearch] = useState('');
|
||||||
|
|
||||||
// Floating button and Dialog states
|
// Floating button and Dialog states
|
||||||
const [speedDialOpen, setSpeedDialOpen] = useState(false);
|
|
||||||
const [multiDeleteDialog, setMultiDeleteDialog] = useState(false);
|
const [multiDeleteDialog, setMultiDeleteDialog] = useState(false);
|
||||||
const [createloader, setCreateloader] = useState(false);
|
const [createloader, setCreateloader] = useState(false);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
@@ -190,7 +188,6 @@ const Orders = () => {
|
|||||||
|
|
||||||
// React Queries
|
// React Queries
|
||||||
const {
|
const {
|
||||||
data: percentageData,
|
|
||||||
isLoading: fetchpercentageIsLoading,
|
isLoading: fetchpercentageIsLoading,
|
||||||
refetch: percentagedataRefetch
|
refetch: percentagedataRefetch
|
||||||
} = useQuery({
|
} = useQuery({
|
||||||
@@ -378,12 +375,6 @@ const Orders = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// KPI tile definitions.
|
|
||||||
const kpiCards = [
|
|
||||||
{ key: 'created', label: 'Created Orders', color: BRAND, icon: MdLocalShipping, value: percentageData?.created, percentage: percentageData?.percentage1 },
|
|
||||||
{ key: 'pending', label: 'Pending Orders', color: '#f59e0b', icon: MdHourglassEmpty, value: percentageData?.uncoveredOrders, percentage: percentageData?.percentage2 }
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<style>{scrollbarStyle}</style>
|
<style>{scrollbarStyle}</style>
|
||||||
@@ -648,17 +639,6 @@ const Orders = () => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{rows.map((row, index) => {
|
{rows.map((row, index) => {
|
||||||
const isItemSelected = !!deliverylist.find((res) => res.orderheaderid === row.orderheaderid);
|
|
||||||
const handleCheckbox = (e) => {
|
|
||||||
if (e.target.checked) {
|
|
||||||
setDeliverylist((prev) => [...prev, { ...row, sno: prev.length + 1 }]);
|
|
||||||
} else {
|
|
||||||
setDeliverylist((prev) =>
|
|
||||||
prev.filter((item) => item.orderheaderid !== row.orderheaderid).map((item, i) => ({ ...item, sno: i + 1 }))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tr key={`${row.orderheaderid}-${index}`} className="ordpg-row" style={{ cursor: 'pointer', transition: 'background-color 0.12s, box-shadow 0.12s' }}>
|
<tr key={`${row.orderheaderid}-${index}`} className="ordpg-row" style={{ cursor: 'pointer', transition: 'background-color 0.12s, box-shadow 0.12s' }}>
|
||||||
<td style={{ borderBottom: `1px solid ${DT.divider}`, padding: '5px 8px', verticalAlign: 'top' }}>
|
<td style={{ borderBottom: `1px solid ${DT.divider}`, padding: '5px 8px', verticalAlign: 'top' }}>
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ export default function OrdersReport() {
|
|||||||
const [enddate, setEnddate] = useState(dayjs().format('YYYY-MM-DD'));
|
const [enddate, setEnddate] = useState(dayjs().format('YYYY-MM-DD'));
|
||||||
const [openRow, setOpenRow] = useState(null);
|
const [openRow, setOpenRow] = useState(null);
|
||||||
const [datestatus, setDatestatus] = useState('Today');
|
const [datestatus, setDatestatus] = useState('Today');
|
||||||
const [total, settotal] = useState(0);
|
const [, settotal] = useState(0);
|
||||||
const [totalOrders, settotalOrders] = useState(0);
|
const [totalOrders, settotalOrders] = useState(0);
|
||||||
const [totalOrderPend, setTotalOrderPend] = useState(0);
|
const [totalOrderPend, setTotalOrderPend] = useState(0);
|
||||||
const [totalOrderComplete, setTotalOrderComplete] = useState(0);
|
const [totalOrderComplete, setTotalOrderComplete] = useState(0);
|
||||||
|
|||||||
@@ -256,8 +256,8 @@ export default function OrdersDetails() {
|
|||||||
const [startdate, setStartdate] = useState(dayjs().format('YYYY-MM-DD'));
|
const [startdate, setStartdate] = useState(dayjs().format('YYYY-MM-DD'));
|
||||||
const [enddate, setEnddate] = useState(dayjs().format('YYYY-MM-DD'));
|
const [enddate, setEnddate] = useState(dayjs().format('YYYY-MM-DD'));
|
||||||
const [datestatus, setDatestatus] = useState('Today');
|
const [datestatus, setDatestatus] = useState('Today');
|
||||||
const [totalCharge, settotalCharge] = useState(0);
|
const [, settotalCharge] = useState(0);
|
||||||
const [totalAmount, settotalAmount] = useState(0);
|
const [, settotalAmount] = useState(0);
|
||||||
const [searchword, setSearchword] = useState('');
|
const [searchword, setSearchword] = useState('');
|
||||||
|
|
||||||
// Density toggle — operators choose how many rows to surface per screen.
|
// Density toggle — operators choose how many rows to surface per screen.
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ import { lazy } from 'react';
|
|||||||
import MainLayout from 'layout/MainLayout';
|
import MainLayout from 'layout/MainLayout';
|
||||||
import CommonLayout from 'layout/CommonLayout';
|
import CommonLayout from 'layout/CommonLayout';
|
||||||
import Loadable from 'components/Loadable';
|
import Loadable from 'components/Loadable';
|
||||||
import AuthGuard from 'utils/route-guard/AuthGuard';
|
|
||||||
import { element } from 'prop-types';
|
|
||||||
|
|
||||||
// pages routing
|
// pages routing
|
||||||
const MaintenanceError = Loadable(lazy(() => import('pages/maintenance/404')));
|
const MaintenanceError = Loadable(lazy(() => import('pages/maintenance/404')));
|
||||||
@@ -13,8 +11,6 @@ const MaintenanceError500 = Loadable(lazy(() => import('pages/maintenance/500'))
|
|||||||
const MaintenanceUnderConstruction = Loadable(lazy(() => import('pages/maintenance/under-construction')));
|
const MaintenanceUnderConstruction = Loadable(lazy(() => import('pages/maintenance/under-construction')));
|
||||||
const MaintenanceComingSoon = Loadable(lazy(() => import('pages/maintenance/coming-soon')));
|
const MaintenanceComingSoon = Loadable(lazy(() => import('pages/maintenance/coming-soon')));
|
||||||
|
|
||||||
// render - sample page
|
|
||||||
const SamplePage = Loadable(lazy(() => import('pages/extra-pages/sample-page')));
|
|
||||||
const Login = Loadable(lazy(() => import('pages/nearle/login')));
|
const Login = Loadable(lazy(() => import('pages/nearle/login')));
|
||||||
|
|
||||||
const Customers = Loadable(lazy(() => import('pages/nearle/clients/customers')));
|
const Customers = Loadable(lazy(() => import('pages/nearle/clients/customers')));
|
||||||
|
|||||||
Reference in New Issue
Block a user