new chnages in ui

This commit is contained in:
2026-05-27 15:22:45 +05:30
parent 8c2248974e
commit 15f15958e6
4 changed files with 1206 additions and 456 deletions

View File

@@ -26,7 +26,7 @@ import {
} from '@mui/material';
import CloseIcon from '@mui/icons-material/Close';
import { Empty } from 'antd';
import { FaPhoneAlt, FaBox, FaBoxes, FaTruck } from 'react-icons/fa';
import { FaPhoneAlt, FaBox, FaBoxes, FaTruck, FaArrowRight, FaArrowLeft, FaCheck, FaRoute, FaMoneyBillWave, FaChartLine, FaReceipt, FaPaperPlane } from 'react-icons/fa';
import { GiDoorHandle } from 'react-icons/gi';
import { FaLandmarkDome } from 'react-icons/fa6';
import ClearIcon from '@mui/icons-material/Clear';
@@ -143,11 +143,11 @@ const OrderMap = ({ startPoint, endPoint, appLocaLat, appLocaLng }) => {
}, [startPoint.latitude, startPoint.longitude, endPoint.latitude, endPoint.longitude, hasPick, hasDrop]);
return (
<div style={{ position: 'relative', width: '100%', height: '100%', minHeight: '350px' }}>
<div style={{ position: 'relative', width: '100%', height: '100%' }}>
<MapContainer
center={defaultCenter}
zoom={12}
style={{ width: '100%', height: '100%', minHeight: '350px' }}
style={{ width: '100%', height: '100%' }}
zoomControl={true}
>
<TileLayer
@@ -257,6 +257,15 @@ const Createorder1 = () => {
const [locationValue, setLocationValue] = useState(null);
const [pickupSlotsList, setPickupSlotsList] = useState(null);
const [pickupSlot, setPickupSlot] = useState(null);
const [routeStep, setRouteStep] = useState(1); // 1 = Pickup, 2 = Drop
const pickupStepComplete = !!(
pickCust?.firstname &&
pickCust?.contactno &&
String(pickCust.contactno).length === 10 &&
pickCust?.doorno &&
pickCust?.suburb &&
pickCust?.postcode
);
useEffect(() => {
console.log('pickupSlotsList', pickupSlotsList);
@@ -1060,14 +1069,14 @@ const Createorder1 = () => {
<Card
className="orders-card page-header-row"
sx={{
mb: { xs: 2, sm: 2.5 },
mb: { xs: 1.5, sm: 2 },
display: 'flex',
flexDirection: { xs: 'column', lg: 'row' },
alignItems: { xs: 'stretch', lg: 'center' },
justifyContent: 'space-between',
gap: { xs: 2, lg: 3 },
px: { xs: 2, sm: 2.5 },
py: { xs: 1.25, sm: 1.5 },
gap: { xs: 1.25, lg: 2 },
px: { xs: 1.75, sm: 2 },
py: { xs: 0.75, sm: 0.9 },
flexShrink: 0
}}
>
@@ -1076,19 +1085,16 @@ const Createorder1 = () => {
sx={{
display: 'flex',
flexDirection: 'column',
gap: 0.5,
gap: 0,
minWidth: 0,
flex: { lg: '1 1 auto' }
}}
>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5 }}>
<Typography variant="h3" sx={{ fontWeight: 700, color: '#1e293b', lineHeight: 1.15 }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<Typography sx={{ fontWeight: 700, color: '#1e293b', lineHeight: 1.15, fontSize: { xs: '17px', sm: '19px' } }}>
Create New Order
</Typography>
</Box>
<Typography variant="body1" sx={{ color: '#64748b', fontWeight: 500 }}>
Configure client coordinates, delivery payloads, and dispatch schedules in real-time.
</Typography>
</Box>
<Box
@@ -1098,14 +1104,14 @@ const Createorder1 = () => {
flexDirection: { xs: 'column', sm: 'row' },
alignItems: { xs: 'stretch', sm: 'center' },
justifyContent: { xs: 'stretch', lg: 'flex-end' },
gap: 1.5,
p: { xs: 0.5, sm: 1, lg: 1.5 },
gap: 1,
p: 0,
width: { xs: '100%', lg: 'auto' },
flexShrink: 0
}}
>
{/* Choose App location */}
<Box sx={{ width: { xs: '100%', sm: 190, md: 210, xl: 230 } }}>
<Box sx={{ width: { xs: '100%', sm: 180, md: 200, xl: 220 } }}>
<Autocomplete
fullWidth
autoFocus
@@ -1113,6 +1119,7 @@ const Createorder1 = () => {
ref={locationRef}
options={locations || []}
getOptionLabel={(option) => `${option.locationname}`}
className="header-compact-input"
onChange={(event, value, reason) => {
if (reason === 'clear') {
setAppId(0);
@@ -1142,12 +1149,12 @@ const Createorder1 = () => {
placeholder="Choose Location"
label="Location"
InputLabelProps={{ shrink: true }}
sx={{ '& .MuiOutlinedInput-root': { borderRadius: '12px', paddingLeft: '12px' } }}
className="header-compact-tf"
InputProps={{
...params.InputProps,
startAdornment: (
<>
<FaLocationDot style={{ color: '#94a3b8', fontSize: 14, marginRight: 8, flexShrink: 0 }} />
<FaLocationDot style={{ color: '#94a3b8', fontSize: 12, marginRight: 6, flexShrink: 0 }} />
{params.InputProps.startAdornment}
</>
)
@@ -1158,10 +1165,11 @@ const Createorder1 = () => {
</Box>
{/* Choose Client */}
<Box sx={{ width: { xs: '100%', sm: 190, md: 210, xl: 230 } }}>
<Box sx={{ width: { xs: '100%', sm: 180, md: 200, xl: 220 } }}>
<Autocomplete
fullWidth
size="small"
className="header-compact-input"
options={tenantlist || []}
value={tenantValue}
onOpen={(event) => {
@@ -1200,12 +1208,12 @@ const Createorder1 = () => {
label="Client"
inputRef={tenantRef}
InputLabelProps={{ shrink: true }}
sx={{ '& .MuiOutlinedInput-root': { borderRadius: '12px', paddingLeft: '12px' } }}
className="header-compact-tf"
InputProps={{
...params.InputProps,
startAdornment: (
<>
<FaUser style={{ color: '#94a3b8', fontSize: 13, marginRight: 8, flexShrink: 0 }} />
<FaUser style={{ color: '#94a3b8', fontSize: 11, marginRight: 6, flexShrink: 0 }} />
{params.InputProps.startAdornment}
</>
)
@@ -1216,7 +1224,7 @@ const Createorder1 = () => {
</Box>
{/* Business Location */}
<Box sx={{ width: { xs: '100%', sm: 210, md: 230, xl: 250 } }}>
<Box sx={{ width: { xs: '100%', sm: 200, md: 220, xl: 240 } }}>
{tenantLocations.length == 1 ? (
<TextField
variant="outlined"
@@ -1225,11 +1233,11 @@ const Createorder1 = () => {
label="Business Location"
value={tenantLocations[0].locationname}
InputLabelProps={{ shrink: true }}
sx={{ '& .MuiOutlinedInput-root': { borderRadius: '12px', paddingLeft: '12px' } }}
className="header-compact-tf"
InputProps={{
style: { color: theme.palette.primary.main },
startAdornment: (
<MyLocationIcon style={{ color: '#94a3b8', fontSize: 16, marginRight: 8, flexShrink: 0 }} />
<MyLocationIcon style={{ color: '#94a3b8', fontSize: 14, marginRight: 6, flexShrink: 0 }} />
)
}}
/>
@@ -1237,6 +1245,7 @@ const Createorder1 = () => {
<Autocomplete
fullWidth
size="small"
className="header-compact-input"
value={locationValue}
options={tenantLocations || []}
getOptionLabel={(option) => `${option.locationname} (${option.suburb})` || ''}
@@ -1275,12 +1284,12 @@ const Createorder1 = () => {
label="Business Location"
color="primary"
InputLabelProps={{ shrink: true }}
sx={{ '& .MuiOutlinedInput-root': { borderRadius: '12px', paddingLeft: '12px' } }}
className="header-compact-tf"
InputProps={{
...params.InputProps,
startAdornment: (
<>
<MyLocationIcon style={{ color: '#94a3b8', fontSize: 16, marginRight: 8, flexShrink: 0 }} />
<MyLocationIcon style={{ color: '#94a3b8', fontSize: 14, marginRight: 6, flexShrink: 0 }} />
{params.InputProps.startAdornment}
</>
)
@@ -1304,17 +1313,64 @@ const Createorder1 = () => {
sx={{
display: 'flex',
flexDirection: 'column',
gap: { xs: 2.5, sm: 3, lg: 4 }
gap: { xs: 1.5, sm: 1.75, lg: 2 }
}}
>
{/* Card 2: Route Planner (Pickup & Drop) — tighter padding on md+ since
the two panels now sit side-by-side and need the horizontal room. */}
<Card className="orders-card" sx={{ p: { xs: 2, sm: 2.5, lg: 2 } }}>
<Card className="orders-card" sx={{ p: { xs: 1.25, sm: 1.5, lg: 1.5 } }}>
{/* Two-step stepper: Pickup → Drop */}
<Box className="route-stepper">
<Box
className={`route-step ${routeStep === 1 ? 'is-active' : ''} ${pickupStepComplete ? 'is-done' : ''} step-pickup`}
onClick={() => setRouteStep(1)}
role="button"
tabIndex={0}
>
<Box className="route-step-index">
{pickupStepComplete && routeStep !== 1 ? <FaCheck /> : '1'}
</Box>
<Box className="route-step-text">
<Typography className="route-step-title">Pickup</Typography>
<Typography className="route-step-sub">Where to collect</Typography>
</Box>
</Box>
<Box className={`route-step-connector ${pickupStepComplete ? 'is-done' : ''}`}>
<Box className="route-step-line" />
<Box className="route-step-line-arrow">
<FaArrowRight />
</Box>
</Box>
<Box
className={`route-step ${routeStep === 2 ? 'is-active' : ''} step-drop ${!pickupStepComplete ? 'is-locked' : ''}`}
onClick={() => {
if (pickupStepComplete) {
setRouteStep(2);
} else {
opentoast('Please complete Pickup details first', 'warning', 2000);
}
}}
role="button"
tabIndex={0}
>
<Box className="route-step-index">2</Box>
<Box className="route-step-text">
<Typography className="route-step-title">Drop</Typography>
<Typography className="route-step-sub">Where to deliver</Typography>
</Box>
</Box>
</Box>
<Box className="route-flow">
{/* Pickup Details Block */}
<Box className="location-panel pickup-panel">
<Box
className="location-panel pickup-panel"
sx={{ display: routeStep === 1 ? 'block' : 'none' }}
>
<Box className="lp-header">
<Box className="lp-header-title">
<Box className="lp-badge">
@@ -1356,7 +1412,7 @@ const Createorder1 = () => {
<Typography className="field-group-caption">
Contact
</Typography>
<Grid container spacing={2.5}>
<Grid container spacing={1.5} sx={{ mt: 0.5 }}>
<Grid item xs={12} sm={6}>
<TextField
inputRef={textFieldRef1}
@@ -1417,7 +1473,7 @@ const Createorder1 = () => {
</Grid>
{/* Address Autocomplete */}
<Typography className="field-group-caption" sx={{ mt: 3 }}>
<Typography className="field-group-caption" sx={{ mt: 2 }}>
Address Lookup
</Typography>
{addId1 == 0 ? (
@@ -1508,10 +1564,10 @@ const Createorder1 = () => {
)}
{/* Address details */}
<Typography className="field-group-caption" sx={{ mt: 3 }}>
<Typography className="field-group-caption" sx={{ mt: 2 }}>
Address Details
</Typography>
<Grid container spacing={2.5}>
<Grid container spacing={1.5} sx={{ mt: 0.5 }}>
<Grid item xs={12} sm={6}>
<TextField
fullWidth
@@ -1596,7 +1652,7 @@ const Createorder1 = () => {
{/* Save for later */}
{showCheck1 == 1 && (
<Box sx={{ display: 'flex', justifyContent: 'flex-end', mt: 2 }}>
<Box sx={{ display: 'flex', justifyContent: 'flex-end', mt: 1 }}>
<Box className="save-later-pill">
<FormControlLabel
control={
@@ -1613,10 +1669,30 @@ const Createorder1 = () => {
</Box>
</Box>
)}
{/* Step navigation */}
<Box className="step-nav">
<Typography className="step-nav-hint">
{pickupStepComplete
? 'Pickup looks good. Proceed to Drop details.'
: 'Fill the required Pickup fields to continue.'}
</Typography>
<Button
className="step-nav-btn step-nav-next"
disabled={!pickupStepComplete}
endIcon={<FaArrowRight style={{ fontSize: 12 }} />}
onClick={() => setRouteStep(2)}
>
Continue to Drop
</Button>
</Box>
</Box>
{/* Drop Details Block */}
<Box className="location-panel drop-panel">
<Box
className="location-panel drop-panel"
sx={{ display: routeStep === 2 ? 'block' : 'none' }}
>
<Box className="lp-header">
<Box className="lp-header-title">
<Box className="lp-badge">
@@ -1656,7 +1732,7 @@ const Createorder1 = () => {
<Typography className="field-group-caption">
Contact
</Typography>
<Grid container spacing={2.5}>
<Grid container spacing={1.5} sx={{ mt: 0.5 }}>
<Grid item xs={12} sm={6}>
<TextField
inputRef={textFieldRef2}
@@ -1715,7 +1791,7 @@ const Createorder1 = () => {
</Grid>
{/* Address Autocomplete */}
<Typography className="field-group-caption" sx={{ mt: 3 }}>
<Typography className="field-group-caption" sx={{ mt: 2 }}>
Address Lookup
</Typography>
{addId2 == 0 ? (
@@ -1806,10 +1882,10 @@ const Createorder1 = () => {
)}
{/* Address details */}
<Typography className="field-group-caption" sx={{ mt: 3 }}>
<Typography className="field-group-caption" sx={{ mt: 2 }}>
Address Details
</Typography>
<Grid container spacing={2.5}>
<Grid container spacing={1.5} sx={{ mt: 0.5 }}>
<Grid item xs={12} sm={6}>
<TextField
fullWidth
@@ -1894,7 +1970,7 @@ const Createorder1 = () => {
{/* Save for later */}
{showCheck2 == 1 && (
<Box sx={{ display: 'flex', justifyContent: 'flex-end', mt: 2 }}>
<Box sx={{ display: 'flex', justifyContent: 'flex-end', mt: 1 }}>
<Box className="save-later-pill">
<FormControlLabel
control={
@@ -1911,23 +1987,37 @@ const Createorder1 = () => {
</Box>
</Box>
)}
{/* Step navigation */}
<Box className="step-nav">
<Button
className="step-nav-btn step-nav-back"
startIcon={<FaArrowLeft style={{ fontSize: 12 }} />}
onClick={() => setRouteStep(1)}
>
Back to Pickup
</Button>
<Typography className="step-nav-hint">
Review the route below once Drop is filled.
</Typography>
</Box>
</Box>
</Box>
</Card>
{/* Card 3: Cargo & Dispatch Logistics */}
<Card className="orders-card" sx={{ p: { xs: 2, sm: 2.5, lg: 3 } }}>
<Box className="section-title-bar" sx={{ mb: 2.5 }}>
<Typography variant="h5" sx={{ fontWeight: 600, color: '#1e293b' }}>
Cargo & Dispatch Logistics
<Card className="orders-card" sx={{ p: { xs: 1.5, sm: 1.75, lg: 2 } }}>
<Box className="section-title-bar" sx={{ mb: 1.25 }}>
<Typography sx={{ fontWeight: 700, color: '#1e293b', fontSize: '15px', letterSpacing: '-0.01em' }}>
Cargo &amp; Dispatch Logistics
</Typography>
</Box>
<Grid container spacing={3} alignItems="stretch">
<Grid container spacing={1.5} alignItems="stretch">
{/* Section Header: Cargo Details */}
<Grid item xs={12}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5, mb: 0.5 }}>
<Typography sx={{ fontWeight: 700, fontSize: '11px', color: '#64748b', letterSpacing: '0.8px', textTransform: 'uppercase' }}>
<Grid item xs={12} sx={{ pt: '0 !important' }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 0.25 }}>
<Typography sx={{ fontWeight: 700, fontSize: '10.5px', color: '#64748b', letterSpacing: '0.7px', textTransform: 'uppercase' }}>
Cargo Details
</Typography>
<Box sx={{ flex: 1, height: '1px', background: 'linear-gradient(90deg, #eef2f6 0%, transparent 100%)' }} />
@@ -1946,7 +2036,7 @@ const Createorder1 = () => {
sx={{
'& .MuiOutlinedInput-root': {
borderRadius: '12px',
height: '42px',
height: '38px',
paddingTop: '0px !important',
paddingBottom: '0px !important'
}
@@ -1957,7 +2047,7 @@ const Createorder1 = () => {
label="Category"
size="small"
InputLabelProps={{ shrink: true }}
sx={{ '& .MuiOutlinedInput-root': { borderRadius: '12px', height: '42px' } }}
sx={{ '& .MuiOutlinedInput-root': { borderRadius: '12px', height: '38px' } }}
InputProps={{
...params.InputProps,
startAdornment: (
@@ -1996,7 +2086,7 @@ const Createorder1 = () => {
setCollectionamt(e.target.value);
}}
inputProps={{ min: 0 }}
sx={{ '& .MuiOutlinedInput-root': { borderRadius: '12px', height: '42px' } }}
sx={{ '& .MuiOutlinedInput-root': { borderRadius: '12px', height: '38px' } }}
InputProps={{
startAdornment: (
<InputAdornment position="start">
@@ -2021,7 +2111,7 @@ const Createorder1 = () => {
setQuantity(e.target.value);
}}
inputProps={{ min: 1 }}
sx={{ '& .MuiOutlinedInput-root': { borderRadius: '12px', height: '42px' } }}
sx={{ '& .MuiOutlinedInput-root': { borderRadius: '12px', height: '38px' } }}
InputProps={{
startAdornment: (
<InputAdornment position="start">
@@ -2033,73 +2123,20 @@ const Createorder1 = () => {
</Stack>
</Grid>
{/* Row 2: Weight Range Selector */}
<Grid item xs={12}>
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ mb: 1 }}>
<Typography variant="h6" sx={{ fontWeight: 600, color: '#475569', fontSize: 13.5 }}>
Select Cargo Weight Range <span style={{ color: '#ef4444' }}>*</span>
</Typography>
{weight && (
<Typography variant="body2" sx={{
fontWeight: 600,
color: weight === '1-10kgs' ? '#0ea5e9' : weight === '11-20kgs' ? '#a855f7' : '#6366f1',
fontSize: 12.5,
textTransform: 'capitalize'
}}>
{weight === '1-10kgs' ? 'Light' : weight === '11-20kgs' ? 'Medium' : 'Heavy'} selected
</Typography>
)}
</Stack>
<div className="weight-selector-grid">
<div
className={`weight-card-btn weight-light ${weight === '1-10kgs' ? 'active' : ''}`}
onClick={() => {
handleChipClick('1-10kgs');
setWeight('1-10kgs');
}}
>
<FaBox className="weight-card-icon" />
<div className="weight-card-label">Light Cargo (1-10 kgs)</div>
<div className="weight-card-desc">Parcels, retail envelopes</div>
</div>
<div
className={`weight-card-btn weight-medium ${weight === '11-20kgs' ? 'active' : ''}`}
onClick={() => {
handleChipClick('11-20kgs');
setWeight('11-20kgs');
}}
>
<FaBoxes className="weight-card-icon" />
<div className="weight-card-label">Medium Cargo (11-20 kgs)</div>
<div className="weight-card-desc">Grocery crates, retail goods</div>
</div>
<div
className={`weight-card-btn weight-heavy ${weight === '21-30kgs' ? 'active' : ''}`}
onClick={() => {
handleChipClick('21-30kgs');
setWeight('21-30kgs');
}}
>
<FaTruck className="weight-card-icon" />
<div className="weight-card-label">Heavy Cargo (21-30 kgs)</div>
<div className="weight-card-desc">Industrial parts, heavy shipments</div>
</div>
</div>
</Grid>
{/* Section Header: Handover & Schedule */}
<Grid item xs={12} sx={{ mt: 0.5, pb: 0 }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5, mb: 1 }}>
<Typography sx={{ display: 'flex', alignItems: 'center', gap: 1, fontWeight: 700, fontSize: '11px', color: '#64748b', letterSpacing: '0.8px', textTransform: 'uppercase' }}>
<CalendarOutlined style={{ fontSize: '12px', color: '#65387a' }} />
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 0.5 }}>
<Typography sx={{ display: 'flex', alignItems: 'center', gap: 0.75, fontWeight: 700, fontSize: '10.5px', color: '#64748b', letterSpacing: '0.7px', textTransform: 'uppercase' }}>
<CalendarOutlined style={{ fontSize: '11px', color: '#65387a' }} />
Schedule Details
</Typography>
<Box sx={{ flex: 1, height: '1px', background: 'linear-gradient(90deg, #eef2f6 0%, transparent 100%)' }} />
</Box>
</Grid>
{/* Nested Grid Container with tighter spacing={2} to eliminate excessive gaps */}
{/* Nested Grid Container with tight spacing to eliminate excessive gaps */}
<Grid item xs={12} sx={{ pt: '0px !important' }}>
<Grid container spacing={2}>
<Grid container spacing={1.5} sx={{ mt: 0.5 }}>
{/* Row 3: Pickup Date & Time Slot (Side-by-Side) */}
<Grid item xs={12} sm={6}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
@@ -2130,7 +2167,7 @@ const Createorder1 = () => {
width: '100%',
'& .MuiOutlinedInput-root': {
borderRadius: '12px',
height: '42px'
height: '38px'
}
}}
slotProps={{
@@ -2148,7 +2185,7 @@ const Createorder1 = () => {
sx: {
'& .MuiOutlinedInput-root': {
borderRadius: '12px',
height: '42px',
height: '38px',
paddingLeft: '10px'
}
}
@@ -2168,7 +2205,7 @@ const Createorder1 = () => {
width: '100%',
'& .MuiOutlinedInput-root': {
borderRadius: '12px',
height: '42px',
height: '38px',
paddingTop: '0px !important',
paddingBottom: '0px !important'
}
@@ -2194,7 +2231,7 @@ const Createorder1 = () => {
placeholder="Select Pickup Slot"
fullWidth
InputLabelProps={{ shrink: true }}
sx={{ '& .MuiOutlinedInput-root': { borderRadius: '12px', height: '42px' } }}
sx={{ '& .MuiOutlinedInput-root': { borderRadius: '12px', height: '38px' } }}
InputProps={{
...params.InputProps,
startAdornment: (
@@ -2209,95 +2246,6 @@ const Createorder1 = () => {
/>
</Grid>
{/* Row 4: Special Dispatch Notes & SMS Updates (Side-by-Side) */}
<Grid item xs={12} sm={6}>
<TextField
id="outlined-multiline-static"
label="Special Dispatch Notes"
size="small"
fullWidth
InputLabelProps={{ shrink: true }}
sx={{
width: '100%',
'& .MuiOutlinedInput-root': { borderRadius: '12px', height: '42px' }
}}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<FileTextOutlined style={{ color: '#94a3b8', fontSize: '13px' }} />
</InputAdornment>
)
}}
placeholder="Provide gate codes, call instructions, or special cargo care instructions..."
value={otherinstructions}
onChange={(e) => setOtherinstructions(e.target.value)}
/>
</Grid>
<Grid item xs={12} sm={6}>
<Stack
direction="row"
justifyContent="space-between"
alignItems="center"
spacing={1.5}
onClick={() => setIsSms(isSms === 1 ? 0 : 1)}
sx={{
py: 0,
px: 2,
height: '42px',
border: '1.5px solid #eef2f6',
borderRadius: '12px',
cursor: 'pointer',
userSelect: 'none',
bgcolor: isSms === 1 ? 'rgba(24, 144, 255, 0.04)' : '#fafbfc',
borderColor: isSms === 1 ? 'rgba(24, 144, 255, 0.25)' : '#eef2f6',
boxShadow: isSms === 1 ? '0 4px 12px rgba(24, 144, 255, 0.05)' : 'none',
transition: 'all 0.25s cubic-bezier(0.4, 0, 0.2, 1)',
'&:hover': {
transform: 'translateY(-1.2px)',
borderColor: isSms === 1 ? 'rgba(24, 144, 255, 0.4)' : '#cbd5e1',
boxShadow: isSms === 1 ? '0 6px 16px rgba(24, 144, 255, 0.08)' : '0 6px 16px rgba(0, 0, 0, 0.04)'
}
}}
>
<Stack direction="row" spacing={1} alignItems="center" sx={{ minWidth: 0 }}>
<Box
sx={{
width: 26,
height: 26,
borderRadius: '6px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
background: isSms === 1
? 'linear-gradient(135deg, #1890ff, #65387a)'
: '#eef2f6',
color: isSms === 1 ? '#ffffff' : '#94a3b8',
transition: 'all 0.2s ease',
flexShrink: 0
}}
>
<MessageOutlined style={{ fontSize: 11.5 }} />
</Box>
<Box sx={{ minWidth: 0 }}>
<Typography variant="h6" sx={{ fontWeight: 600, color: '#1e293b', fontSize: 12.5, lineHeight: 1.1 }}>
SMS Updates
</Typography>
<Typography variant="body2" sx={{ color: '#64748b', fontSize: 10, mt: 0.1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title="Send tracking updates automatically">
Track automatically
</Typography>
</Box>
</Stack>
<Switch
size="small"
checked={isSms === 1}
onChange={(e) => {
e.stopPropagation();
setIsSms(e.target.checked ? 1 : 0);
}}
/>
</Stack>
</Grid>
</Grid>
</Grid>
</Grid>
@@ -2315,12 +2263,12 @@ const Createorder1 = () => {
height: 'fit-content'
}}
>
<Stack spacing={4}>
<Stack spacing={2}>
{/* Map Card */}
<Card className="orders-card" sx={{ p: 2, display: 'flex', flexDirection: 'column' }}>
<Typography variant="h5" sx={{ fontWeight: 600, mb: 2, display: 'flex', alignItems: 'center', gap: 1, color: '#1e293b' }}>
<MyLocationIcon sx={{ color: '#1890ff', fontSize: 20 }} />
<Card className="orders-card" sx={{ p: 1.5, display: 'flex', flexDirection: 'column' }}>
<Typography sx={{ fontWeight: 700, mb: 1.25, display: 'flex', alignItems: 'center', gap: 0.75, color: '#1e293b', fontSize: '14px', letterSpacing: '-0.01em' }}>
<MyLocationIcon sx={{ color: '#1890ff', fontSize: 16 }} />
Live Route Preview
</Typography>
<div className="map-preview-wrapper">
@@ -2328,24 +2276,99 @@ const Createorder1 = () => {
</div>
</Card>
{/* Delivery Preferences — Dispatch Notes & SMS Updates */}
<Card className="orders-card delivery-prefs-card" sx={{ p: 1.5 }}>
<Box className="delivery-prefs-header">
<Typography className="delivery-prefs-title">Delivery Preferences</Typography>
<Typography className="delivery-prefs-sub">Customer notifications &amp; dispatch instructions</Typography>
</Box>
<Box className="delivery-prefs-row">
<Box className="delivery-prefs-field">
<label className="delivery-prefs-label" htmlFor="dispatch-notes-input">
<FileTextOutlined style={{ fontSize: 11, color: '#65387a' }} />
Special Dispatch Notes
</label>
<TextField
id="dispatch-notes-input"
size="small"
fullWidth
placeholder="Gate codes, call instructions, special cargo care…"
value={otherinstructions}
onChange={(e) => setOtherinstructions(e.target.value)}
sx={{
'& .MuiOutlinedInput-root': {
borderRadius: '10px',
padding: '0 10px',
alignItems: 'center',
fontSize: '12px',
background: '#ffffff',
height: '32px'
},
'& .MuiOutlinedInput-input': {
padding: '0 !important',
fontSize: '12px !important',
lineHeight: '32px'
}
}}
/>
</Box>
<Box
className={`sms-toggle-tile ${isSms === 1 ? 'is-active' : ''}`}
onClick={() => setIsSms(isSms === 1 ? 0 : 1)}
role="button"
tabIndex={0}
>
<Box className="sms-toggle-left">
<Box className="sms-toggle-icon">
<MessageOutlined style={{ fontSize: 13 }} />
</Box>
<Box sx={{ minWidth: 0 }}>
<Typography className="sms-toggle-title">SMS Updates</Typography>
<Typography className="sms-toggle-sub">Auto-notify customer on dispatch &amp; delivery</Typography>
</Box>
</Box>
<Switch
size="small"
checked={isSms === 1}
onChange={(e) => {
e.stopPropagation();
setIsSms(e.target.checked ? 1 : 0);
}}
/>
</Box>
</Box>
</Card>
{/* Pricing breakdown card */}
<Card className="orders-card pricing-summary-card">
<Typography variant="h5" sx={{ fontWeight: 600, mb: 2.5, color: '#1e293b' }}>
Pricing & Dispatch Metrics
</Typography>
<Box className="pricing-header">
<Typography className="pricing-title">Pricing &amp; Dispatch</Typography>
<Typography className="pricing-subtitle">Live cost estimate</Typography>
</Box>
<div className="price-metric-item">
<div className="price-metric-label">
<span style={{ fontSize: '20px' }}>📍</span> Delivery Distance
<span className="price-metric-icon icon-distance">
<FaRoute />
</span>
<span>Delivery Distance</span>
</div>
<div className={`price-metric-value ${showDistance ? 'highlight' : ''}`}>
{showDistance ? `${distance} km` : '--'}
{showDistance ? `${distance} km` : ''}
</div>
</div>
<div className="price-metric-item">
<div className="price-metric-label">
<span style={{ fontSize: '20px' }}>💵</span> Base Fare ({minKm} km limit)
<span className="price-metric-icon icon-base">
<FaMoneyBillWave />
</span>
<span>
Base Fare
<span className="price-metric-sub"> · {minKm} km</span>
</span>
</div>
<div className="price-metric-value">
{basePrice ? `${basePrice.toFixed(2)}` : '₹0.00'}
@@ -2354,28 +2377,36 @@ const Createorder1 = () => {
<div className="price-metric-item">
<div className="price-metric-label">
<span style={{ fontSize: '20px' }}>📈</span> Rate per km
<span className="price-metric-icon icon-rate">
<FaChartLine />
</span>
<span>Rate per km</span>
</div>
<div className="price-metric-value">
{pricePerKm ? `${pricePerKm.toFixed(2)}/km` : '₹0.00/km'}
{pricePerKm ? `${pricePerKm.toFixed(2)}` : '₹0.00'}
<span className="price-metric-unit">/km</span>
</div>
</div>
{/* Total Cost Display */}
{showDistance && (
<div className="total-charge-badge">
<div className="total-charge-label">Total Delivery Charge</div>
<div className="total-charge-left">
<FaReceipt className="total-charge-icon" />
<div className="total-charge-label">Total Delivery Charge</div>
</div>
<div className="total-charge-val">{totalCharge.toFixed(2)}</div>
</div>
)}
{/* Submit button */}
<Box sx={{ mt: 3 }}>
<Box sx={{ mt: 1.5 }}>
<AnimateButton>
<Button
fullWidth
className="gradient-btn-create"
disabled={!showDistance || !selectedtime || !pickupSlot}
startIcon={!btnLoading && <FaPaperPlane style={{ fontSize: 11 }} />}
onClick={() => {
setLoading(true);
setBtnLoading(true);
@@ -2387,7 +2418,7 @@ const Createorder1 = () => {
}}
>
{btnLoading ? (
<CircularProgress color="inherit" size={24} thickness={4} />
<CircularProgress color="inherit" size={16} thickness={5} />
) : (
'Dispatch Delivery Order'
)}