updated the ui for the mobile view
This commit is contained in:
@@ -22,7 +22,9 @@ import {
|
||||
TableHead,
|
||||
TableRow,
|
||||
Tooltip,
|
||||
Typography
|
||||
Typography,
|
||||
useMediaQuery,
|
||||
useTheme
|
||||
} from '@mui/material';
|
||||
import {
|
||||
MdDirectionsBike,
|
||||
@@ -53,6 +55,7 @@ import DebounceSearchBar from 'components/nearle_components/DebounceSearchBar';
|
||||
import { OrdersTableSkeleton } from '../orders/OrdersTableSkeleton';
|
||||
import RidersRoutes from './RidersRoutes';
|
||||
import { OpenToast } from 'components/third-party/OpenToast';
|
||||
import { MobileCard, MobileCardList, MobileField, MobileFieldGrid } from 'components/nearle_components/MobileCard';
|
||||
|
||||
// ============================================================================
|
||||
// Design tokens — shared with deliveries / tenants / customers / pricing /
|
||||
@@ -182,6 +185,9 @@ function formatNumberToRupees(value) {
|
||||
// ==============================|| Riders Summary ||============================== //
|
||||
|
||||
export default function RidersSummary() {
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
||||
|
||||
const [startdate, setStartdate] = useState(dayjs().format('YYYY-MM-DD'));
|
||||
const [enddate, setEnddate] = useState(dayjs().format('YYYY-MM-DD'));
|
||||
const [locaName, setLocoName] = useState('All');
|
||||
@@ -584,6 +590,249 @@ export default function RidersSummary() {
|
||||
background: '#fff'
|
||||
}}
|
||||
>
|
||||
{isMobile ? (
|
||||
<MobileCardList scroll>
|
||||
{isLoadingReports && (
|
||||
<Stack alignItems="center" sx={{ py: 4 }}>
|
||||
<Typography variant="caption" sx={{ color: DT.textMuted, fontWeight: 700 }}>
|
||||
Loading riders…
|
||||
</Typography>
|
||||
</Stack>
|
||||
)}
|
||||
{(!filteredRows || filteredRows.length === 0) && !isLoadingReports ? (
|
||||
<Stack alignItems="center" spacing={1.5} sx={{ py: 6 }}>
|
||||
<Avatar sx={{ width: 64, height: 64, bgcolor: soft('#94a3b8'), color: DT.textMuted }}>
|
||||
<MdDirectionsBike size={28} />
|
||||
</Avatar>
|
||||
<Typography variant="subtitle1" sx={{ fontWeight: 700, color: DT.textPrimary }}>
|
||||
No riders to show
|
||||
</Typography>
|
||||
<Typography variant="caption" sx={{ color: DT.textSecondary }}>
|
||||
{searchword ? 'Try a different keyword.' : 'Pick a zone or date range to load the summary.'}
|
||||
</Typography>
|
||||
</Stack>
|
||||
) : (
|
||||
filteredRows.map((row, index) => {
|
||||
const isOpen = openRow === row.userid;
|
||||
const amount = Math.max(Number(row.charges) || 0, Number(row.deliveryamt) || 0);
|
||||
const riderName = `${row?.firstname || ''} ${row?.lastname || ''}`.trim() || '—';
|
||||
return (
|
||||
<MobileCard
|
||||
key={row.userid || index}
|
||||
accent={BRAND}
|
||||
selected={isOpen}
|
||||
header={
|
||||
<Stack direction="row" alignItems="center" justifyContent="space-between" spacing={1}>
|
||||
<Stack direction="row" alignItems="center" spacing={1} sx={{ minWidth: 0 }}>
|
||||
<AccentAvatar color={BRAND} size={36}>
|
||||
<MdPerson size={18} />
|
||||
</AccentAvatar>
|
||||
<Stack sx={{ minWidth: 0 }}>
|
||||
<Typography variant="subtitle2" sx={{ fontWeight: 700, color: DT.textPrimary }} noWrap>
|
||||
{riderName}
|
||||
</Typography>
|
||||
<Typography variant="caption" sx={{ color: DT.textSecondary }}>
|
||||
#{String(index + 1).padStart(2, '0')} · ID #{row.userid}
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Stack>
|
||||
<Stack direction="row" spacing={0.75} sx={{ flexShrink: 0 }}>
|
||||
<Tooltip title="View planned route" placement="top">
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() => {
|
||||
setSelectedRider({
|
||||
userid: row?.userid,
|
||||
name: `${row?.firstname || ''} ${row?.lastname || ''}`.trim() || `Rider ${row?.userid}`
|
||||
});
|
||||
setLogDetails(null);
|
||||
setMapOpen(true);
|
||||
getuserdeliverylogs(row?.userid);
|
||||
}}
|
||||
sx={{
|
||||
bgcolor: soft('#0ea5e9'),
|
||||
color: '#0ea5e9',
|
||||
border: `1px solid ${edge('#0ea5e9')}`,
|
||||
'&:hover': { bgcolor: '#0ea5e9', color: '#fff' }
|
||||
}}
|
||||
>
|
||||
<MdMap size={14} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title={isOpen ? 'Collapse breakdown' : 'Expand breakdown'} placement="top">
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() => {
|
||||
const isOpening = !isOpen;
|
||||
setOpenRow(isOpening ? row.userid : null);
|
||||
if (isOpening) fetchTenantSummary(row.userid);
|
||||
}}
|
||||
sx={{
|
||||
bgcolor: isOpen ? BRAND : soft(BRAND),
|
||||
color: isOpen ? '#fff' : BRAND,
|
||||
border: `1px solid ${edge(BRAND)}`,
|
||||
'&:hover': { bgcolor: BRAND, color: '#fff' }
|
||||
}}
|
||||
>
|
||||
{isOpen ? <MdExpandLess size={16} /> : <MdExpandMore size={16} />}
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Stack>
|
||||
</Stack>
|
||||
}
|
||||
>
|
||||
<MobileFieldGrid columns={2}>
|
||||
<MobileField label="Orders">
|
||||
<CountCell value={row.totalorders} color={BRAND} icon={<MdLocalShipping size={11} />} />
|
||||
</MobileField>
|
||||
<MobileField label="Delivered">
|
||||
<CountCell value={row.delivered} color="#10b981" icon={<MdCheckCircle size={11} />} />
|
||||
</MobileField>
|
||||
<MobileField label="Pending">
|
||||
<CountCell value={row.pending} color="#f59e0b" icon={<MdHourglassEmpty size={11} />} />
|
||||
</MobileField>
|
||||
<MobileField label="Cancelled">
|
||||
<CountCell value={row.cancelled} color="#ef4444" icon={<MdCancel size={11} />} />
|
||||
</MobileField>
|
||||
<MobileField label="KMS">
|
||||
<MetricPill
|
||||
color="#ef4444"
|
||||
icon={<MdStraighten size={11} />}
|
||||
label={`${Number(row.kms || 0).toFixed(2)} km`}
|
||||
tooltip="KMS"
|
||||
/>
|
||||
</MobileField>
|
||||
<MobileField label="Actual KMS">
|
||||
<MetricPill
|
||||
color="#10b981"
|
||||
icon={<MdStraighten size={11} />}
|
||||
label={`${Number(row.cumulativekms || 0).toFixed(2)} km`}
|
||||
tooltip="Actual KMS"
|
||||
/>
|
||||
</MobileField>
|
||||
<MobileField label="Amount" full>
|
||||
<MetricPill
|
||||
color={BRAND}
|
||||
icon={<MdCurrencyRupee size={11} />}
|
||||
label={formatNumberToRupees(amount).replace('₹', '').trim()}
|
||||
tooltip="Total Amount"
|
||||
minWidth={100}
|
||||
/>
|
||||
</MobileField>
|
||||
</MobileFieldGrid>
|
||||
|
||||
{/* per-tenant breakdown */}
|
||||
{isOpen && (
|
||||
<Collapse in={isOpen} timeout="auto" unmountOnExit>
|
||||
<Paper
|
||||
elevation={0}
|
||||
sx={{
|
||||
mt: 1.25,
|
||||
borderRadius: DT.radiusCard / 8,
|
||||
border: '1px solid',
|
||||
borderColor: DT.borderSubtle,
|
||||
overflow: 'hidden',
|
||||
boxShadow: DT.shadowSoft
|
||||
}}
|
||||
>
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
spacing={1}
|
||||
sx={{
|
||||
px: 1.5,
|
||||
py: 1,
|
||||
background: `linear-gradient(135deg, ${tint(BRAND)} 0%, ${tint(BRAND_LIGHT)} 100%)`,
|
||||
borderBottom: `1px solid ${DT.borderSubtle}`
|
||||
}}
|
||||
>
|
||||
<AccentAvatar color={BRAND} size={24} selected>
|
||||
<MdGroups size={12} />
|
||||
</AccentAvatar>
|
||||
<Typography
|
||||
variant="caption"
|
||||
sx={{ fontWeight: 800, color: DT.textPrimary, letterSpacing: 0.6, textTransform: 'uppercase' }}
|
||||
>
|
||||
Tenant Breakdown
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stack divider={<Divider />}>
|
||||
{loading && (
|
||||
<Typography variant="caption" sx={{ color: DT.textMuted, textAlign: 'center', py: 2 }}>
|
||||
Loading…
|
||||
</Typography>
|
||||
)}
|
||||
{!loading && (!tenantData || tenantData.length === 0) ? (
|
||||
<Typography variant="caption" sx={{ color: DT.textMuted, textAlign: 'center', py: 2 }}>
|
||||
No tenant breakdown available.
|
||||
</Typography>
|
||||
) : (
|
||||
tenantData?.map((sub, sidx) => (
|
||||
<Box key={`${sub.tenantname}-${sidx}`} sx={{ p: 1.5 }}>
|
||||
<Stack direction="row" alignItems="center" spacing={0.75} sx={{ mb: 1 }}>
|
||||
<AccentAvatar color="#0ea5e9" size={24}>
|
||||
<MdGroups size={12} />
|
||||
</AccentAvatar>
|
||||
<Typography variant="subtitle2" sx={{ fontWeight: 700, color: DT.textPrimary }} noWrap>
|
||||
{sub.tenantname || '—'}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<MobileFieldGrid columns={2}>
|
||||
<MobileField label="All">
|
||||
<CountCell value={sub.totalorders} color={BRAND} icon={<MdLocalShipping size={10} />} />
|
||||
</MobileField>
|
||||
<MobileField label="Completed">
|
||||
<CountCell value={sub.deliveriescompleted} color="#10b981" icon={<MdCheckCircle size={10} />} />
|
||||
</MobileField>
|
||||
<MobileField label="Pending">
|
||||
<CountCell value={sub.deliveriespending} color="#f59e0b" icon={<MdHourglassEmpty size={10} />} />
|
||||
</MobileField>
|
||||
<MobileField label="Cancelled">
|
||||
<CountCell value={sub.deliveriescancelled} color="#ef4444" icon={<MdCancel size={10} />} />
|
||||
</MobileField>
|
||||
<MobileField label="KMS">
|
||||
<MetricPill
|
||||
color="#ef4444"
|
||||
icon={<MdStraighten size={10} />}
|
||||
label={`${Number(sub.kms || 0).toFixed(2)} km`}
|
||||
tooltip="KMS"
|
||||
/>
|
||||
</MobileField>
|
||||
<MobileField label="Actual KMS">
|
||||
<MetricPill
|
||||
color="#10b981"
|
||||
icon={<MdStraighten size={10} />}
|
||||
label={`${Number(sub.cumulativekms || 0).toFixed(2)} km`}
|
||||
tooltip="Actual KMS"
|
||||
/>
|
||||
</MobileField>
|
||||
<MobileField label="Amount" full>
|
||||
<MetricPill
|
||||
color={BRAND}
|
||||
icon={<MdCurrencyRupee size={10} />}
|
||||
label={formatNumberToRupees(
|
||||
Math.max(Number(sub.charges) || 0, Number(sub.deliveryamt) || 0)
|
||||
)
|
||||
.replace('₹', '')
|
||||
.trim()}
|
||||
tooltip="Total Amount"
|
||||
minWidth={100}
|
||||
/>
|
||||
</MobileField>
|
||||
</MobileFieldGrid>
|
||||
</Box>
|
||||
))
|
||||
)}
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Collapse>
|
||||
)}
|
||||
</MobileCard>
|
||||
);
|
||||
})
|
||||
)}
|
||||
</MobileCardList>
|
||||
) : (
|
||||
<TableContainer
|
||||
sx={{
|
||||
maxHeight: { xs: 'calc(100vh - 220px)', md: 'calc(100vh - 190px)' },
|
||||
@@ -940,6 +1189,7 @@ export default function RidersSummary() {
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
)}
|
||||
|
||||
{/* ============================================= || Total Bar || ============================================= */}
|
||||
{filteredRows.length > 0 && (
|
||||
|
||||
Reference in New Issue
Block a user