// ===== BICYCLES & E-BIKES =====
// ---------- Shared: hand signals data ----------
const bike_signals = [
{ id: 1, label: 'Turn left', desc: 'Left arm straight out', icon: '⬅️' },
{ id: 2, label: 'Turn right', desc: 'Right arm out, or left arm bent up', icon: '➡️' },
{ id: 3, label: 'Slowing / stop', desc: 'Left arm bent down, palm back', icon: '✋' },
{ id: 4, label: 'Hazard ahead', desc: 'Point down at the road hazard', icon: '👇' },
];
const bike_gear = [
{ id: 'helmet', icon: '🪖', label: 'Certified helmet', desc: 'Properly fastened, correct fit' },
{ id: 'lights', icon: '💡', label: 'Front & rear lights', desc: 'White front, red rear — esp. at night' },
{ id: 'reflect', icon: '🦺', label: 'Reflective vest / strips', desc: 'Be visible from all sides' },
{ id: 'bell', icon: '🔔', label: 'Working bell or horn', desc: 'Alert pedestrians & vehicles' },
{ id: 'brakes', icon: '🛑', label: 'Brakes checked', desc: 'Both brakes firm and responsive' },
{ id: 'tires', icon: '🛞', label: 'Tire pressure & tread', desc: 'Inflated, no cracks or bulges' },
];
const bike_rules = [
{ id: 1, cat: 'Use the bike lane', icon: '🛣️', rules: [
'Ride in designated bike lanes where provided (per local bike-lane ordinances)',
'Where no lane exists, keep to the rightmost part of the road',
'Ride in single file on busy roads; max two abreast on quiet ones',
]},
{ id: 2, cat: 'Obey traffic rules', icon: '🚦', rules: [
'Cyclists follow the same signals and signs as motor vehicles',
'Stop at red lights and pedestrian crossings',
'Never ride against the flow of traffic (no counterflow)',
]},
{ id: 3, cat: 'Be visible & predictable', icon: '👁️', rules: [
'Use hand signals before turning or stopping',
'Make eye contact with drivers at intersections',
'Avoid riding in vehicle blind spots, especially trucks & buses',
]},
{ id: 4, cat: 'Your protections', icon: '🛡️', rules: [
'Many LGUs protect bike lanes — blocking them is finable',
'Motorists must keep a safe overtaking distance from cyclists',
'You have equal right to the road as a vulnerable road user',
]},
];
const bike_routes = [
{ name: 'EDSA Protected Bike Lane', len: '23 km', type: 'Protected', color: '#00c48c' },
{ name: 'Marikina Bikeways', len: '52 km', type: 'Protected', color: '#00c48c' },
{ name: 'Pasig Greenways', len: '14 km', type: 'Painted', color: '#ffa502' },
{ name: 'BGC Cycle Network', len: '11 km', type: 'Protected', color: '#00c48c' },
];
function BicycleScreen({ t, go }) {
const [checked, setChecked] = useState({});
const [open, setOpen] = useState(1);
const [toast, setToast] = useState('');
const note = (m) => { setToast(m); setTimeout(() => setToast(''), 2000); };
const done = Object.values(checked).filter(Boolean).length;
return (
{toast &&
{toast}
}
🚲
Cyclist Hub
Ride safe, know your rights, and find protected bike lanes across Metro Manila.
{/* Pre-ride gear checklist */}
{done}/{bike_gear.length}}>Pre-Ride Safety Check
{bike_gear.map((g, i) => {
const on = !!checked[g.id];
return (
);
})}
{/* Bike lanes */}
note('Opening bike-lane map…')} className="no-select" style={{ background: 'none', border: 'none', color: t.mid, fontSize: 12.5, fontWeight: 700 }}>View map}>Protected Bike Lanes
{bike_routes.map(r => (
{r.name}
{r.len} · {r.type} lane
{r.type}
))}
{/* Hand signals */}
Hand Signals
{bike_signals.map(s => (
{s.icon}
{s.label}
{s.desc}
))}
{/* Rights & rules */}
Cyclist Rights & Rules
{bike_rules.map(l => {
const isOpen = open === l.id;
return (
{l.rules.map((r, i) => (
{r}
))}
);
})}
{/* Report */}
Blocked or unsafe bike lane?
Report obstructions, parked vehicles, or hazards in bike lanes to your LGU.
);
}
// ---------- E-BIKES ----------
const ebike_classes = [
{ id: 1, cls: 'Type A1 · Pedal-assist', speed: '≤ 25 km/h', reg: false, lic: false, where: 'Bike lanes & local roads', color: '#00c48c', icon: '🚲', note: 'Light e-bikes & pedal-assist. No LTO registration or license required.' },
{ id: 2, cls: 'Type A2/B · Throttle e-bike', speed: '26–50 km/h', reg: true, lic: false, where: 'Local roads (not bike lanes)', color: '#ffa502', icon: '🛵', note: 'Must be LTO-registered with a plate. Driver\u2019s license generally not required but helmet is mandatory.' },
{ id: 3, cls: 'Type L · E-motorcycle', speed: '> 50 km/h', reg: true, lic: true, where: 'Roads only (no bike lanes/sidewalks)', color: '#ff4757', icon: '🏍️', note: 'Treated as a motorcycle: LTO registration, plate, and driver\u2019s license all required.' },
];
const ebike_battery = [
{ icon: '🔌', text: 'Use only the manufacturer\u2019s charger and cable' },
{ icon: '🌡️', text: 'Charge in a cool, dry, ventilated area — never on exits or stairs' },
{ icon: '⏰', text: 'Don\u2019t charge overnight or unattended; unplug when full' },
{ icon: '🚫', text: 'Stop using a battery that is swollen, hot, or damaged' },
{ icon: '💧', text: 'Keep batteries away from water and direct heat/sun' },
{ icon: '🧯', text: 'Keep a working smoke alarm where you charge' },
];
const ebike_stations = [
{ name: 'SM Megamall — EV Bay', dist: '1.2 km', slots: '4 free', color: '#00c48c' },
{ name: 'Ayala Triangle Charge Point', dist: '3.4 km', slots: '1 free', color: '#ffa502' },
{ name: 'Robinsons Galleria Hub', dist: '2.1 km', slots: 'Full', color: '#ff4757' },
];
function EbikeScreen({ t, go }) {
const [sel, setSel] = useState(1);
const [toast, setToast] = useState('');
const note = (m) => { setToast(m); setTimeout(() => setToast(''), 2000); };
const cur = ebike_classes.find(c => c.id === sel);
return (
{toast &&
{toast}
}
🛵
E-Bike Center
Know your e-bike class, registration rules, where you can ride, and how to charge safely.
{/* Classification selector */}
What class is your e-bike?
{ebike_classes.map(c => (
setSel(c.id)} color={c.color}>{c.icon} {c.speed}
))}
{cur.cls}
Top speed {cur.speed}
{cur.note}
{[['LTO registration', cur.reg], ["Driver's license", cur.lic]].map(([label, need]) => (
{need ? 'Required' : 'Not needed'}
{label}
))}
Allowed: {cur.where}
Guidance based on LTO rules for light electric vehicles. Always confirm the latest LTO/LGU requirements.
{cur.reg && (
note('Opening LTO e-vehicle registration…')}>Register with LTO
)}
{/* Battery safety */}
🔋 Battery & Charging Safety
{ebike_battery.map((b, i) => (
{b.icon}
{b.text}
))}
{/* Charging stations */}
note('Opening charging map…')} className="no-select" style={{ background: 'none', border: 'none', color: t.mid, fontSize: 12.5, fontWeight: 700 }}>View map}>Nearby Charging Stations
{ebike_stations.map(s => (
))}
);
}
Object.assign(window, { BicycleScreen, EbikeScreen });