import * as React from 'react'; import { useEffect, useState, useRef, Fragment } from 'react'; import { FormControl, InputAdornment, Grid, Typography, Stack, Button, TextField, Autocomplete, Chip, Divider, DialogTitle, DialogContent, Checkbox, DialogActions, CircularProgress, IconButton, Switch, OutlinedInput, FormGroup, FormControlLabel, Avatar, Box } from '@mui/material'; import CloseIcon from '@mui/icons-material/Close'; import { Empty } from 'antd'; import { FaPhoneAlt } from 'react-icons/fa'; import { GiDoorHandle } from 'react-icons/gi'; import { FaLandmarkDome } from 'react-icons/fa6'; import ClearIcon from '@mui/icons-material/Clear'; import { useNavigate } from 'react-router'; import { TbMapPinCode } from 'react-icons/tb'; import { FaLocationDot } from 'react-icons/fa6'; import axios from 'axios'; import { useTheme } from '@mui/material/styles'; import Geocode from 'react-geocode'; import Loader from 'components/Loader'; import MainCard from 'components/MainCard'; import { FaUser } from 'react-icons/fa6'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import Dialog from '@mui/material/Dialog'; import dayjs from 'dayjs'; import { enqueueSnackbar } from 'notistack'; var utc = require('dayjs/plugin/utc'); dayjs.extend(utc); import { ArrowDownOutlined, ArrowUpOutlined, SearchOutlined } from '@ant-design/icons'; import MyLocationIcon from '@mui/icons-material/MyLocation'; import HighlightOffIcon from '@mui/icons-material/HighlightOff'; import { OpenToast } from 'components/third-party/OpenToast'; import TitleCard from 'components/nearle_components/TitleCard'; import AccessTimeIcon from '@mui/icons-material/AccessTime'; import { TimePicker } from '@mui/x-date-pickers'; import ArrowOutwardIcon from '@mui/icons-material/ArrowOutward'; import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward'; import LocationOnOutlinedIcon from '@mui/icons-material/LocationOnOutlined'; import { MapContainer, TileLayer, Marker, Polyline, useMap } from 'react-leaflet'; import L from 'leaflet'; import 'leaflet/dist/leaflet.css'; const pickupIcon = typeof window !== 'undefined' ? new L.Icon({ iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-blue.png', shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon.png', iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], shadowSize: [41, 41] }) : null; const dropoffIcon = typeof window !== 'undefined' ? new L.Icon({ iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png', shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon.png', iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], shadowSize: [41, 41] }) : null; const MapBoundsController = ({ startPoint, endPoint }) => { const map = useMap(); useEffect(() => { const points = []; const pLat = parseFloat(startPoint?.latitude); const pLng = parseFloat(startPoint?.longitude); const dLat = parseFloat(endPoint?.latitude); const dLng = parseFloat(endPoint?.longitude); if (!isNaN(pLat) && !isNaN(pLng) && pLat !== 0 && pLng !== 0) { points.push([pLat, pLng]); } if (!isNaN(dLat) && !isNaN(dLng) && dLat !== 0 && dLng !== 0) { points.push([dLat, dLng]); } if (points.length === 1) { map.setView(points[0], 14); } else if (points.length === 2) { map.fitBounds(points, { padding: [50, 50] }); } }, [startPoint?.latitude, startPoint?.longitude, endPoint?.latitude, endPoint?.longitude, map]); return null; }; const OrderMap = ({ startPoint, endPoint, appLocaLat, appLocaLng }) => { const defaultCenter = [ parseFloat(appLocaLat) || 11.0168, parseFloat(appLocaLng) || 76.9558 ]; const hasPick = startPoint?.latitude && startPoint?.longitude && parseFloat(startPoint.latitude) !== 0; const hasDrop = endPoint?.latitude && endPoint?.longitude && parseFloat(endPoint.latitude) !== 0; const pickCoords = hasPick ? [parseFloat(startPoint.latitude), parseFloat(startPoint.longitude)] : null; const dropCoords = hasDrop ? [parseFloat(endPoint.latitude), parseFloat(endPoint.longitude)] : null; // ---- Animation state (mirrors Dispatch.js pattern) ---- const [osrmRoute, setOsrmRoute] = useState(null); // full road path [[lat,lng],...] const [animatedSegments, setAnimatedSegments] = useState([]); // drawn pair-by-pair const [isAnimating, setIsAnimating] = useState(false); const isAnimatingRef = useRef(false); const timeoutsRef = useRef([]); // Fetch OSRM route whenever both points are available useEffect(() => { if (!hasPick || !hasDrop) { setOsrmRoute(null); setAnimatedSegments([]); setIsAnimating(false); return; } const url = `https://router.project-osrm.org/route/v1/driving/${pickCoords[1]},${pickCoords[0]};${dropCoords[1]},${dropCoords[0]}?overview=full&geometries=geojson`; fetch(url) .then((r) => r.json()) .then((data) => { const coords = data?.routes?.[0]?.geometry?.coordinates; if (coords && coords.length >= 2) { // OSRM returns [lng, lat], Leaflet needs [lat, lng] setOsrmRoute(coords.map(([lng, lat]) => [lat, lng])); } else { // Fallback to straight line setOsrmRoute([pickCoords, dropCoords]); } }) .catch(() => { setOsrmRoute([pickCoords, dropCoords]); }); // eslint-disable-next-line react-hooks/exhaustive-deps }, [startPoint?.latitude, startPoint?.longitude, endPoint?.latitude, endPoint?.longitude]); // Reset animation when route changes useEffect(() => { setAnimatedSegments([]); setIsAnimating(false); isAnimatingRef.current = false; timeoutsRef.current.forEach(clearTimeout); timeoutsRef.current = []; }, [osrmRoute]); const startAnimation = () => { // Stop if already animating if (isAnimating) { setIsAnimating(false); isAnimatingRef.current = false; setAnimatedSegments([]); timeoutsRef.current.forEach(clearTimeout); timeoutsRef.current = []; return; } const path = osrmRoute || (hasPick && hasDrop ? [pickCoords, dropCoords] : null); if (!path || path.length < 2) return; setIsAnimating(true); isAnimatingRef.current = true; setAnimatedSegments([]); timeoutsRef.current.forEach(clearTimeout); timeoutsRef.current = []; // Build segments same way as Dispatch.js: path[i] → path[i+1], each with a delay const allSegs = []; for (let i = 0; i < path.length - 1; i++) { allSegs.push({ from: path[i], to: path[i + 1], delay: i * 18 }); } allSegs.forEach((s, idx) => { const t = setTimeout(() => { if (!isAnimatingRef.current) return; setAnimatedSegments((prev) => [...prev, s]); if (idx === allSegs.length - 1) { const finalT = setTimeout(() => { setIsAnimating(false); isAnimatingRef.current = false; }, 800); timeoutsRef.current.push(finalT); } }, s.delay); timeoutsRef.current.push(t); }); }; // Cleanup on unmount useEffect(() => () => { timeoutsRef.current.forEach(clearTimeout); isAnimatingRef.current = false; }, []); const staticRoute = osrmRoute || (hasPick && hasDrop ? [pickCoords, dropCoords] : null); return (
{hasPick && } {hasDrop && } {/* Static solid polyline (shown when not animating) */} {!isAnimating && staticRoute && staticRoute.length >= 2 && ( )} {/* Animated segments — drawn pair-by-pair, matching Dispatch.js pattern */} {isAnimating && animatedSegments.map((s, i) => ( ))} {/* Floating Animate Routes button — same style as Dispatch's sbt button */} {hasPick && hasDrop && ( )}
); }; function loadScript(src, position, id) { if (!position) { return; } const script = document.createElement('script'); script.setAttribute('async', ''); script.setAttribute('id', id); script.src = src; position.appendChild(script); } const Createorder1 = () => { Geocode.setApiKey(process.env.REACT_APP_GOOGLE_MAPS_API_KEY); // ================================================= || GoogleMaps (Drawer) || ================================================= const loaded = React.useRef(false); const navigate = useNavigate(); const theme = useTheme(); const locationRef = useRef(null); const tenantRef = useRef(null); const [inputValue1, setInputValue1] = React.useState(''); const [inputValue2, setInputValue2] = React.useState(''); const textFieldRef1 = useRef(null); const textFieldRef1a = useRef(null); const textFieldRef2 = useRef(null); const [appId, setAppId] = useState(0); const [open, setOpen] = useState(false); const [startdate, setStartdate] = useState(dayjs().format('MM-DD-YYYY')); const [starttime, setStatrttime] = useState(); const [endtime, setEndtime] = useState(); const [timeslotarr, setTimeslotarr] = useState([]); const [otherinstructions, setOtherinstructions] = useState(''); const [loading2, setLoading2] = useState(false); const [loading, setLoading] = useState(false); const [btnLoading, setBtnLoading] = useState(false); const [alertmessage, setAlertmessage] = useState(''); const [admintoken, setAdmintoken] = useState(); const [tenant, setTenant] = useState({}); const [selectedtime, setSelectedtime] = useState(''); const [tenantlist, setTenantlist] = useState([]); const [startPoint, setStartPoint] = useState({ latitude: 0, longitude: 0 }); const [endPoint, setEndPoint] = useState({ latitude: 0, longitude: 0 }); const [showDistance, setShowDistance] = useState(false); const [distance, setDistance] = useState(0); const [basePrice, setBasePrice] = useState(0); const [pricePerKm, setPricePerKm] = useState(0); const [minKm, setMinKm] = useState(0); const [totalCharge, setTotalCharge] = useState(0); const [subCat, setSubCat] = useState([]); const [subCatName, setSubCatName] = useState('Select '); const [subCatId, setSubCatId] = useState(0); const [weight, setWeight] = useState(''); const [tenantid, setTenantid] = useState(0); const [locationid, setLocationid] = useState(0); const [selectedCatChip, setSelectedCatChip] = useState(null); const [isCustomerOpen, setIsCustomerOpen] = useState(false); const [searchCustList, setSearchCustList] = useState(''); const [customerlist, setCustomerlist] = useState([]); const [pickCust, setPickCust] = useState(null); const [dropCust, setDropCust] = useState(null); const [pickordrop, setpickordrop] = useState(0); // 1 ->pick 2 -> drop const [addId1, setAddId1] = useState(0); const [addId2, setAddId2] = useState(0); const [tenantLocations, setTenantlocations] = useState([]); const [appLocaLat, setAppLocaLat] = useState(); const [appLocaLng, setAppLocaLng] = useState(); const [appLocaRadius, setAppLocaRadius] = useState(); const [locations, setLocations] = useState('Select Location'); const userid = localStorage.getItem('userid'); const [isNumChange1, setIsNumChange1] = useState(0); const [isNumChange2, setIsNumChange2] = useState(0); const [showCheck1, setShowCheck1] = useState(0); const [showCheck2, setShowCheck2] = useState(0); const [pickNum, setPickNum] = useState(); const [dropNum, setdropNum] = useState(); const [numErr1, setNumErr1] = useState(false); const [numErr2, setNumErr2] = useState(false); const [isSms, setIsSms] = useState(0); const [collectionamt, setCollectionamt] = useState(0); const [quantity, setQuantity] = useState(1); const [tenantValue, setTenantValue] = useState(null); const [locationValue, setLocationValue] = useState(null); const [pickupdate, setPickupdate] = useState(dayjs().add(5, 'minute')); const [pickDialog, setPickDialog] = useState(false); const [deliverydate, setDeliverydate] = useState(dayjs().add(30, 'minute')); const [deliveryDialog, setDeliveryDialog] = useState(false); const [pickupSearchOpen, setPickupSearchOpen] = useState(false); const [dropSearchOpen, setDropSearchOpen] = useState(false); const pickerRef = useRef(null); const deliveryRef = useRef(null); const handlePickupChange = (newValue) => { if (!newValue) return; setPickupdate(newValue); if (deliverydate.isBefore(newValue)) { setDeliverydate(newValue.add(30, 'minute')); } }; if (typeof window !== 'undefined' && !loaded.current) { if (!document.querySelector('#google-maps')) { loadScript( `https://maps.googleapis.com/maps/api/js?key=${process.env.REACT_APP_GOOGLE_MAPS_API_KEY}&libraries=places&location=10.3656,77.9690&radius=50000&components=country:IN&strictbounds=true`, document.querySelector('head'), 'google-maps' ); } loaded.current = true; } // ==============================|| fetchAppLocations ||============================== // const fetchAppLocations = async () => { try { const locationRes = await axios.get(`${process.env.REACT_APP_URL}/partners/getlocations/?userid=${userid}`); console.log('fetchAppLocations', locationRes.data.details); setLocations(locationRes.data.details); } catch (err) { console.log('locationRes', err); } }; useEffect(() => { fetchAppLocations(); }, []); // ===================================================== || fetchtenantinfolist || ===================================================== const fetchtenantinfolist = async () => { setLoading(true); await axios .get(`${process.env.REACT_APP_URL}/tenants/gettenants/?applocationid=${appId}&status=active`) .then((res) => { console.log(res); if (res.data.status) { let arr = []; res.data.details.map((val) => { arr.push({ ...val, label: `${val.tenantname}` }); }); setTenantlist(arr); } setLoading(false); }) .catch((err) => { console.log(err); setLoading(false); }); }; useEffect(() => { appId && fetchtenantinfolist(); }, [appId]); const handleChipClick = (chipLabel) => { setSelectedCatChip(chipLabel); }; const chipStyle = (chipLabel) => ({ cursor: 'pointer', backgroundColor: selectedCatChip === chipLabel ? theme.palette.primary.main : 'default', color: selectedCatChip === chipLabel ? '#fff' : '', '&:hover': { backgroundColor: selectedCatChip === chipLabel ? theme.palette.primary.main : theme.palette.primary.light, color: '#fff' } }); const fetchTenantPricing = async (id) => { try { const pricingResponse = await axios.get(`${process.env.REACT_APP_URL}/tenants/gettenantpricing/?tenantid=${id}`); console.log('pricingResponse', pricingResponse.data.details); setBasePrice(pricingResponse.data.details.baseprice); setPricePerKm(pricingResponse.data.details.priceperkm); setMinKm(pricingResponse.data.details.minkm); } catch (error) { console.log('fetchTenantPricing error', error); } }; useEffect(() => { console.log('startPoint', startPoint); console.log('endPoint', endPoint); if (startPoint.latitude != 0 && startPoint.longitude != 0 && endPoint.latitude != 0 && endPoint.longitude != 0) { // getDistance(); calculateDistance(startPoint, endPoint); } }, [startPoint, endPoint]); const calculateDistance = async (pickup, drop) => { const service = new google.maps.DistanceMatrixService(); const getDistanceMatrix = (origins, destinations, travelMode, unitSystem) => { return new Promise((resolve, reject) => { service.getDistanceMatrix( { origins: [new google.maps.LatLng(origins.latitude, origins.longitude)], destinations: [new google.maps.LatLng(destinations.latitude, destinations.longitude)], travelMode: travelMode, unitSystem: unitSystem }, (response, status) => { if (status === 'OK') { resolve(response); } else { reject(new Error(`Error calculating distance: ${status}`)); } } ); }); }; try { // Use await to wait for the promise to resolve const response = await getDistanceMatrix(pickup, drop, 'DRIVING', google.maps.UnitSystem.METRIC); // Handle the response const results = response.rows[0].elements; for (let i = 0; i < results.length; i++) { const element = results[i]; // Extract the numerical value of the distance const distance = element.distance.value; console.log('distance in m ', distance); const distanceInKm = (distance / 1000).toFixed(2); console.log('distance in km ', distanceInKm); const roundedDistance = Math.round(distanceInKm); console.log('roundedDistance', roundedDistance); setDistance(roundedDistance); if (roundedDistance < minKm) { setTotalCharge(basePrice); } else { console.log('minKm', minKm); console.log('pricePerKm', pricePerKm); console.log('basePrice', basePrice); const total = (roundedDistance - minKm) * pricePerKm + basePrice; console.log('total', total); setTotalCharge(total); } setShowDistance(true); if (roundedDistance > appLocaRadius) { setShowDistance(true); setOpen(true); } // Extract the numerical value of the duration const durationMatch = element.duration.text.match(/([\d.]+)/); const duration = durationMatch ? parseInt(durationMatch[0]) : null; // Display only the numerical values console.log(`Distance: ${roundedDistance}, Duration: ${duration}`); } } catch (error) { console.error('Error calculating distance:', error); } }; useEffect(() => { if (tenantid) { clientdetails(); } }, [searchCustList?.length > 3, searchCustList == '', tenantid, pickupSearchOpen, dropSearchOpen]); useEffect(() => { if (timeslotarr[0]) { let arr = []; timeslotarr.map((val) => { if (dayjs().diff(dayjs(`${dayjs(startdate).format('MM-DD-YYYY')} ${dayjs(val).format('HH:mm:ss')}`), 'm') <= 0) { arr.push(val); } }); } }, [timeslotarr]); // ==================================================== || fetchtenantinfo || ==================================================== const fetchtenantinfo = async () => { setLoading(true); console.log('tenantid', tenantid); await axios .get(`${process.env.REACT_APP_URL}/tenants/gettenantinfo/?tenantid=${tenantid}`) .then((res) => { console.log('fetchtenantinfo', res); if (res.data.status) { setTenant(res.data.details); fetchAppAdminTokens(); setSubCatName(res.data.details.subcategoryname); setSubCatId(res.data.details.subcategoryid); } setLoading(false); }) .catch((err) => { console.log(err); setLoading(false); }); }; useEffect(() => { if (tenantid) { fetchtenantinfo(); } }, [tenantid]); // ==================================================== || getsubcategories || ==================================================== const getsubcategories = async () => { await axios .get(`${process.env.REACT_APP_URL}/utils/getsubcategories/?moduleid=6`) .then((res) => { console.log('subcateRes', res.data.details); if (res.data.status) { setSubCat(res.data.details); } }) .catch((err) => { console.log(err); }); }; useEffect(() => { getsubcategories(); }, []); // ==================================================== || fetchTiming || ==================================================== const fetchTiming = async () => { setLoading(true); await axios .get(`${process.env.REACT_APP_URL}/utils/getapplocations/?applocationid=${appId}`) .then((res) => { console.log('fetchTiming', res); const { opentime, closetime, latitude, longitude, radius } = res.data.details[0]; if (res.data.status) { setAppLocaLat(latitude); setAppLocaLng(longitude); setAppLocaRadius(radius); console.log('radius', radius); setStatrttime(`${dayjs().format('MM-DD-YYYY')} ${opentime}`); setEndtime(`${dayjs().format('MM-DD-YYYY')} ${closetime}`); console.log('starttime', `${dayjs().format('MM-DD-YYYY')} ${opentime}`); console.log('endtime', `${dayjs().format('MM-DD-YYYY')} ${closetime} `); let arr = []; for ( let i = `${dayjs().format('MM-DD-YYYY')} ${opentime}`, j = 0; dayjs(`${dayjs().format('MM-DD-YYYY')} ${closetime} `).diff(i, 'm') >= 0; j++, i = dayjs(i).add(30, 'm') ) { arr.push(i); } console.log('setTimeslotarr', arr); setTimeslotarr(arr); } setLoading(false); }) .catch((err) => { console.log(err); setLoading(false); }); }; useEffect(() => { if (appId) { fetchTiming(); } }, [appId]); // =============================================== || fetchAppAdminTokens (via appId) || =============================================== const fetchAppAdminTokens = async () => { setLoading(true); await axios .get(`${process.env.REACT_APP_URL}/utils/getapplocationconfig/?applocationid=${appId}`) .then((res) => { const userfcmtokemArray = res.data.details.applocationadmins.map((admin) => admin.userfcmtokem); // fcm => firebase cloud messaging console.log('fetchAppAdminTokens', res); console.log('userfcmtokemArray', userfcmtokemArray); if (res.data.status) { setAdmintoken(userfcmtokemArray); } setLoading(false); }) .catch((err) => { console.log(err); setLoading(false); }); }; useEffect(() => { if (starttime && endtime) { fetchAppAdminTokens(); } }, [starttime, endtime]); // =============================================== || opentoast || =============================================== const opentoast = (message, variant, time) => { enqueueSnackbar(message, { variant: variant, anchorOrigin: { vertical: 'top', horizontal: 'right' }, autoHideDuration: time ? time : 1500 }); console.log(alertmessage); }; const createsubmitobj2 = async () => { let arr = {}; arr = { orders: { applocationid: tenant.applolcationid, cancellled: '', categoryid: +tenant.categoryid, configid: 9, customerid: isNumChange1 == 0 ? +pickCust.customerid || 0 : 0, deliveryaddress: dropCust.address || '', deliverycharge: +totalCharge.toFixed(2) || 0, deliverycity: dropCust.city || '', deliverycontactno: dropCust.contactno || '', deliverycustomer: dropCust.firstname || '', deliveryid: isNumChange2 == 0 ? +dropCust.customerid || 0 : 0, deliverylandmark: dropCust.landmark || '', deliverylat: dropCust.latitude.toString(), deliverylocation: dropCust.suburb || '', deliverylocationid: dropCust.deliverylocationid || 0, deliverylong: dropCust.longitude.toString(), deliverytime: `${dayjs(startdate).format('YYYY-MM-DD')} ${dayjs(selectedtime.$d).format('HH:mm:ss')}`, deliverytype: 'B', delivered: '', itemcount: 1, kms: distance.toString() || 0, locationid: +locationid, moduleid: +tenant.moduleid, orderamount: +totalCharge.toFixed(2) || 0, ordercharges: 0.0, orderdate: dayjs().format('YYYY-MM-DD HH:mm:ss'), ordernotes: otherinstructions, orderstatus: 'created', ordervalue: +totalCharge.toFixed(2) || 0, partnerid: tenant.partnerid, partneruserid: +userid, paymentstatus: 1, paymenttype: 42, pickupaddress: pickCust.address || '', pickupcity: pickCust.city || '', pickupcontactno: pickCust.contactno || '', pickupcustomer: pickCust.firstname || '', pickuplandmark: pickCust.landmark || '', pickuplat: pickCust.latitude.toString() || '', pickuplocation: pickCust.suburb || '', pickuplocationid: pickCust.deliverylocationid || 0, pickuplong: pickCust.longitude.toString() || '', smsdelivery: isSms, subcategoryid: +subCatId, tenantid: tenant.tenantid, collectionamt: +collectionamt, quantity: +quantity, weight }, pickup: { address: pickCust.address || '', applocationid: tenant.applolcationid, city: pickCust.city || '', configid: 1, contactno: pickCust.contactno || '', customertoken: '', customerid: isNumChange1 == 0 ? pickCust.customerid || 0 : 0, devicetype: '', deviceid: '', dialcode: '+91', doorno: pickCust.doorno || '', email: pickCust.email || '', firstname: pickCust.firstname || '', landmark: pickCust.landmark || '', latitude: pickCust.latitude.toString() || '', longitude: pickCust.longitude.toString() || '', postcode: pickCust.postcode || '', primaryaddress: 1, locationid: pickCust.deliverylocationid || 0, profileimage: '', state: pickCust.state || '', suburb: pickCust.suburb || '', tenantid: tenant.tenantid }, drop: { address: dropCust.address || '', applocationid: tenant.applolcationid, city: dropCust.city || '', configid: 1, contactno: dropCust.contactno || '', customertoken: '', customerid: isNumChange2 == 0 ? dropCust.customerid || 0 : 0, devicetype: '', deviceid: '', locationid: dropCust.deliverylocationid || 0, dialcode: '+91', doorno: dropCust.doorno || '', email: dropCust.email || '', firstname: dropCust.firstname || '', landmark: dropCust.landmark || '', latitude: dropCust.latitude.toString(), longitude: dropCust.longitude.toString(), postcode: dropCust.postcode || '', primaryaddress: 1, profileimage: '', state: dropCust.state || '', suburb: dropCust.suburb || '', tenantid: tenant.tenantid } }; console.log('createsubmitobj2', arr); if (!pickCust.firstname) { opentoast('Enter Pickup Contact Name ', 'warning', 2000); } else if (!pickCust.contactno) { opentoast('Enter Pickup Contact Number ', 'warning', 2000); } else if (pickCust.contactno.length != 10) { opentoast('Check Pickup Contact Number ', 'error', 2000); } else if (!pickCust.suburb) { opentoast('Enter Pickup Location ', 'warning', 2000); } // else if (!pickCust.city) { // opentoast('Enter Pickup City ', 'warning', 2000); // } else if (!pickCust.postcode) { opentoast('Enter Pickup Postcode ', 'warning', 2000); } else if (!pickCust.landmark) { opentoast('Enter Pickup Landmark ', 'warning', 2000); } else if (!dropCust.firstname) { opentoast('Enter Drop Contact Name ', 'warning', 2000); } else if (!dropCust.contactno) { opentoast('Enter Drop Contact Number', 'warning', 2000); } else if (dropCust.contactno.length !== 10) { opentoast('Check Drop Contact Number ', 'error', 2000); } else if (!dropCust.suburb) { opentoast('Enter Drop Suburb ', 'warning', 2000); } // else if (!dropCust.city) { // opentoast('Enter Drop City ', 'warning', 2000); // } else if (!dropCust.postcode) { opentoast('Enter Drop postcode ', 'warning', 2000); } else if (!dropCust.landmark) { opentoast('Enter Drop Landmark ', 'warning', 2000); } else if (!selectedtime) { opentoast('Choose deliverytime ', 'warning', 2000); } else if (!setSubCatId) { opentoast('Choose SubCategory ', 'warning', 2000); } else { try { const createRes = await axios.post(`${process.env.REACT_APP_URL2}/orders/createorder`, arr); if (createRes.data.status) { console.log('createRes', createRes); enqueueSnackbar('Order Created Successfully', { variant: 'success', anchorOrigin: { vertical: 'top', horizontal: 'right' }, autoHideDuration: 1000 }); if (admintoken) { // notifyadmin(admintoken); sendnotifications(); } navigate('/nearle/orders'); } else { opentoast('Error in creating orders', 'warning'); } setLoading(false); } catch (error) { opentoast(error.message, 'warning'); console.log('createResErr', error); } } }; // ========================================================= || clientdetails || ========================================================= const clientdetails = async () => { setLoading2(true); try { let url = searchCustList == '' ? `${process.env.REACT_APP_URL}/customers/gettenantcustomers/?tenantid=${tenantid}&pageno=1&pagesize=30` : `${process.env.REACT_APP_URL}/customers/search/?tenantid=${tenantid}&keyword=${searchCustList}`; await axios .get(url) .then((res) => { if (res.data.status) { console.log('clientdetails', res.data.details); setCustomerlist(res.data.details); } setLoading2(false); }) .catch((err) => { console.log(err); setLoading2(false); opentoast('server error', 'warning'); }); } catch (err) { console.log(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) => { console.log(res); if (res.data.message == 'Success') { enqueueSnackbar('Notification sent Successfully', { variant: 'success', anchorOrigin: { vertical: 'top', horizontal: 'right' }, autoHideDuration: 1000 }); } setLoading(false); }) .catch((err) => { console.log(err); enqueueSnackbar(err.message, { variant: 'error', anchorOrigin: { vertical: 'top', horizontal: 'right' }, autoHideDuration: 1000 }); setLoading(false); }); }; // ============================================= || Google Maps Autocomplete(pick) || ============================================= useEffect(() => { // Initialize Google Maps Autocomplete if (inputValue1) { const autocompleteInput = document.getElementById('addressAuto1'); const autocomplete = new window.google.maps.places.Autocomplete(autocompleteInput, { // types: ['(cities)'], // You can adjust the types parameter based on your requirements strictBounds: true, bounds: new window.google.maps.Circle({ // center: new window.google.maps.LatLng(11.0050707, 76.9509083), // radius: 100000 center: new window.google.maps.LatLng(appLocaLat, appLocaLng), radius: appLocaRadius * 1000 }).getBounds() }); // Event listener for autocomplete place changed autocomplete.addListener('place_changed', () => { const place = autocomplete.getPlace(); setInputValue1(`${place.name}, ${place.formatted_address}`); console.log('new place', place); // Do something with the selected place console.log(' pick (new place) lat lng', { lat: place.geometry.location.lat(), lng: place.geometry.location.lng() }); // Do something with the selected place // to trigger getDistance setStartPoint({ latitude: place.geometry.location.lat(), longitude: place.geometry.location.lng() }); setPickCust({ ...pickCust, address: `${place.name} ${place.formatted_address}` }); const address = { address: `${place.name} ${place.formatted_address}`, street_number: '', route: '', locality: '', sublocality_level_1: '', administrative_area_level_3: '', administrative_area_level_1: '', country: '', postal_code: '' }; place.address_components.forEach((component) => { component.types.forEach((type) => { switch (type) { case 'street_number': address.street_number = component.long_name; break; case 'route': address.route = component.long_name; break; case 'locality': address.locality = component.long_name; break; case 'sublocality_level_1': address.sublocality_level_1 = component.long_name; break; case 'administrative_area_level_3': address.administrative_area_level_3 = component.long_name; break; case 'administrative_area_level_1': address.administrative_area_level_1 = component.long_name; break; case 'country': address.country = component.long_name; break; case 'postal_code': address.postal_code = component.long_name; break; // Add more cases as needed for other types } }); }); // Use address object as per your requirements setPickCust({ ...pickCust, address: address.address, doorno: `${address.street_number} ${address.route}`, suburb: address.sublocality_level_1, city: address.locality, postcode: address.postal_code, latitude: place.geometry.location.lat(), longitude: place.geometry.location.lng() }); console.log('Pick Address:', address); }); } }, [inputValue1]); // ============================================= || Google Maps Autocomplete(Drop) || ============================================= useEffect(() => { if (inputValue2) { // Initialize Google Maps Autocomplete const autocompleteInput = document.getElementById('addressAuto2'); const autocomplete = new window.google.maps.places.Autocomplete(autocompleteInput, { // types: ['(cities)'], // You can adjust the types parameter based on your requirements strictBounds: true, bounds: new window.google.maps.Circle({ // center: new window.google.maps.LatLng(11.0050707, 76.9509083), center: new window.google.maps.LatLng(appLocaLat, appLocaLng), radius: appLocaRadius * 1000 //km to m // radius: 100000 //km to m }).getBounds() }); let arr = []; // Event listener for autocomplete place changed autocomplete.addListener('place_changed', () => { const place = autocomplete.getPlace(); setInputValue2(`${place.name}, ${place.formatted_address}`); console.log('new place', place); // Do something with the selected place console.log('drop (new place) lat lng', { lat: place.geometry.location.lat(), lng: place.geometry.location.lng() }); // Do something with the selected place setEndPoint({ latitude: place.geometry.location.lat(), longitude: place.geometry.location.lng() }); setDropCust({ ...dropCust, address: `${place.name} ${place.formatted_address}` }); const address = { address: `${place.name} ${place.formatted_address}`, street_number: '', route: '', locality: '', sublocality_level_1: '', administrative_area_level_3: '', administrative_area_level_1: '', country: '', postal_code: '' }; place.address_components.forEach((component) => { component.types.forEach((type) => { switch (type) { case 'street_number': address.street_number = component.long_name; break; case 'route': address.route = component.long_name; break; case 'locality': address.locality = component.long_name; break; case 'sublocality_level_1': address.sublocality_level_1 = component.long_name; break; case 'administrative_area_level_3': address.administrative_area_level_3 = component.long_name; break; case 'administrative_area_level_1': address.administrative_area_level_1 = component.long_name; break; case 'country': address.country = component.long_name; break; case 'postal_code': address.postal_code = component.long_name; break; // Add more cases as needed for other types } }); }); // Use address object as per your requirements setDropCust({ ...dropCust, address: address.address, doorno: `${address.street_number} ${address.route}`, suburb: address.sublocality_level_1, city: address.locality, postcode: address.postal_code, latitude: place.geometry.location.lat(), longitude: place.geometry.location.lng() }); console.log('Drop Address:', address); }); } }, [inputValue2]); // ============================================= || gettenantlocations (branches) || ============================================= const gettenantlocations = async (id) => { try { const res = await axios.get(`${process.env.REACT_APP_URL}/tenants/gettenantlocations/?tenantid=${id}`); console.log('gettenantlocations', res.data.details); if (res.data.details.length == 1) { setTenantlocations(res.data.details); setLocationid(res.data.details[0].locationid); setLocationValue(res.data.details[0].locationid); } else { setTenantlocations(res.data.details); } } catch (err) { console.log('gettenantlocations', err); } }; return ( <> {loading && } {loading2 && } 1 Select Location and Client {/* ===================================================== || Choose App location || ===================================================== */} `${option.locationname}`} onChange={(event, value, reason) => { if (reason === 'clear') { setAppId(0); setTenantid(0); setTenantValue(null); setTenantlist([]); setLocationid(0); setLocationValue(null); setTenantlocations([]); setPickCust(null); setDropCust(null); } else { setAppId(value.applocationid); setPickCust(null); setDropCust(null); setTenantid(0); setTenantValue(null); setTenantlist([]); setLocationid(0); setLocationValue(null); setTenantlocations([]); } }} renderInput={(params) => } /> {/* ===================================================== || Choose client || ===================================================== */} { if (!appId) { event.preventDefault(); OpenToast('Please select a your location first!', 'warning', 3000); setTimeout(() => { locationRef.current?.focus(); }, 0); } }} onChange={(e, val, reason) => { if (reason == 'clear') { setTenantid(0); setTenantValue(null); setLocationid(0); setLocationValue(null); setTenantlocations([]); setPickCust(null); setDropCust(null); } else { setTenantid(val?.tenantid || 0); setTenantValue(val); setLocationid(0); setLocationValue(null); fetchTenantPricing(val.tenantid); gettenantlocations(val.tenantid); setDropCust(null); } }} renderInput={(params) => } /> {/* ===================================================== ||Business Location || ===================================================== */} {tenantLocations.length == 1 ? ( ) }} /> ) : ( `${option.locationname} (${option.suburb})` || ''} onOpen={(event) => { if (!appId && !tenantid) { event.preventDefault(); OpenToast('Please select Location and Tenant first!', 'warning', 3000); setTimeout(() => { locationRef.current?.focus(); }, 0); } else if (!tenantid) { event.preventDefault(); OpenToast('Please select a your Tenant first!', 'warning', 3000); setTimeout(() => { tenantRef.current?.focus(); }, 0); } }} onChange={(event, value, reason) => { if (reason === 'clear') { setLocationid(0); setLocationValue(null); setPickCust(null); } else { setLocationid(value.locationid || 0); setLocationValue(value); } }} renderInput={(params) => } /> )} {/* ================================================= || Pickup & Drop || ================================================= */} 2 Pickup & Drop Details {/* ================================================= || Pickup || ================================================= */} Pickup Details {pickCust?.firstname && ( ✓ Selected )} {/* ============ Inline Pickup Search Panel ============ */}
{/* Search Input */} setSearchCustList(e.target.value)} sx={{ bgcolor: 'white', borderRadius: '8px' }} startAdornment={ } endAdornment={ searchCustList ? ( setSearchCustList('')}> ) : null } /> {/* Customer List */}
{customerlist?.length === 0 ? ( ) : ( customerlist?.map((address, index) => ( )) )}
{/* ====================================== ||Contact Name (pick) || ====================================== */} ) }} variant="outlined" label="Contact Name" value={pickCust?.firstname || ''} onChange={(e) => { setPickCust({ ...pickCust, firstname: e.target.value }); }} /> {/* ====================================== ||Contact Number(pick) || ====================================== */} ) }} variant="outlined" label="Contact Number" value={pickCust?.contactno || ''} onChange={(e) => { if (e.target.value.length <= 10) { setPickCust({ ...pickCust, contactno: e.target.value }); } if (pickNum == e.target.value) { setShowCheck1(0); } else { setShowCheck1(1); } if (e.target.value.length < 10) { setNumErr1(true); } else { setNumErr1(false); } }} /> {/* ====================================== || Address(pick) || ====================================== */} {addId1 == 0 ? (
setInputValue1(e.target.value)} InputProps={{ endAdornment: ( { setInputValue1(''); setPickCust({ ...pickCust, doorno: '', suburb: '', city: '', postcode: '', landmark: '' }); setShowDistance(false); setStartPoint({ latitude: 0, longitude: 0 }); }} size="small" > ) }} />
) : ( { setAddId1(0); setPickCust({ ...pickCust, doorno: '', suburb: '', city: '', postcode: '', landmark: '' }); setShowDistance(false); setStartPoint({ latitude: 0, longitude: 0 }); }} > ) }} value={pickCust?.address || ''} onChange={(e) => { setPickCust({ ...pickCust, address: e.target.value }); if (e.target.value == '') { setAddId1(0); setShowDistance(false); setStartPoint({ latitude: 0, longitude: 0 }); } }} /> )}
{/* ====================================== ||Door No (pick) || ====================================== */} ) }} variant="outlined" label="Door No / Street" value={pickCust?.doorno || ''} onChange={(e) => { setPickCust({ ...pickCust, doorno: e.target.value }); }} /> {/* ====================================== || Suburb (pick) || ====================================== */} ) }} variant="outlined" label="Location" value={pickCust?.suburb || ''} onChange={(e) => { setPickCust({ ...pickCust, suburb: e.target.value }); }} /> {/* ====================================== || postcode (pick) || ====================================== */} ) }} variant="outlined" label="Postcode" value={pickCust?.postcode || ''} onChange={(e) => { setPickCust({ ...pickCust, postcode: e.target.value }); }} /> {/* ====================================== || Landmark (pick) || ====================================== */} ) }} variant="outlined" label="Landmark" value={pickCust?.landmark || ''} onChange={(e) => { setPickCust({ ...pickCust, landmark: e.target.value }); }} /> {/* ====================================== ||Checkbox save for later (pick) || ====================================== */} {showCheck1 == 1 && ( { setIsNumChange1(e.target.checked ? 1 : 0); }} /> } label="Save For Later" /> )}
{/* ================================================= || Drop || ================================================= */} Drop Details {dropCust?.firstname && ( ✓ Selected )} {/* ============ Inline Drop Search Panel ============ */}
{/* Search Input */} setSearchCustList(e.target.value)} sx={{ bgcolor: 'white', borderRadius: '8px' }} startAdornment={ } endAdornment={ searchCustList ? ( setSearchCustList('')}> ) : null } /> {/* Customer List */}
{customerlist?.length === 0 ? ( ) : ( customerlist?.map((address, index) => ( )) )}
{/* ====================================== ||Contact Name (drop) || ====================================== */} ) }} value={dropCust?.firstname || ''} onChange={(e) => { setDropCust({ ...dropCust, firstname: e.target.value }); }} /> {/* ====================================== ||Contact Number (drop) || ====================================== */} ) }} value={dropCust?.contactno || ''} onChange={(e) => { if (e.target.value.length <= 10) { setDropCust({ ...dropCust, contactno: e.target.value }); } if (dropNum == e.target.value) { setShowCheck2(0); } else { setShowCheck2(1); } if (e.target.value.length < 10) { setNumErr2(true); } else { setNumErr2(false); } }} sx={{ color: numErr2 ? 'red' : 'inherit' }} /> {/* ====================================== || Address (drop) || ====================================== */} {addId2 == 0 ? (
setInputValue2(e.target.value)} InputProps={{ endAdornment: ( { setInputValue2(''); setDropCust({ ...dropCust, doorno: '', suburb: '', city: '', postcode: '', landmark: '' }); setShowDistance(false); setEndPoint({ latitude: 0, longitude: 0 }); }} size="small" > ) }} />
) : ( { setAddId2(0); setDropCust({ ...dropCust, // firstname: '', // contactno: '', doorno: '', suburb: '', city: '', postcode: '', landmark: '' }); setShowDistance(false); setEndPoint({ latitude: 0, longitude: 0 }); }} > ) }} value={dropCust?.address || ''} onChange={(e) => { setPickCust({ ...dropCust, address: e.target.value }); if (e.target.value == '') { setAddId2(0); setShowDistance(false); setEndPoint({ latitude: 0, longitude: 0 }); } }} /> )}
{/* ====================================== ||Door No (drop) || ====================================== */} ) }} value={dropCust?.doorno || ''} onChange={(e) => { setDropCust({ ...dropCust, doorno: e.target.value }); }} /> {/* ====================================== ||Suburb (drop) || ====================================== */} ) }} value={dropCust?.suburb || ''} onChange={(e) => { setDropCust({ ...dropCust, suburb: e.target.value }); }} /> {/* ====================================== ||Postcode (drop) || ====================================== */} ) }} value={dropCust?.postcode || ''} onChange={(e) => { setDropCust({ ...dropCust, postcode: e.target.value }); }} /> {/* ====================================== ||Landmark (drop) || ====================================== */} ) }} value={dropCust?.landmark || ''} onChange={(e) => { setDropCust({ ...dropCust, landmark: e.target.value }); }} /> {/* ====================================== ||Checkbox save for later (drop) || ====================================== */} {showCheck2 == 1 && ( { setIsNumChange2(e.target.checked ? 1 : 0); }} /> } label="Save For Later" /> )}
{/* ================================================= || Live Map Preview || ================================================= */} Live Route Preview
{/* ================================================= || Category || ================================================= */} 3 Package Details `${option.subcategoryname}` || ''} fullWidth renderInput={(params) => } onChange={(event, value, reason) => { if (value) { console.log(value); setSubCatName(value.subcategoryname || ''); setSubCatId(value.subcategoryid || 0); } else if (reason) { setSubCatName(null); setSubCatId(null); } }} /> { setCollectionamt(e.target.value); }} inputProps={{ min: 0 }} /> { setQuantity(e.target.value); }} inputProps={{ min: 1 }} /> 4 Schedule & Delivery Options {/* ================================================= || Time || ================================================= */} {/* Schedule */} Pickup Slots Date { let dateres11 = dayjs().diff(dayjs(`${dayjs(e).format('YYYY-MM-DD')}`), 'd'); console.log('dateres11'); console.log(dateres11); setSelectedtime(''); if (dateres11 <= 0) { console.log('startdate', e); setStartdate(e); let arr = []; timeslotarr.map((val) => { if ( dayjs().diff(dayjs(`${dayjs(e).format('MM-DD-YYYY')} ${dayjs(val).format('HH:mm:ss')}`), 'm') <= 0 ) { arr.push(val); } }); } else { setAlertmessage('choose Upcoming Date'); opentoast('choose Upcoming Date', 'warning'); setStartdate(NaN); } }} value={dayjs(startdate)} sx={{ width: '100%', mt: 2 }} disablePast /> Time {/* ================= PICKUP ================= */} setPickDialog(true)} > setPickDialog(false)} onAccept={() => setPickDialog(false)} // ✅ CLOSE HERE value={pickupdate} onChange={handlePickupChange} disablePast minutesStep={5} slotProps={{ textField: { sx: { position: 'absolute', inset: 0, opacity: 0 } } }} /> Pickup Time {pickupdate.format('hh:mm A')} {/* ================= DELIVERY ================= */} setDeliveryDialog(true)} > setDeliveryDialog(false)} onAccept={() => setDeliveryDialog(false)} // ✅ CLOSE HERE value={deliverydate} onChange={(newValue) => { if (!newValue) return; // Prevent delivery before pickup if (newValue.isBefore(pickupdate)) { setDeliverydate(pickupdate.add(30, 'minute')); } else { setDeliverydate(newValue); } setDeliveryDialog(false); }} minTime={pickupdate} disablePast minutesStep={5} slotProps={{ textField: { sx: { position: 'absolute', inset: 0, opacity: 0 } } }} /> Delivery Time {deliverydate.format('hh:mm A')} {/* {timeslotarr.map((val, index) => { if ( dayjs().diff(dayjs(`${dayjs(startdate).format('MM-DD-YYYY')} ${dayjs(val).format('HH:mm:ss')}`), 'm') <= 0 ) { return ( { if (distance > appLocaRadius) { setOpen(true); } else if (showDistance) { console.log('selectedtime', val); setSelectedtime(val); } else { opentoast('Out of city limit', 'error'); } }} /> ); } })} */} {showDistance && ( )} Weight { handleChipClick('1-10kgs'); setWeight('1-10kgs'); }} /> { handleChipClick('11-20kgs'); setWeight('11-20kgs'); }} /> { handleChipClick('21-30kgs'); setWeight('21-30kgs'); }} /> SMS Delivery { setIsSms(e.target.checked ? 1 : 0); }} /> Notes setOtherinstructions(e.target.value)} />
{/* ================================================= || Notes || ================================================= */} {/* */}
{/* */}
{/* Customer Dialog removed — replaced with inline search panels above */} {/* ============================================= || location error Dialog || ============================================= */} { setOpen(false); }} > Error Service not available at this location { setOpen(false); }} > Close ); }; export default Createorder1;