| import React, { useState, useEffect } from 'react'; |
| import * as API from '../api.js'; |
|
|
| export default function DispatchMapView({ onBack }) { |
| const [data, setData] = useState(null); |
| const [loading, setLoading] = useState(true); |
| const [dispatchMode, setDispatchMode] = useState('batched'); |
|
|
| useEffect(() => { |
| API.analyzeDispatch().then((res) => { |
| if (res) setData(res); |
| setLoading(false); |
| }); |
| }, []); |
|
|
| return ( |
| <div className="min-h-screen bg-[#07070B] text-white p-6 md:p-12 font-sans selection:bg-[#FF3366]"> |
| |
| {/* Top Header */} |
| <div className="max-w-6xl mx-auto flex items-center justify-between mb-8 pb-6 border-b border-white/10"> |
| <div className="flex items-center gap-4"> |
| <button |
| onClick={onBack} |
| className="p-2.5 rounded-full bg-white/[0.05] border border-white/15 text-white/80 hover:text-white hover:bg-white/10 transition-all cursor-pointer" |
| > |
| <span className="material-symbols-outlined text-xl">arrow_back</span> |
| </button> |
| <div> |
| <div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-[#00D4FF]/10 border border-[#00D4FF]/30 mb-1"> |
| <span className="w-2 h-2 rounded-full bg-[#00D4FF] animate-pulse"></span> |
| <span className="text-[10px] font-bold tracking-widest text-[#00D4FF] uppercase">MODULE 5 β’ ROUTE BATCH OPTIMIZER</span> |
| </div> |
| <h1 className="text-3xl md:text-4xl font-serif font-bold text-white tracking-tight"> |
| Dispatch Intelligence <span className="italic font-serif text-[#00D4FF]">Optimized.</span> |
| </h1> |
| </div> |
| </div> |
| </div> |
| |
| {/* Industry Differentiation Showcase Card */} |
| <div className="max-w-6xl mx-auto mb-8 bg-[#101018]/90 border border-white/10 rounded-3xl p-6 backdrop-blur-2xl space-y-4"> |
| <div className="flex flex-col md:flex-row items-start md:items-center justify-between gap-4"> |
| <div> |
| <div className="flex items-center gap-2 mb-1"> |
| <span className="text-xs font-bold font-mono text-[#00D4FF] uppercase tracking-wider">WHY HYPERFLOW VS INDUSTRY BASELINE</span> |
| <span className="px-2.5 py-0.5 rounded-full text-[10px] font-bold bg-[#00D4FF]/20 text-[#00D4FF] border border-[#00D4FF]/30"> |
| 28.4% FUEL SAVED Β· ~14M FASTER |
| </span> |
| </div> |
| <h3 className="text-lg font-serif font-bold text-white">Haversine Batch Clustering vs Greedy Individual Dispatch</h3> |
| <p className="text-xs text-white/60 font-light max-w-2xl mt-1"> |
| Standard logistics dispatches riders 1-to-1 per order, creating severe traffic congestion and high delivery costs. HyperFlow clusters nearby spatial-temporal delivery destinations within strict SLA bounds. |
| </p> |
| </div> |
| |
| <div className="flex items-center gap-2 bg-white/[0.05] p-1.5 rounded-full border border-white/10 shrink-0"> |
| <button |
| onClick={() => setDispatchMode('batched')} |
| className={`px-4 py-1.5 rounded-full text-xs font-bold transition-all cursor-pointer ${ |
| dispatchMode === 'batched' |
| ? 'bg-gradient-to-r from-[#00D4FF] to-[#00E6FF] text-black shadow-md font-bold' |
| : 'text-white/60 hover:text-white' |
| }`} |
| > |
| HyperFlow Batched Route |
| </button> |
| <button |
| onClick={() => setDispatchMode('unbatched')} |
| className={`px-4 py-1.5 rounded-full text-xs font-bold transition-all cursor-pointer ${ |
| dispatchMode === 'unbatched' |
| ? 'bg-red-500/30 text-red-300 border border-red-500/50 shadow-md' |
| : 'text-white/60 hover:text-white' |
| }`} |
| > |
| Greedy 1-to-1 Dispatch |
| </button> |
| </div> |
| </div> |
| </div> |
| |
| <div className="max-w-6xl mx-auto space-y-6"> |
| <div className="bg-[#101018]/90 border border-white/10 rounded-3xl p-8 backdrop-blur-2xl space-y-6"> |
| <div className="grid grid-cols-1 sm:grid-cols-3 gap-6"> |
| <div className="p-5 bg-white/[0.03] border border-white/10 rounded-2xl"> |
| <span className="text-xs text-white/40 uppercase font-mono">TOTAL ORDERS</span> |
| <p className="text-3xl font-serif font-bold text-white mt-1">{data?.total_deliveries || 5} orders</p> |
| </div> |
| |
| <div className={`p-5 rounded-2xl border transition-all ${ |
| dispatchMode === 'batched' ? 'bg-[#00D4FF]/10 border-[#00D4FF]/30' : 'bg-red-500/10 border-red-500/30' |
| }`}> |
| <span className="text-xs uppercase font-mono font-bold" style={{ color: dispatchMode === 'batched' ? '#00D4FF' : '#EF4444' }}> |
| {dispatchMode === 'batched' ? 'OPTIMIZED BATCHES' : 'ACTIVE RIDERS NEEDED'} |
| </span> |
| <p className="text-3xl font-serif font-bold mt-1" style={{ color: dispatchMode === 'batched' ? '#00D4FF' : '#EF4444' }}> |
| {dispatchMode === 'batched' ? `${data?.optimized_batches_count || 2} routes` : `${data?.total_deliveries || 5} riders`} |
| </p> |
| </div> |
| |
| <div className="p-5 bg-emerald-500/10 border border-emerald-500/20 rounded-2xl"> |
| <span className="text-xs text-emerald-400 uppercase font-mono font-bold">ESTIMATED TIME SAVED</span> |
| <p className="text-3xl font-serif font-bold text-emerald-300 mt-1"> |
| {dispatchMode === 'batched' ? `~${data?.estimated_time_saved_min || 14} min` : '0 min (baseline)'} |
| </p> |
| </div> |
| </div> |
| |
| <div className="p-6 bg-white/[0.02] border border-white/10 rounded-2xl font-mono text-xs space-y-3"> |
| <p className="text-white/60 font-bold uppercase tracking-wider">HUB ORIGIN: Patia Warehouse [20.3533, 85.8333]</p> |
| <div className="space-y-2 text-white/80"> |
| {dispatchMode === 'batched' ? ( |
| <> |
| <div className="p-3 bg-white/[0.03] rounded-xl flex justify-between"> |
| <span>Route Batch 1: Patia Hub β Prasanti Vihar (20.3562, 85.8315) β Lp 60 (20.3585, 85.8288)</span> |
| <span className="text-[#00D4FF] font-bold">SLA: 18m</span> |
| </div> |
| <div className="p-3 bg-white/[0.03] rounded-xl flex justify-between"> |
| <span>Route Batch 2: Patia Hub β KIIT Campus 3 (20.3540, 85.8360) β Damana (20.3510, 85.8380)</span> |
| <span className="text-[#00D4FF] font-bold">SLA: 22m</span> |
| </div> |
| </> |
| ) : ( |
| <> |
| <div className="p-3 bg-red-500/10 border border-red-500/20 rounded-xl flex justify-between"> |
| <span>Single Rider 1: Patia Hub β Prasanti Vihar</span> |
| <span className="text-red-400 font-bold">SLA: 24m</span> |
| </div> |
| <div className="p-3 bg-red-500/10 border border-red-500/20 rounded-xl flex justify-between"> |
| <span>Single Rider 2: Patia Hub β Lp 60</span> |
| <span className="text-red-400 font-bold">SLA: 28m</span> |
| </div> |
| <div className="p-3 bg-red-500/10 border border-red-500/20 rounded-xl flex justify-between"> |
| <span>Single Rider 3: Patia Hub β KIIT Campus 3</span> |
| <span className="text-red-400 font-bold">SLA: 21m</span> |
| </div> |
| </> |
| )} |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| ); |
| } |
|
|