diff --git a/src/pages/nearle/dispatch/ProfitabilitySection.css b/src/pages/nearle/dispatch/ProfitabilitySection.css index 4bdfd39..65939bc 100644 --- a/src/pages/nearle/dispatch/ProfitabilitySection.css +++ b/src/pages/nearle/dispatch/ProfitabilitySection.css @@ -319,7 +319,7 @@ body { max-width: 100%; display: grid; - grid-template-columns: repeat(4, minmax(0, 1fr)); + grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--space-xl); margin-bottom: var(--space-lg); @@ -338,9 +338,9 @@ body { display: flex; flex-direction: column; - gap: var(--space-md); + gap: 6px; - padding: var(--space-2xl); + padding: 12px 16px; background: var(--bg-card); border: 1px solid var(--border); @@ -508,10 +508,10 @@ body { } .profitability-summary-value { - font-size: clamp(28px, 3vw, 42px); + font-size: clamp(20px, 2.2vw, 24px); font-weight: 800; color: var(--text-primary); - letter-spacing: -0.04em; + letter-spacing: -0.02em; line-height: 1; margin: 0; overflow-wrap: break-word; @@ -1390,10 +1390,10 @@ body { } } -/* LAPTOP: 1280px - 4-column still works */ +/* LAPTOP: 1280px - 5-column works since cards are smaller */ @media (max-width: 1440px) { .profitability-summary-row { - grid-template-columns: repeat(4, minmax(0, 1fr)); + grid-template-columns: repeat(5, minmax(0, 1fr)); } } diff --git a/src/pages/nearle/dispatch/ProfitabilitySection.js b/src/pages/nearle/dispatch/ProfitabilitySection.js index a8ea3da..357e6bd 100644 --- a/src/pages/nearle/dispatch/ProfitabilitySection.js +++ b/src/pages/nearle/dispatch/ProfitabilitySection.js @@ -441,6 +441,7 @@ export default function ProfitabilitySection({ const slotRevenue = activeEnriched.reduce((s, r) => s + r._m.revenue, 0); const slotCost = activeEnriched.reduce((s, r) => s + r._m.totalCost, 0); const slotNet = activeEnriched.reduce((s, r) => s + r._m.net, 0); + const slotKms = activeEnriched.reduce((s, r) => s + r._m.kms, 0); const profitCount = activeEnriched.filter((r) => r._m.net >= 0).length; const lossCount = activeEnriched.length - profitCount; @@ -525,6 +526,11 @@ export default function ProfitabilitySection({ {profitCount} in profit · {lossCount} at loss +
+ Total Distance + {slotKms.toFixed(1)} km + Cumulative travel distance +
Slot Revenue {rupees(slotRevenue)} diff --git a/src/pages/nearle/reports/profitability.js b/src/pages/nearle/reports/profitability.js index 2ad15fd..f811ec0 100644 --- a/src/pages/nearle/reports/profitability.js +++ b/src/pages/nearle/reports/profitability.js @@ -286,6 +286,7 @@ export default function ProfitabilityReport() { let totalCost = 0; let profitableRiders = 0; let lossRiders = 0; + let totalKms = 0; const list = ridersList .map((r) => { @@ -341,6 +342,7 @@ export default function ProfitabilityReport() { totalOrders += ordersInSlots; totalRevenue += rRevenue; totalCost += rTotalCost; + totalKms += rKms; activeRiders++; return { @@ -368,6 +370,7 @@ export default function ProfitabilityReport() { totalMargin, profitableRiders, lossRiders, + totalKms, enrichedRiders: list }; }, [ridersList, customBatches]); @@ -392,6 +395,14 @@ export default function ProfitabilityReport() { value: stats?.activeRiders ?? 0, detail: `${stats?.profitableRiders ?? 0} in profit · ${stats?.lossRiders ?? 0} at loss` }, + { + key: 'kms', + label: 'Total Distance', + color: '#10b981', + icon: MdStraighten, + value: `${(stats?.totalKms ?? 0).toFixed(1)} km`, + detail: 'Cumulative travel distance' + }, { key: 'revenue', label: 'Slot Revenue', @@ -449,7 +460,7 @@ export default function ProfitabilityReport() { {KPI_META.map((item) => { const Icon = item.icon; return ( - +