/* Transport — live bus tracking */
function MapCanvas() {
const STOPS = [
{ id:1, x:'40%', y:'52%', name:'Cypress Trace', time:'3:12 PM', done:true },
{ id:2, x:'63%', y:'33%', name:'Morton Ranch Rd', time:'3:20 PM', done:false, next:true },
{ id:3, x:'10%', y:'86%', name:'Your stop · Home', time:'3:25 PM', done:false },
];
const [sel, setSel] = React.useState(2);
const cur = STOPS.find(s => s.id === sel);
return (
{/* route line */}
{/* animated bus traveling the route */}
{/* tappable stops */}
{STOPS.map(s => {
const on = s.id === sel;
return (
);
})}
{/* stop detail chip */}
{cur.name}
{cur.done ? 'Arrived' : 'ETA'} · {cur.time}
{cur.next &&
NEXT STOP}
);
}
function TransportScreen({ onNav, onBack }) {
const [notify, setNotify] = React.useState(false);
const [reportOpen, setReportOpen] = React.useState(false);
const [reported, setReported] = React.useState(false);
const [reason, setReason] = React.useState('Stayed after class');
const REASONS = ['Stayed after class', 'Running late', 'Felt sick', 'Other'];
const scans = [
{ n:'EJ Hatten', t:'3:05 PM', c:'green', done:true },
{ n:'James Walker', t:'3:07 PM', c:'blue', done:true },
{ n:'Sophia Perez', t:'3:08 PM', c:'gold', done:true },
];
return (
{/* missed-bus confirmation banner */}
{reported && (
School & family notified
EJ missed Bus #12 · {reason}
)}
{/* driver */}
{/* live source attribution */}
Live from driver's phone GPS · updated just now
{/* next stop / ETA */}
NEXT STOP
Morton Ranch Rd
{/* notify toggle */}
{/* missed the bus */}
{/* scanned students */}
On Board
{scans.map((s,i)=>(
{i>0 && }
w[0]).join('')} color={s.c} size={38} />
))}
{/* bottom sheet: report missed bus */}
{reportOpen && (
setReportOpen(false)} style={{ position:'absolute', inset:0, zIndex:60, background:'rgba(10,20,40,.4)', display:'flex', alignItems:'flex-end' }}>
e.stopPropagation()} style={{ width:'100%', background:'#fff', borderRadius:'22px 22px 0 0', padding:'10px 18px 34px' }}>
Report Missed Bus
EJ Hatten · Bus #12
We'll instantly notify the school office and your family so someone can arrange a safe pickup.
What happened?
{REASONS.map(r => {
const on = r===reason;
return (
);
})}
Notifies Katy Middle office & Ashley Hatten
)}
);
}
Object.assign(window, { TransportScreen, MapCanvas });