diff --git a/src/pages/Dashboard.jsx b/src/pages/Dashboard.jsx
index a0db701..b5c5ac9 100644
--- a/src/pages/Dashboard.jsx
+++ b/src/pages/Dashboard.jsx
@@ -47,6 +47,68 @@ const DAY_LABELS = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];
// ── Doormile-themed range calendar ───────────────────────────────────────────────
// Click a day to set the start, click again to set the end (auto-swaps if reversed).
// In-range days get a soft red wash; the two endpoints are solid brand red.
+// Renders two compact months side-by-side (single month on small screens).
+
+// A single compact month grid — kept lightweight so both months render fast.
+function MonthGrid({ view, start, end, max, onDay }) {
+ const gridStart = view.startOf('month').subtract(view.startOf('month').day(), 'day');
+ const cells = Array.from({ length: 42 }, (_, i) => gridStart.add(i, 'day'));
+
+ return (
+
+
+ {view.format('MMMM YYYY')}
+
+
+ {/* Weekday labels */}
+
+ {DAY_LABELS.map((d, i) => (
+
+ {d}
+
+ ))}
+
+
+ {/* Days */}
+
+ {cells.map((d) => {
+ const inMonth = d.month() === view.month();
+ const isStart = start && d.isSame(start, 'day');
+ const isEnd = end && d.isSame(end, 'day');
+ const isEndpoint = isStart || isEnd;
+ const inRange = start && end && d.isAfter(start, 'day') && d.isBefore(end, 'day');
+ const isToday = d.isSame(dayjs(), 'day');
+ const disabled = max && d.isAfter(max, 'day');
+ return (
+
+ onDay(d)}
+ sx={{
+ width: 28, height: 28, m: '1px', border: 'none', cursor: disabled ? 'default' : 'pointer',
+ borderRadius: 1.5, fontSize: '0.72rem', fontFamily: 'inherit',
+ fontWeight: isEndpoint ? 700 : 500,
+ color: disabled ? '#D5D9DD' : isEndpoint ? '#fff' : inMonth ? '#3C4043' : '#C4C9CE',
+ bgcolor: isEndpoint ? BRAND : 'transparent',
+ boxShadow: isToday && !isEndpoint ? `inset 0 0 0 1.5px ${BRAND}` : 'none',
+ transition: 'background-color .12s',
+ '&:hover': { bgcolor: disabled ? 'transparent' : isEndpoint ? '#9E0E20' : alpha(BRAND, 0.1) }
+ }}
+ >
+ {d.date()}
+
+
+ );
+ })}
+
+
+ );
+}
+
function RangeCalendar({ from, to, maxDate, onSelect }) {
const [view, setView] = useState(dayjs(to || from || undefined).startOf('month'));
const [anchorDate, setAnchorDate] = useState(null); // first click while picking a new range
@@ -55,9 +117,6 @@ function RangeCalendar({ from, to, maxDate, onSelect }) {
const end = to ? dayjs(to) : null;
const max = maxDate ? dayjs(maxDate) : null;
- const gridStart = view.startOf('month').subtract(view.startOf('month').day(), 'day');
- const cells = Array.from({ length: 42 }, (_, i) => gridStart.add(i, 'day'));
-
const handleDay = (d) => {
if (!anchorDate) {
setAnchorDate(d);
@@ -72,63 +131,23 @@ function RangeCalendar({ from, to, maxDate, onSelect }) {
};
return (
-
- {/* Month header */}
-
- setView((v) => v.subtract(1, 'month'))} sx={{ color: '#5F6368' }}>
-
+
+ {/* Shared nav header spanning both months */}
+
+ setView((v) => v.subtract(1, 'month'))} sx={{ color: '#9AA0A6', p: 0.5 }}>
+
- {view.format('MMMM YYYY')}
- setView((v) => v.add(1, 'month'))} sx={{ color: '#5F6368' }}>
-
+ setView((v) => v.add(1, 'month'))} sx={{ color: '#9AA0A6', p: 0.5 }}>
+
- {/* Weekday labels */}
-
- {DAY_LABELS.map((d, i) => (
-
- {d}
-
- ))}
-
-
- {/* Days */}
-
- {cells.map((d) => {
- const inMonth = d.month() === view.month();
- const isStart = start && d.isSame(start, 'day');
- const isEnd = end && d.isSame(end, 'day');
- const isEndpoint = isStart || isEnd;
- const inRange = start && end && d.isAfter(start, 'day') && d.isBefore(end, 'day');
- const isToday = d.isSame(dayjs(), 'day');
- const disabled = max && d.isAfter(max, 'day');
- return (
-
- handleDay(d)}
- sx={{
- width: 36, height: 36, m: '2px', border: 'none', cursor: disabled ? 'default' : 'pointer',
- borderRadius: 2, fontSize: '0.85rem', fontFamily: 'inherit',
- fontWeight: isEndpoint ? 800 : 600,
- color: disabled ? '#CED4DA' : isEndpoint ? '#fff' : inMonth ? '#212529' : '#B9BEC4',
- bgcolor: isEndpoint ? BRAND : 'transparent',
- boxShadow: isToday && !isEndpoint ? `inset 0 0 0 1.5px ${BRAND}` : 'none',
- transition: 'background-color .15s',
- '&:hover': { bgcolor: disabled ? 'transparent' : isEndpoint ? '#9E0E20' : alpha(BRAND, 0.12) }
- }}
- >
- {d.date()}
-
-
- );
- })}
-
+
+
+
+
+
+
);
}
@@ -317,11 +336,11 @@ export default function Dashboard() {
onClose={() => setCalAnchor(null)}
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
- PaperProps={{ sx: { mt: 1, borderRadius: 3, border: '1px solid #ECEEF1', boxShadow: '0 12px 40px rgba(0,0,0,0.14)', overflow: 'hidden' } }}
+ PaperProps={{ sx: { mt: 1, borderRadius: 2.5, border: '1px solid #EEF0F2', boxShadow: '0 8px 28px rgba(0,0,0,0.10)', overflow: 'hidden' } }}
>
-
- Select date range
-
+
+ Select date range
+
{dayjs(range.from).format('DD MMM')} – {dayjs(range.to).format('DD MMM YYYY')} · {dayCount} {dayCount === 1 ? 'day' : 'days'}
diff --git a/src/pages/operations/Dispatch.jsx b/src/pages/operations/Dispatch.jsx
index 9b4a90d..46d639a 100644
--- a/src/pages/operations/Dispatch.jsx
+++ b/src/pages/operations/Dispatch.jsx
@@ -147,7 +147,7 @@ export default function Dispatch() {
diff --git a/src/pages/operations/RiderRoutes.jsx b/src/pages/operations/RiderRoutes.jsx
index 10a900b..2540d8e 100644
--- a/src/pages/operations/RiderRoutes.jsx
+++ b/src/pages/operations/RiderRoutes.jsx
@@ -529,7 +529,7 @@ export default function RiderRoutes() {
Rider Routes
- Pickups each miler covered today — open any order for full details, or press play to replay the trip.
+ Pickups each miler covered today open any order for full details, or press play to replay the trip.
diff --git a/src/pages/operations/Routing.jsx b/src/pages/operations/Routing.jsx
index a2a1e81..c31d4fc 100644
--- a/src/pages/operations/Routing.jsx
+++ b/src/pages/operations/Routing.jsx
@@ -146,7 +146,7 @@ export default function Routing() {
Where Does It Go?
- Scan a parcel and we'll tell you exactly what to do with it next — deliver locally, transfer to another city, or set it aside.
+ Scan a parcel and we'll tell you exactly what to do with it next deliver locally, transfer to another city, or set it aside.