/* * timeline.jsx — Match timeline: momentum tracker, * live observations, and match summary. * * ── DEPENDS ON (from app.jsx, loaded before this file) ── * Globals: C, uid * Components: Field * React hooks: useState * * ── EXPORTS (to global scope) ── * MatchTimeline — used by App in app.jsx */ function MatchTimeline(_ref) { var momentum = _ref.momentum, onMomentumChange = _ref.onMomentumChange, observations = _ref.observations, onAddObservation = _ref.onAddObservation, onDeleteObservation = _ref.onDeleteObservation; var summary = _ref.summary, onUpdateSummary = _ref.onUpdateSummary, clockMinute = _ref.clockMinute; var _o = useState(""), newObs = _o[0], setNewObs = _o[1]; var _m = useState(""), newObsMin = _m[0], setNewObsMin = _m[1]; var SEGS = 18; var segStates = ["neutral", "us", "them"]; var cycleSeg = function (i) { var cur = momentum[i] || "neutral"; var next = segStates[(segStates.indexOf(cur) + 1) % 3]; onMomentumChange({ ...momentum, [i]: next === "neutral" ? undefined : next }); }; var addObs = function () { if (!newObs.trim()) return; onAddObservation({ id: uid(), text: newObs, minute: newObsMin || (clockMinute > 0 ? String(clockMinute) : "") }); setNewObs(""); setNewObsMin(""); }; return (
Match Momentum — Tap to cycle
0'45' HT90'
{Array.from({ length: SEGS }).map(function (_, i) { var state = momentum[i] || "neutral"; var bg = state === "us" ? C.blue : state === "them" ? C.red : C.bgInput; return ( ); })}
■ Us ■ Them ■ Neutral
Match Observations
0 ? clockMinute + "'" : "min"} aria-label="Minute" style={{ width: 48, padding: "8px 4px", fontSize: 13, textAlign: "center", background: C.bgInput, border: "1px solid " + C.border, borderRadius: 4, color: C.yellow, fontFamily: C.fontCond, outline: "none" }} />
{observations.length === 0 && (
No observations yet.
)} {observations.slice().reverse().map(function (o) { return (
{o.minute && ( {o.minute}' )} {o.text}
); })}
Match Summary
); }