// Shared UI primitives and inline icons (line-art SVG, original).
const { useState, useEffect, useRef, useMemo, useCallback } = React;
// ----- Inline icon set (simple, line-art) -----
const Icon = {
arrow: ({ size=16, stroke=1.6 }) => (
),
back: ({ size=16, stroke=1.6 }) => (
),
plane: ({ size=16, stroke=1.6 }) => (
),
pin: ({ size=16, stroke=1.6 }) => (
),
cal: ({ size=16, stroke=1.6 }) => (
),
user: ({ size=16, stroke=1.6 }) => (
),
swap: ({ size=16, stroke=1.6 }) => (
),
search: ({ size=16, stroke=1.6 }) => (
),
check: ({ size=16, stroke=2 }) => (
),
filter: ({ size=16, stroke=1.6 }) => (
),
bag: ({ size=16, stroke=1.6 }) => (
),
wifi: ({ size=16, stroke=1.6 }) => (
),
meal: ({ size=16, stroke=1.6 }) => (
),
leaf: ({ size=16, stroke=1.6 }) => (
),
star: ({ size=16, fill="currentColor" }) => (
),
cardChip: ({ size=18 }) => (
),
qr: ({ size=120 }) => {
// pseudo-QR: deterministic pattern, purely decorative
const cells = [];
const rnd = randSeed("AERIA-BP");
for (let y = 0; y < 21; y++) for (let x = 0; x < 21; x++) {
if (rnd() > .5) cells.push();
}
// corner markers
const corners = [[0,0],[14,0],[0,14]];
return (
);
}
};
// ----- Top nav -----
function TopNav({ stage, goto, onReset }) {
return (
);
}
// ----- Step rail -----
function StepRail({ stage }) {
const steps = [
{ key: "results", label: "Choose flight" },
{ key: "seats", label: "Seat" },
{ key: "passenger", label: "Passenger" },
{ key: "confirm", label: "Confirm" },
];
if (stage === "search") return null;
const idx = steps.findIndex(s => s.key === stage);
return (
{steps.map((s, i) => {
const done = i < idx, active = i === idx;
return (
{done ? : (i + 1)}
{s.label}
{i < steps.length - 1 && }
);
})}
);
}
// ----- Booking summary "ticket" stub used in passenger + confirm -----
function FlightLine({ flight, originCity, destCity, date, big = false }) {
return (
{originCity}
{flight.origin}
{fmtTime(flight.depMin)}
{fmtDuration(flight.durationMin)} ยท {flight.stops === 0 ? "Nonstop" : `${flight.stops} stop`}
{destCity}
{flight.dest}
{fmtTime(flight.arrMin)}
);
}
// ----- Action bar (sticky bottom) used on multiple screens -----
function ActionBar({ left, right, primary, onPrimary, secondary, onSecondary, primaryDisabled }) {
return (
{left}
{right}
{secondary && (
)}
{primary && (
)}
);
}
// ----- Faux 3D plane silhouette (top-down) used across screens -----
function PlaneSilhouette({ width = 360, opacity = 1, color = "var(--ink)" }) {
return (
);
}
Object.assign(window, { Icon, TopNav, StepRail, FlightLine, ActionBar, PlaneSilhouette });