updated the ui for the mobile view

This commit is contained in:
2026-06-09 13:12:18 +05:30
parent 8513c7c2ec
commit f18b680247
29 changed files with 3664 additions and 225 deletions

View File

@@ -0,0 +1,140 @@
import PropTypes from 'prop-types';
import { Box, Paper, Stack, Typography } from '@mui/material';
// ============================================================================
// MobileCard — shared primitives that turn a desktop data-table row into an
// app-style card on phones. Used by every operator list page (deliveries,
// orders, customers, riders, tenants, …) so the mobile experience is
// consistent. Purely presentational: pages keep their own data + handlers and
// just slot content into these shells. Desktop layouts are untouched — these
// only render inside an `isMobile` branch.
//
// Tokens mirror the `DT` block in deliveries.js so cards match page surfaces.
// ============================================================================
const BORDER = '#e2e8f0';
const MUTED = '#94a3b8';
const PRIMARY_TEXT = '#0f172a';
// Vertical list wrapper — drop-in replacement for <TableContainer>/<TableBody>
// on mobile. `scroll` makes it an internal scroll region (matches the table's
// maxHeight behaviour); omit it to let the page scroll naturally.
export const MobileCardList = ({ children, scroll = false, onScroll, sx, ...rest }) => (
<Stack
spacing={1.25}
onScroll={onScroll}
sx={{
p: 1.5,
...(scroll && { maxHeight: 'calc(100vh - 220px)', overflowY: 'auto', overflowX: 'hidden' }),
...sx
}}
{...rest}
>
{children}
</Stack>
);
MobileCardList.propTypes = {
children: PropTypes.node,
scroll: PropTypes.bool,
onScroll: PropTypes.func,
sx: PropTypes.object
};
// Card shell — coloured accent rail on the left, a header slot (status badge /
// title / action buttons), then any field grid / collapse content as children.
export const MobileCard = ({ accent = '#662582', header, footer, selected = false, onClick, children, sx }) => (
<Paper
elevation={0}
onClick={onClick}
sx={{
position: 'relative',
overflow: 'hidden',
// Cards live inside a flex-column list; without this, a scroll-capped
// list (maxHeight) would SHRINK each card to a sliver (flex-shrink:1)
// and clip its content instead of scrolling. Keep natural height.
flexShrink: 0,
borderRadius: 2.5,
border: '1px solid',
borderColor: selected ? accent : BORDER,
background: selected ? `${accent}0a` : '#fff',
boxShadow: '0 4px 14px rgba(15,23,42,0.05)',
transition: 'border-color 0.15s, box-shadow 0.15s',
...sx
}}
>
<Box sx={{ position: 'absolute', left: 0, top: 0, bottom: 0, width: 3, bgcolor: accent }} />
<Box sx={{ p: 1.5, pl: 2 }}>
{header}
{children}
{footer}
</Box>
</Paper>
);
MobileCard.propTypes = {
accent: PropTypes.string,
header: PropTypes.node,
footer: PropTypes.node,
selected: PropTypes.bool,
onClick: PropTypes.func,
children: PropTypes.node,
sx: PropTypes.object
};
// Grid wrapper for MobileField cells. Two columns by default; pass `columns`
// to change. Keeps every card's body alignment identical.
export const MobileFieldGrid = ({ children, columns = 2, sx }) => (
<Box
sx={{
display: 'grid',
gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
gap: 1,
mt: 1.25,
...sx
}}
>
{children}
</Box>
);
MobileFieldGrid.propTypes = {
children: PropTypes.node,
columns: PropTypes.number,
sx: PropTypes.object
};
// A single label/value cell. `full` makes it span the whole row; `value` can be
// a string/number or any node (chip, stack, etc.).
export const MobileField = ({ label, value, children, full = false, align = 'left' }) => (
<Box sx={{ gridColumn: full ? '1 / -1' : 'auto', minWidth: 0, textAlign: align }}>
<Typography
sx={{
fontSize: 9.5,
fontWeight: 800,
letterSpacing: 0.5,
textTransform: 'uppercase',
color: MUTED,
lineHeight: 1.4
}}
>
{label}
</Typography>
<Box sx={{ mt: 0.25, minWidth: 0 }}>
{children !== undefined ? (
children
) : (
<Typography sx={{ fontSize: 13, fontWeight: 600, color: PRIMARY_TEXT }} noWrap>
{value ?? '—'}
</Typography>
)}
</Box>
</Box>
);
MobileField.propTypes = {
label: PropTypes.node,
value: PropTypes.node,
children: PropTypes.node,
full: PropTypes.bool,
align: PropTypes.string
};