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

@@ -5,7 +5,7 @@
/* ============================================== */
.location-panel {
position: relative;
padding: 16px 18px 16px 18px;
padding: 12px 14px;
border-radius: 12px;
border: 1px solid #eef2f6;
background: linear-gradient(180deg, #ffffff 0%, #fbfcff 100%);
@@ -39,10 +39,10 @@
display: flex;
justify-content: space-between;
align-items: center;
gap: 12px;
gap: 10px;
flex-wrap: wrap;
margin-bottom: 22px;
padding-bottom: 18px;
margin-bottom: 12px;
padding-bottom: 10px;
border-bottom: 1px dashed #e2e8f0;
}
@@ -154,16 +154,16 @@
}
.lp-badge {
width: 42px;
height: 42px;
border-radius: 12px;
width: 34px;
height: 34px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
font-size: 15px;
color: #fff;
flex-shrink: 0;
box-shadow: 0 6px 14px rgba(0, 0, 0, 0.10);
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.10);
}
.pickup-panel .lp-badge {
@@ -177,25 +177,26 @@
}
.lp-title {
font-size: 18px;
font-size: 15px;
font-weight: 700;
color: #1e293b;
line-height: 1.2;
}
.lp-subtitle {
font-size: 13.5px;
font-size: 11.5px;
color: #94a3b8;
margin-top: 3px;
margin-top: 1px;
}
.lp-action-btn {
text-transform: none !important;
font-weight: 600 !important;
font-size: 13.5px !important;
border-radius: 10px !important;
padding: 7px 14px !important;
font-size: 12px !important;
border-radius: 8px !important;
padding: 5px 11px !important;
letter-spacing: 0.2px !important;
min-height: 30px !important;
}
.pickup-panel .lp-action-btn {
@@ -264,12 +265,12 @@
display: flex;
align-items: center;
gap: 8px;
font-size: 12.5px;
font-size: 10.5px;
font-weight: 700;
letter-spacing: 0.8px;
letter-spacing: 0.7px;
text-transform: uppercase;
color: #64748b;
margin-bottom: 14px;
margin-bottom: 8px;
}
.field-group-caption::after {
@@ -723,48 +724,53 @@
/* MUI Field Sizing — Readable on large screens */
/* ============================================== */
/* Bump TextField input + label sizes inside Pickup/Drop panels and order cards */
/* Compact TextField input + label sizes inside Pickup/Drop panels and order cards */
.location-panel .MuiOutlinedInput-root,
.orders-card .MuiOutlinedInput-root {
font-size: 14.5px !important;
font-size: 13px !important;
border-radius: 10px !important;
}
.location-panel .MuiOutlinedInput-input,
.orders-card .MuiOutlinedInput-input {
font-size: 14.5px !important;
padding-top: 11px !important;
padding-bottom: 11px !important;
font-size: 13px !important;
padding-top: 9px !important;
padding-bottom: 9px !important;
}
.location-panel .MuiInputLabel-root,
.orders-card .MuiInputLabel-root {
font-size: 14.5px !important;
font-size: 13px !important;
}
/* When label is shrunk (floating up), keep it slightly smaller for the float effect */
.location-panel .MuiInputLabel-root.MuiInputLabel-shrink,
.orders-card .MuiInputLabel-root.MuiInputLabel-shrink {
font-size: 13px !important;
font-size: 11.5px !important;
}
/* MUI helper text (validation / hints under fields) */
.location-panel .MuiFormHelperText-root,
.orders-card .MuiFormHelperText-root {
font-size: 12.5px !important;
font-size: 11px !important;
margin-top: 3px !important;
}
/* Autocomplete options dropdown */
.MuiAutocomplete-popper .MuiAutocomplete-option {
font-size: 14.5px !important;
font-size: 13px !important;
padding-top: 6px !important;
padding-bottom: 6px !important;
min-height: 34px !important;
}
/* Card section titles (h5 / h6) inside order cards — bump slightly for hierarchy */
/* Card section titles (h5 / h6) inside order cards — tighter hierarchy */
.orders-card .MuiTypography-h5 {
font-size: 19px !important;
font-size: 15px !important;
}
.orders-card .MuiTypography-h6 {
font-size: 16.5px !important;
font-size: 13.5px !important;
}
.orders-card:hover {
@@ -900,99 +906,209 @@
overflow: hidden;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
border: 1px solid #eef2f6;
height: 380px;
min-height: 380px;
height: 260px;
min-height: 260px;
}
/* Premium Cost & Metrics Dashboard */
.map-preview-wrapper .leaflet-container {
height: 100% !important;
min-height: 0 !important;
}
.map-preview-wrapper > div {
min-height: 0 !important;
}
/* Premium Cost & Metrics Dashboard — compact professional layout */
.pricing-summary-card {
background: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%) !important;
border: 1px solid #eef2f6 !important;
border-radius: 16px !important;
padding: 20px !important;
border-radius: 14px !important;
padding: 14px 16px !important;
}
.pricing-header {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 12px;
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 1px solid #f1f5f9;
}
.pricing-title {
font-size: 14px !important;
font-weight: 700 !important;
color: #1e293b !important;
letter-spacing: -0.01em;
}
.pricing-subtitle {
font-size: 11px !important;
font-weight: 500 !important;
color: #94a3b8 !important;
text-transform: uppercase;
letter-spacing: 0.6px;
}
.price-metric-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 0;
border-bottom: 1px dashed #e2e8f0;
padding: 7px 0;
border-bottom: 1px solid #f5f7fa;
}
.price-metric-item:last-child {
.price-metric-item:last-of-type {
border-bottom: none;
padding-bottom: 4px;
}
.price-metric-label {
font-size: 14.5px;
font-size: 12.5px;
color: #475569;
font-weight: 500;
display: flex;
align-items: center;
gap: 8px;
gap: 10px;
min-width: 0;
}
.price-metric-icon {
width: 26px;
height: 26px;
flex-shrink: 0;
border-radius: 8px;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 12px;
}
.price-metric-icon.icon-distance {
background: rgba(24, 144, 255, 0.10);
color: #1890ff;
}
.price-metric-icon.icon-base {
background: rgba(34, 197, 94, 0.10);
color: #16a34a;
}
.price-metric-icon.icon-rate {
background: rgba(245, 158, 11, 0.12);
color: #d97706;
}
.price-metric-sub {
color: #94a3b8;
font-weight: 500;
font-size: 11.5px;
}
.price-metric-value {
font-size: 16px;
font-size: 13.5px;
font-weight: 700;
color: #1e293b;
display: inline-flex;
align-items: baseline;
gap: 2px;
white-space: nowrap;
}
.price-metric-value.highlight {
color: #1890ff;
}
.price-metric-unit {
font-size: 11px;
font-weight: 500;
color: #94a3b8;
margin-left: 2px;
}
.total-charge-badge {
background: linear-gradient(135deg, rgba(24, 144, 255, 0.08) 0%, rgba(101, 56, 122, 0.08) 100%);
border: 1px solid rgba(24, 144, 255, 0.15);
border-radius: 12px;
padding: 16px;
background: linear-gradient(135deg, rgba(24, 144, 255, 0.08) 0%, rgba(101, 56, 122, 0.10) 100%);
border: 1px solid rgba(101, 56, 122, 0.18);
border-radius: 10px;
padding: 10px 14px;
display: flex;
flex-direction: column;
align-items: center;
margin-top: 16px;
justify-content: space-between;
gap: 12px;
margin-top: 12px;
}
.total-charge-left {
display: inline-flex;
align-items: center;
gap: 8px;
min-width: 0;
}
.total-charge-icon {
font-size: 13px;
color: #65387A;
flex-shrink: 0;
}
.total-charge-label {
font-size: 13px;
font-size: 11.5px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.8px;
letter-spacing: 0.6px;
color: #65387A;
margin-bottom: 6px;
}
.total-charge-val {
font-size: 32px;
font-size: 20px;
font-weight: 800;
color: #65387A;
line-height: 1.1;
letter-spacing: -0.01em;
white-space: nowrap;
}
/* Gradient Action Button */
/* Gradient Action Button — compact professional */
.gradient-btn-create {
background: linear-gradient(135deg, #1890ff 0%, #65387a 100%) !important;
color: #ffffff !important;
font-weight: 600 !important;
border-radius: 12px !important;
padding: 12px 28px !important;
box-shadow: 0 8px 20px -4px rgba(24, 144, 255, 0.3) !important;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
font-size: 13px !important;
letter-spacing: 0.01em !important;
text-transform: none !important;
border-radius: 10px !important;
padding: 8px 18px !important;
min-height: 38px !important;
box-shadow: 0 4px 12px -3px rgba(24, 144, 255, 0.30), 0 2px 4px rgba(101, 56, 122, 0.10) !important;
transition: all 0.22s cubic-bezier(0.4, 0, 0.2, 1) !important;
border: none !important;
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
gap: 8px !important;
}
.gradient-btn-create .MuiButton-startIcon,
.gradient-btn-create .MuiButton-endIcon {
margin: 0 !important;
}
.gradient-btn-create:hover {
transform: translateY(-2px) !important;
box-shadow: 0 12px 28px -4px rgba(24, 144, 255, 0.45), 0 4px 10px rgba(101, 56, 122, 0.2) !important;
transform: translateY(-1px) !important;
filter: brightness(1.04);
box-shadow: 0 8px 18px -4px rgba(24, 144, 255, 0.40), 0 3px 8px rgba(101, 56, 122, 0.18) !important;
}
.gradient-btn-create:active {
transform: translateY(0) !important;
filter: brightness(0.98);
}
.gradient-btn-create.Mui-disabled,
.gradient-btn-create:disabled {
background: #cbd5e1 !important;
background: #e2e8f0 !important;
color: #94a3b8 !important;
box-shadow: none !important;
cursor: not-allowed !important;
@@ -1261,8 +1377,8 @@
}
.map-preview-wrapper {
height: 300px;
min-height: 300px;
height: 220px;
min-height: 220px;
}
.weight-card-btn {
@@ -1299,4 +1415,464 @@
main:has(.orders-workspace-bg) {
padding: 16px !important;
}
}
/* ============================================== */
/* Compact header dropdowns (Location / Client / Business Location) */
/* ============================================== */
.header-compact-tf .MuiOutlinedInput-root {
border-radius: 10px !important;
height: 40px !important;
padding-left: 10px !important;
font-size: 12.5px !important;
background: #ffffff;
}
.header-compact-tf .MuiOutlinedInput-input {
padding-top: 6px !important;
padding-bottom: 6px !important;
font-size: 12.5px !important;
}
.header-compact-tf .MuiInputLabel-root {
font-size: 11.5px !important;
letter-spacing: 0.02em;
font-weight: 600;
color: #64748b !important;
}
.header-compact-tf .MuiInputLabel-shrink {
transform: translate(12px, -7px) scale(0.82) !important;
background: #ffffff;
padding: 0 4px;
}
.header-compact-tf .MuiOutlinedInput-notchedOutline {
border-color: #e2e8f0;
}
.header-compact-tf:hover .MuiOutlinedInput-notchedOutline {
border-color: #cbd5e1;
}
.header-compact-tf .Mui-focused .MuiOutlinedInput-notchedOutline {
border-width: 1.5px !important;
}
/* Autocomplete-specific tweaks: vertically center the clear / popup icons */
.header-compact-input .MuiAutocomplete-endAdornment {
top: 50%;
transform: translateY(-50%);
right: 8px;
display: inline-flex;
align-items: center;
height: auto;
gap: 2px;
}
.header-compact-input .MuiAutocomplete-endAdornment .MuiSvgIcon-root {
font-size: 16px;
display: block;
}
.header-compact-input .MuiAutocomplete-clearIndicator,
.header-compact-input .MuiAutocomplete-popupIndicator {
padding: 3px !important;
width: 22px;
height: 22px;
display: inline-flex;
align-items: center;
justify-content: center;
color: #94a3b8 !important;
}
.header-compact-input .MuiAutocomplete-clearIndicator:hover,
.header-compact-input .MuiAutocomplete-popupIndicator:hover {
background: rgba(148, 163, 184, 0.12) !important;
color: #475569 !important;
}
.header-compact-input .MuiAutocomplete-popupIndicator {
margin-right: 0;
}
.header-compact-input .MuiOutlinedInput-root {
padding-top: 0 !important;
padding-bottom: 0 !important;
padding-right: 60px !important;
}
.header-compact-input .MuiAutocomplete-input {
padding: 4px 4px 4px 0 !important;
height: auto !important;
}
/* Title row alignment tweak for tighter header */
.page-header-row {
min-height: 0 !important;
}
/* ============================================== */
/* Delivery Preferences Card */
/* (Special Dispatch Notes + SMS Updates) */
/* ============================================== */
.delivery-prefs-card {
background: linear-gradient(135deg, #ffffff 0%, #fbfcff 100%) !important;
border: 1px solid #eef2f6 !important;
border-radius: 14px !important;
}
.delivery-prefs-header {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 10px;
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 1px solid #f1f5f9;
}
.delivery-prefs-title {
font-size: 14px !important;
font-weight: 700 !important;
color: #1e293b !important;
letter-spacing: -0.01em;
line-height: 1.2;
}
.delivery-prefs-sub {
font-size: 10.5px !important;
font-weight: 500 !important;
color: #94a3b8 !important;
text-transform: uppercase;
letter-spacing: 0.55px;
text-align: right;
line-height: 1.2;
}
.delivery-prefs-row {
display: flex;
flex-direction: column;
gap: 10px;
}
.delivery-prefs-field {
display: flex;
flex-direction: column;
gap: 5px;
}
.delivery-prefs-label {
display: inline-flex;
align-items: center;
gap: 5px;
font-size: 10.5px;
font-weight: 700;
letter-spacing: 0.55px;
text-transform: uppercase;
color: #64748b;
}
/* SMS toggle tile — a card-like clickable strip */
.sms-toggle-tile {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
padding: 8px 12px;
border-radius: 10px;
border: 1px solid #eef2f6;
background: #fafbfc;
cursor: pointer;
user-select: none;
transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
}
.sms-toggle-tile:hover {
border-color: #cbd5e1;
background: #ffffff;
}
.sms-toggle-tile.is-active {
background: linear-gradient(135deg, rgba(24, 144, 255, 0.06) 0%, rgba(101, 56, 122, 0.05) 100%);
border-color: rgba(24, 144, 255, 0.28);
box-shadow: 0 3px 10px -3px rgba(24, 144, 255, 0.18);
}
.sms-toggle-left {
display: inline-flex;
align-items: center;
gap: 9px;
min-width: 0;
}
.sms-toggle-icon {
width: 28px;
height: 28px;
flex-shrink: 0;
border-radius: 8px;
display: inline-flex;
align-items: center;
justify-content: center;
background: #eef2f6;
color: #94a3b8;
transition: all 0.2s ease;
}
.sms-toggle-tile.is-active .sms-toggle-icon {
background: linear-gradient(135deg, #1890ff, #65387a);
color: #ffffff;
box-shadow: 0 3px 10px rgba(101, 56, 122, 0.22);
}
.sms-toggle-title {
font-size: 12.5px !important;
font-weight: 700 !important;
color: #1e293b !important;
line-height: 1.2 !important;
letter-spacing: -0.005em;
}
.sms-toggle-sub {
font-size: 10.5px !important;
color: #94a3b8 !important;
font-weight: 500 !important;
margin-top: 1px !important;
line-height: 1.2 !important;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.sms-toggle-tile .MuiSwitch-root {
flex-shrink: 0;
}
/* ============================================== */
/* Pickup → Drop Two-Step Stepper */
/* ============================================== */
.route-stepper {
display: flex;
align-items: stretch;
gap: 0;
padding: 4px;
margin-bottom: 12px;
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
border: 1px solid #e2e8f0;
border-radius: 12px;
}
.route-step {
flex: 1;
display: flex;
align-items: center;
gap: 10px;
padding: 6px 10px;
border-radius: 9px;
cursor: pointer;
transition: background-color 0.22s ease, box-shadow 0.22s ease, transform 0.22s ease;
user-select: none;
background: transparent;
outline: none;
}
.route-step:hover {
background: rgba(255, 255, 255, 0.6);
}
.route-step.is-active {
background: #ffffff;
box-shadow: 0 6px 18px -8px rgba(15, 23, 42, 0.12), 0 2px 6px -2px rgba(15, 23, 42, 0.06);
transform: translateY(-1px);
}
.route-step.is-locked {
cursor: not-allowed;
opacity: 0.6;
}
.route-step.is-locked:hover {
background: transparent;
}
.route-step-index {
width: 26px;
height: 26px;
flex-shrink: 0;
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
font-weight: 700;
font-size: 12px;
color: #94a3b8;
background: #ffffff;
border: 1.5px solid #e2e8f0;
transition: all 0.22s ease;
}
.step-pickup.is-active .route-step-index {
background: linear-gradient(135deg, #1890ff, #096dd9);
border-color: transparent;
color: #ffffff;
box-shadow: 0 4px 12px rgba(24, 144, 255, 0.32);
}
.step-drop.is-active .route-step-index {
background: linear-gradient(135deg, #a855f7, #65387a);
border-color: transparent;
color: #ffffff;
box-shadow: 0 4px 12px rgba(101, 56, 122, 0.32);
}
.step-pickup.is-done:not(.is-active) .route-step-index {
background: rgba(34, 197, 94, 0.12);
border-color: rgba(34, 197, 94, 0.35);
color: #16a34a;
}
.route-step-text {
display: flex;
flex-direction: column;
line-height: 1.2;
}
.route-step-title {
font-size: 13px !important;
font-weight: 700 !important;
color: #1e293b !important;
letter-spacing: -0.01em;
}
.route-step.is-locked .route-step-title {
color: #94a3b8 !important;
}
.route-step-sub {
font-size: 10.5px !important;
font-weight: 500 !important;
color: #94a3b8 !important;
margin-top: 1px !important;
}
.route-step-connector {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 0 6px;
position: relative;
min-width: 28px;
}
.route-step-line {
width: 100%;
height: 2px;
background: #e2e8f0;
border-radius: 2px;
transition: background 0.3s ease;
}
.route-step-connector.is-done .route-step-line {
background: linear-gradient(90deg, #1890ff, #a855f7);
}
.route-step-line-arrow {
position: absolute;
display: inline-flex;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
border-radius: 50%;
background: #ffffff;
border: 1.5px solid #e2e8f0;
color: #cbd5e1;
font-size: 10px;
transition: all 0.3s ease;
}
.route-step-connector.is-done .route-step-line-arrow {
border-color: rgba(168, 85, 247, 0.4);
color: #a855f7;
}
/* Step navigation footer inside each panel */
.step-nav {
margin-top: 12px;
padding-top: 10px;
border-top: 1px dashed #e2e8f0;
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
flex-wrap: wrap;
}
.step-nav-hint {
font-size: 11.5px !important;
color: #64748b !important;
font-weight: 500 !important;
}
.step-nav-btn {
text-transform: none !important;
font-weight: 600 !important;
border-radius: 8px !important;
padding: 6px 14px !important;
font-size: 12px !important;
letter-spacing: 0.01em !important;
transition: all 0.22s ease !important;
min-height: 32px !important;
}
.step-nav-next {
background: linear-gradient(135deg, #1890ff, #65387a) !important;
color: #ffffff !important;
box-shadow: 0 6px 18px -6px rgba(101, 56, 122, 0.35) !important;
}
.step-nav-next:hover {
filter: brightness(1.05);
transform: translateY(-1px);
box-shadow: 0 10px 22px -8px rgba(101, 56, 122, 0.45) !important;
}
.step-nav-next.Mui-disabled {
background: #e2e8f0 !important;
color: #94a3b8 !important;
box-shadow: none !important;
}
.step-nav-back {
color: #475569 !important;
background: #f1f5f9 !important;
border: 1px solid #e2e8f0 !important;
}
.step-nav-back:hover {
background: #e2e8f0 !important;
color: #1e293b !important;
}
@media (max-width: 599px) {
.route-step-sub {
display: none !important;
}
.route-step {
padding: 8px 10px;
gap: 8px;
}
.route-step-index {
width: 28px;
height: 28px;
font-size: 13px;
}
.step-nav {
flex-direction: column-reverse;
align-items: stretch;
}
.step-nav-btn {
width: 100%;
}
}

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'
)}