Fix typos and improve readability in Dashboard, Dispatch, RiderRoutes, and Routing components

This commit is contained in:
2026-07-03 11:40:19 +05:30
parent c36f2d5b1d
commit 200831d19c
4 changed files with 82 additions and 63 deletions

View File

@@ -47,6 +47,68 @@ const DAY_LABELS = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];
// ── Doormile-themed range calendar ─────────────────────────────────────────────── // ── Doormile-themed range calendar ───────────────────────────────────────────────
// Click a day to set the start, click again to set the end (auto-swaps if reversed). // 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. // 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 (
<Box sx={{ width: 224 }}>
<Typography align="center" sx={{ fontWeight: 700, fontSize: '0.82rem', color: '#212529', mb: 0.75 }}>
{view.format('MMMM YYYY')}
</Typography>
{/* Weekday labels */}
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', mb: 0.25 }}>
{DAY_LABELS.map((d, i) => (
<Typography key={i} align="center" sx={{ fontSize: '0.62rem', fontWeight: 600, color: '#B0B5BA', py: 0.25 }}>
{d}
</Typography>
))}
</Box>
{/* Days */}
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)' }}>
{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 (
<Box key={d.format(DATE_FMT)} sx={{ display: 'flex', justifyContent: 'center', bgcolor: inRange ? alpha(BRAND, 0.07) : 'transparent',
borderTopLeftRadius: isStart ? 6 : 0, borderBottomLeftRadius: isStart ? 6 : 0,
borderTopRightRadius: isEnd ? 6 : 0, borderBottomRightRadius: isEnd ? 6 : 0 }}>
<Box
component="button"
type="button"
disabled={disabled}
onClick={() => 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()}
</Box>
</Box>
);
})}
</Box>
</Box>
);
}
function RangeCalendar({ from, to, maxDate, onSelect }) { function RangeCalendar({ from, to, maxDate, onSelect }) {
const [view, setView] = useState(dayjs(to || from || undefined).startOf('month')); const [view, setView] = useState(dayjs(to || from || undefined).startOf('month'));
const [anchorDate, setAnchorDate] = useState(null); // first click while picking a new range 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 end = to ? dayjs(to) : null;
const max = maxDate ? dayjs(maxDate) : 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) => { const handleDay = (d) => {
if (!anchorDate) { if (!anchorDate) {
setAnchorDate(d); setAnchorDate(d);
@@ -72,63 +131,23 @@ function RangeCalendar({ from, to, maxDate, onSelect }) {
}; };
return ( return (
<Box sx={{ p: 2, width: 320 }}> <Box sx={{ px: 1.5, py: 1.5 }}>
{/* Month header */} {/* Shared nav header spanning both months */}
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ mb: 1.5 }}> <Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ mb: 1 }}>
<IconButton size="small" onClick={() => setView((v) => v.subtract(1, 'month'))} sx={{ color: '#5F6368' }}> <IconButton size="small" onClick={() => setView((v) => v.subtract(1, 'month'))} sx={{ color: '#9AA0A6', p: 0.5 }}>
<ChevronLeftRoundedIcon /> <ChevronLeftRoundedIcon fontSize="small" />
</IconButton> </IconButton>
<Typography sx={{ fontWeight: 800, color: '#212529' }}>{view.format('MMMM YYYY')}</Typography> <IconButton size="small" onClick={() => setView((v) => v.add(1, 'month'))} sx={{ color: '#9AA0A6', p: 0.5 }}>
<IconButton size="small" onClick={() => setView((v) => v.add(1, 'month'))} sx={{ color: '#5F6368' }}> <ChevronRightRoundedIcon fontSize="small" />
<ChevronRightRoundedIcon />
</IconButton> </IconButton>
</Stack> </Stack>
{/* Weekday labels */} <Stack direction="row" spacing={2}>
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', mb: 0.5 }}> <MonthGrid view={view} start={start} end={end} max={max} onDay={handleDay} />
{DAY_LABELS.map((d, i) => ( <Box sx={{ display: { xs: 'none', sm: 'block' } }}>
<Typography key={i} align="center" sx={{ fontSize: '0.72rem', fontWeight: 700, color: '#9AA0A6', py: 0.5 }}> <MonthGrid view={view.add(1, 'month')} start={start} end={end} max={max} onDay={handleDay} />
{d} </Box>
</Typography> </Stack>
))}
</Box>
{/* Days */}
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', rowGap: 0.25 }}>
{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 (
<Box key={d.format(DATE_FMT)} sx={{ display: 'flex', justifyContent: 'center', bgcolor: inRange ? alpha(BRAND, 0.08) : 'transparent',
borderTopLeftRadius: isStart ? 8 : 0, borderBottomLeftRadius: isStart ? 8 : 0,
borderTopRightRadius: isEnd ? 8 : 0, borderBottomRightRadius: isEnd ? 8 : 0 }}>
<Box
component="button"
type="button"
disabled={disabled}
onClick={() => 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()}
</Box>
</Box>
);
})}
</Box>
</Box> </Box>
); );
} }
@@ -317,11 +336,11 @@ export default function Dashboard() {
onClose={() => setCalAnchor(null)} onClose={() => setCalAnchor(null)}
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }} anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
transformOrigin={{ vertical: 'top', 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' } }}
> >
<Box sx={{ px: 2, pt: 2 }}> <Box sx={{ px: 2, pt: 1.75, pb: 0.5 }}>
<Typography sx={{ fontWeight: 800, color: '#212529' }}>Select date range</Typography> <Typography sx={{ fontWeight: 700, fontSize: '0.9rem', color: '#212529' }}>Select date range</Typography>
<Typography variant="caption" color="text.secondary"> <Typography variant="caption" sx={{ color: '#8A9099' }}>
{dayjs(range.from).format('DD MMM')} {dayjs(range.to).format('DD MMM YYYY')} · {dayCount} {dayCount === 1 ? 'day' : 'days'} {dayjs(range.from).format('DD MMM')} {dayjs(range.to).format('DD MMM YYYY')} · {dayCount} {dayCount === 1 ? 'day' : 'days'}
</Typography> </Typography>
</Box> </Box>

View File

@@ -147,7 +147,7 @@ export default function Dispatch() {
<PageHeader <PageHeader
icon={LocalShippingIcon} icon={LocalShippingIcon}
title="Dispatch & Transfer" title="Dispatch & Transfer"
subtitle="Group parcels that go out together, check them, and send them either out for local delivery or transferred to another city hub." subtitle="Group parcels that go out together, check them, and send them either out for local delivery or transferred to another city hub."
/> />
<Grid container spacing={3}> <Grid container spacing={3}>

View File

@@ -529,7 +529,7 @@ export default function RiderRoutes() {
<Box> <Box>
<Typography variant="h4" sx={{ fontWeight: 800, letterSpacing: '-0.4px', lineHeight: 1.2 }}>Rider Routes</Typography> <Typography variant="h4" sx={{ fontWeight: 800, letterSpacing: '-0.4px', lineHeight: 1.2 }}>Rider Routes</Typography>
<Typography variant="body1" color="text.secondary" sx={{ fontWeight: 500 }}> <Typography variant="body1" color="text.secondary" sx={{ fontWeight: 500 }}>
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.
</Typography> </Typography>
</Box> </Box>
</Stack> </Stack>

View File

@@ -146,7 +146,7 @@ export default function Routing() {
<Box sx={{ mb: 4 }}> <Box sx={{ mb: 4 }}>
<Typography variant="h4" sx={{ fontWeight: 800, color: '#212529', mb: 1 }}>Where Does It Go?</Typography> <Typography variant="h4" sx={{ fontWeight: 800, color: '#212529', mb: 1 }}>Where Does It Go?</Typography>
<Typography variant="body1" color="text.secondary"> <Typography variant="body1" color="text.secondary">
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.
</Typography> </Typography>
</Box> </Box>