updates on the profitability
This commit is contained in:
@@ -2238,7 +2238,7 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
transition: color 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
|
transition: color 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
appearance: none;
|
appearance: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dispatch-container .trip-sort-pill svg {
|
.dispatch-container .trip-sort-pill svg {
|
||||||
@@ -2275,13 +2275,11 @@
|
|||||||
/* Mode-semantic accent on the active pill's icon — picks up the same
|
/* Mode-semantic accent on the active pill's icon — picks up the same
|
||||||
indigo / emerald used on the Compare control + the time-rank badge
|
indigo / emerald used on the Compare control + the time-rank badge
|
||||||
below, so the page reads as a coherent system. */
|
below, so the page reads as a coherent system. */
|
||||||
.dispatch-container .trip-sort-toggle[data-mode='planned']
|
.dispatch-container .trip-sort-toggle[data-mode='planned'] .trip-sort-pill.is-active svg {
|
||||||
.trip-sort-pill.is-active svg {
|
|
||||||
color: #662582;
|
color: #662582;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dispatch-container .trip-sort-toggle[data-mode='time']
|
.dispatch-container .trip-sort-toggle[data-mode='time'] .trip-sort-pill.is-active svg {
|
||||||
.trip-sort-pill.is-active svg {
|
|
||||||
color: #10b981;
|
color: #10b981;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9598,8 +9596,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@keyframes da-live-pulse {
|
@keyframes da-live-pulse {
|
||||||
0%, 100% { opacity: 1; transform: scale(1); }
|
|
||||||
50% { opacity: 0.4; transform: scale(0.85); }
|
0%,
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
opacity: 0.4;
|
||||||
|
transform: scale(0.85);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dispatch-container .da-metric-grid {
|
.dispatch-container .da-metric-grid {
|
||||||
@@ -10011,8 +10018,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@keyframes da-pos-fade {
|
@keyframes da-pos-fade {
|
||||||
from { opacity: 0; }
|
from {
|
||||||
to { opacity: 1; }
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dispatch-container .da-pos-modal-card {
|
.dispatch-container .da-pos-modal-card {
|
||||||
@@ -10030,8 +10042,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@keyframes da-pos-rise {
|
@keyframes da-pos-rise {
|
||||||
from { opacity: 0; transform: translateY(12px) scale(0.98); }
|
from {
|
||||||
to { opacity: 1; transform: translateY(0) scale(1); }
|
opacity: 0;
|
||||||
|
transform: translateY(12px) scale(0.98);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0) scale(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dispatch-container .da-pos-modal-head {
|
.dispatch-container .da-pos-modal-head {
|
||||||
@@ -10652,11 +10671,9 @@
|
|||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
background-image:
|
background-image:
|
||||||
repeating-linear-gradient(
|
repeating-linear-gradient(135deg,
|
||||||
135deg,
|
|
||||||
#e2e8f0 0 6px,
|
#e2e8f0 0 6px,
|
||||||
#f1f5f9 6px 12px
|
#f1f5f9 6px 12px);
|
||||||
);
|
|
||||||
border-left: 1px dashed #cbd5e1;
|
border-left: 1px dashed #cbd5e1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10900,6 +10917,7 @@
|
|||||||
(≥ md) is untouched; every rule here is gated inside this media query.
|
(≥ md) is untouched; every rule here is gated inside this media query.
|
||||||
========================================================================= */
|
========================================================================= */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
|
|
||||||
/* The standalone page un-does MainCard's 24px padding via negative margin
|
/* The standalone page un-does MainCard's 24px padding via negative margin
|
||||||
+ 100vw-ish sizing; keep that, just allow the inner body to grow with
|
+ 100vw-ish sizing; keep that, just allow the inner body to grow with
|
||||||
its stacked children instead of being clipped to a single row height. */
|
its stacked children instead of being clipped to a single row height. */
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ body {
|
|||||||
Fixed architecture: NO overflow, NO clipping, NO width:100vw
|
Fixed architecture: NO overflow, NO clipping, NO width:100vw
|
||||||
════════════════════════════════════════════════════════════════════════════ */
|
════════════════════════════════════════════════════════════════════════════ */
|
||||||
|
|
||||||
.profitability-dashboard {
|
.dispatch-container .profitability-dashboard {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
@@ -126,7 +126,7 @@ body {
|
|||||||
HEADER SECTION — Premium Top Header
|
HEADER SECTION — Premium Top Header
|
||||||
════════════════════════════════════════════════════════════════════════════ */
|
════════════════════════════════════════════════════════════════════════════ */
|
||||||
|
|
||||||
.profitability-header {
|
.profitability-dashboard .profitability-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|
||||||
@@ -252,7 +252,7 @@ body {
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profitability-kpi-chip {
|
.profitability-dashboard .profitability-kpi-chip {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--space-md);
|
gap: var(--space-md);
|
||||||
@@ -329,7 +329,7 @@ body {
|
|||||||
════════════════════════════════════════════════════════════════════════════ */
|
════════════════════════════════════════════════════════════════════════════ */
|
||||||
|
|
||||||
/* Enhanced KPI card interactions */
|
/* Enhanced KPI card interactions */
|
||||||
.profitability-summary-card {
|
.profitability-dashboard .profitability-summary-card {
|
||||||
position: relative;
|
position: relative;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
@@ -404,6 +404,7 @@ body {
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: scaleY(0.95);
|
transform: scaleY(0.95);
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: scaleY(1);
|
transform: scaleY(1);
|
||||||
@@ -549,7 +550,7 @@ body {
|
|||||||
CONTROLS BAR — Search, Filter, Sort
|
CONTROLS BAR — Search, Filter, Sort
|
||||||
════════════════════════════════════════════════════════════════════════════ */
|
════════════════════════════════════════════════════════════════════════════ */
|
||||||
|
|
||||||
.profitability-controls-bar {
|
.profitability-dashboard .profitability-controls-bar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|
||||||
@@ -588,7 +589,7 @@ body {
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profitability-search-input {
|
.profitability-dashboard .profitability-search-input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
|
|
||||||
@@ -619,7 +620,7 @@ body {
|
|||||||
box-shadow: 0 0 0 3px rgba(108, 76, 241, 0.1);
|
box-shadow: 0 0 0 3px rgba(108, 76, 241, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.profitability-search-input:focus ~ .profitability-search-icon {
|
.profitability-search-input:focus~.profitability-search-icon {
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -633,7 +634,7 @@ body {
|
|||||||
border: 1px solid var(--border-light);
|
border: 1px solid var(--border-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
.profitability-tab-btn {
|
.profitability-dashboard .profitability-tab-btn {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -696,7 +697,7 @@ body {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profitability-sort-select {
|
.profitability-dashboard .profitability-sort-select {
|
||||||
height: 40px;
|
height: 40px;
|
||||||
padding: 0 32px 0 var(--space-md);
|
padding: 0 32px 0 var(--space-md);
|
||||||
|
|
||||||
@@ -790,7 +791,7 @@ body {
|
|||||||
RIDER CARD — Modern Enterprise SaaS Card
|
RIDER CARD — Modern Enterprise SaaS Card
|
||||||
════════════════════════════════════════════════════════════════════════════ */
|
════════════════════════════════════════════════════════════════════════════ */
|
||||||
|
|
||||||
.rider-profitability-card {
|
.profitability-dashboard .rider-profitability-card {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
@@ -825,7 +826,7 @@ body {
|
|||||||
box-shadow: 0 0 0 2px var(--primary-light), var(--shadow-md);
|
box-shadow: 0 0 0 2px var(--primary-light), var(--shadow-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
.rider-card-header {
|
.profitability-dashboard .rider-card-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--space-lg);
|
gap: var(--space-lg);
|
||||||
@@ -1043,13 +1044,14 @@ body {
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(-8px);
|
transform: translateY(-8px);
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.rider-detail-inner {
|
.profitability-dashboard .rider-detail-inner {
|
||||||
padding: var(--space-lg);
|
padding: var(--space-lg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1060,7 +1062,7 @@ body {
|
|||||||
margin-bottom: var(--space-xl);
|
margin-bottom: var(--space-xl);
|
||||||
}
|
}
|
||||||
|
|
||||||
.cost-tile {
|
.profitability-dashboard .cost-tile {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--space-md);
|
gap: var(--space-md);
|
||||||
padding: var(--space-lg);
|
padding: var(--space-lg);
|
||||||
@@ -1170,7 +1172,7 @@ body {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.revenue-breakdown-header {
|
.profitability-dashboard .revenue-breakdown-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@@ -1211,7 +1213,7 @@ body {
|
|||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
.orders-table thead th {
|
.profitability-dashboard .orders-table thead th {
|
||||||
padding: var(--space-md) var(--space-lg);
|
padding: var(--space-md) var(--space-lg);
|
||||||
text-align: left;
|
text-align: left;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
@@ -1237,7 +1239,7 @@ body {
|
|||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.orders-table tbody td {
|
.profitability-dashboard .orders-table tbody td {
|
||||||
padding: var(--space-md) var(--space-lg);
|
padding: var(--space-md) var(--space-lg);
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
@@ -1495,7 +1497,7 @@ body {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profitability-kpi-chip {
|
.profitability-dashboard .profitability-kpi-chip {
|
||||||
padding: var(--space-sm) var(--space-md);
|
padding: var(--space-sm) var(--space-md);
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
@@ -1504,7 +1506,7 @@ body {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profitability-summary-card {
|
.profitability-dashboard .profitability-summary-card {
|
||||||
padding: var(--space-lg);
|
padding: var(--space-lg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -125,94 +125,94 @@ const RidersLogs = () => {
|
|||||||
{/* Individuals */}
|
{/* Individuals */}
|
||||||
{ridersIsLoading || riderIsFetching
|
{ridersIsLoading || riderIsFetching
|
||||||
? Array.from({ length: 10 }).map((_, index) => (
|
? Array.from({ length: 10 }).map((_, index) => (
|
||||||
<Fragment key={index}>
|
<Fragment key={index}>
|
||||||
<ListItem sx={{ py: 1.5, px: 2 }}>
|
<ListItem sx={{ py: 1.5, px: 2 }}>
|
||||||
|
<ListItemAvatar>
|
||||||
|
<Skeleton variant="circular" width={24} height={24} />
|
||||||
|
</ListItemAvatar>
|
||||||
|
|
||||||
|
<ListItemText
|
||||||
|
primary={<Skeleton variant="text" width="60%" height={22} />}
|
||||||
|
secondary={<Skeleton variant="text" width="40%" height={18} />}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Stack spacing={0.5} textAlign="right">
|
||||||
|
<Skeleton variant="text" width={50} height={18} />
|
||||||
|
<Skeleton variant="text" width={80} height={16} />
|
||||||
|
</Stack>
|
||||||
|
</ListItem>
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
</Fragment>
|
||||||
|
))
|
||||||
|
: !isMobile &&
|
||||||
|
riders?.map((row) => {
|
||||||
|
return (
|
||||||
|
<Fragment key={row.userid}>
|
||||||
|
<ListItem
|
||||||
|
sx={{
|
||||||
|
cursor: 'pointer',
|
||||||
|
py: 1,
|
||||||
|
px: 2,
|
||||||
|
borderRadius: 1,
|
||||||
|
'&:hover': { bgcolor: theme.palette.secondary.lighter }
|
||||||
|
}}
|
||||||
|
secondaryAction={
|
||||||
|
<Stack textAlign="right" spacing={0.5}>
|
||||||
|
<Typography variant="body2" noWrap sx={{ color: row.status == 'active' ? 'success.main' : 'error.main' }}>
|
||||||
|
{row.userid}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="caption" color="text.secondary" noWrap>
|
||||||
|
{dayjs(row.logdate).format('DD/MM/YYYY hh:mm A')}
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
}
|
||||||
|
>
|
||||||
<ListItemAvatar>
|
<ListItemAvatar>
|
||||||
<Skeleton variant="circular" width={24} height={24} />
|
<Checkbox
|
||||||
|
sx={{
|
||||||
|
color: row.status == 'active' ? 'green' : 'red',
|
||||||
|
'&.Mui-checked': {
|
||||||
|
color: row.status == 'active' ? 'green' : 'red'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
checked={
|
||||||
|
// INDIVIDUAL CHECKED CONDITION
|
||||||
|
selectedRiders?.length === 1 && selectedRiders[0]?.userid === row?.userid
|
||||||
|
}
|
||||||
|
onChange={(e) => {
|
||||||
|
if (e.target.checked) {
|
||||||
|
// SELECT ONE RIDER
|
||||||
|
setSelectedRiders([row]);
|
||||||
|
} else {
|
||||||
|
// UNCHECK -> SELECT ALL
|
||||||
|
setSelectedRiders(riders);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</ListItemAvatar>
|
</ListItemAvatar>
|
||||||
|
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={<Skeleton variant="text" width="60%" height={22} />}
|
primary={
|
||||||
secondary={<Skeleton variant="text" width="40%" height={18} />}
|
<Typography noWrap>
|
||||||
/>
|
{row.username?.slice(0, 25) || ''}
|
||||||
|
{row.username?.length > 25 && '...'}
|
||||||
|
|
||||||
<Stack spacing={0.5} textAlign="right">
|
{/* {row.status === 'active' && <TaskAltIcon fontSize="small" color="success" sx={{ ml: 1 }} />} */}
|
||||||
<Skeleton variant="text" width={50} height={18} />
|
</Typography>
|
||||||
<Skeleton variant="text" width={80} height={16} />
|
}
|
||||||
</Stack>
|
secondary={
|
||||||
|
<Typography variant="caption" color="text.secondary" noWrap>
|
||||||
|
{row.contactno || '##########'}
|
||||||
|
</Typography>
|
||||||
|
}
|
||||||
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
</Fragment>
|
</Fragment>
|
||||||
))
|
);
|
||||||
: !isMobile &&
|
})}
|
||||||
riders?.map((row) => {
|
|
||||||
return (
|
|
||||||
<Fragment key={row.userid}>
|
|
||||||
<ListItem
|
|
||||||
sx={{
|
|
||||||
cursor: 'pointer',
|
|
||||||
py: 1,
|
|
||||||
px: 2,
|
|
||||||
borderRadius: 1,
|
|
||||||
'&:hover': { bgcolor: theme.palette.secondary.lighter }
|
|
||||||
}}
|
|
||||||
secondaryAction={
|
|
||||||
<Stack textAlign="right" spacing={0.5}>
|
|
||||||
<Typography variant="body2" noWrap sx={{ color: row.status == 'active' ? 'success.main' : 'error.main' }}>
|
|
||||||
{row.userid}
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="caption" color="text.secondary" noWrap>
|
|
||||||
{dayjs(row.logdate).format('DD/MM/YYYY hh:mm A')}
|
|
||||||
</Typography>
|
|
||||||
</Stack>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<ListItemAvatar>
|
|
||||||
<Checkbox
|
|
||||||
sx={{
|
|
||||||
color: row.status == 'active' ? 'green' : 'red',
|
|
||||||
'&.Mui-checked': {
|
|
||||||
color: row.status == 'active' ? 'green' : 'red'
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
checked={
|
|
||||||
// INDIVIDUAL CHECKED CONDITION
|
|
||||||
selectedRiders?.length === 1 && selectedRiders[0]?.userid === row?.userid
|
|
||||||
}
|
|
||||||
onChange={(e) => {
|
|
||||||
if (e.target.checked) {
|
|
||||||
// SELECT ONE RIDER
|
|
||||||
setSelectedRiders([row]);
|
|
||||||
} else {
|
|
||||||
// UNCHECK -> SELECT ALL
|
|
||||||
setSelectedRiders(riders);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</ListItemAvatar>
|
|
||||||
|
|
||||||
<ListItemText
|
|
||||||
primary={
|
|
||||||
<Typography noWrap>
|
|
||||||
{row.username?.slice(0, 25) || ''}
|
|
||||||
{row.username?.length > 25 && '...'}
|
|
||||||
|
|
||||||
{/* {row.status === 'active' && <TaskAltIcon fontSize="small" color="success" sx={{ ml: 1 }} />} */}
|
|
||||||
</Typography>
|
|
||||||
}
|
|
||||||
secondary={
|
|
||||||
<Typography variant="caption" color="text.secondary" noWrap>
|
|
||||||
{row.contactno || '##########'}
|
|
||||||
</Typography>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</ListItem>
|
|
||||||
|
|
||||||
<Divider />
|
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</List>
|
</List>
|
||||||
|
|
||||||
{/* Mobile: rider rows rendered as app-style cards (same selection behaviour) */}
|
{/* Mobile: rider rows rendered as app-style cards (same selection behaviour) */}
|
||||||
|
|||||||
Reference in New Issue
Block a user