/* global React, DATA, Panel, ComposedChart, BarChart, KPI, fmtEUR, fmtN, fmtPct, fmtSignPct */ const Forecast = () => { const fw = DATA.forecast_weekly; const fm = DATA.forecast_market; const totRev = fm.reduce((s, x) => s + x.revenue, 0); const totPax = fm.reduce((s, x) => s + x.forecast_pax, 0); const avgLf = fm.reduce((s, x) => s + x.lf * x.forecast_pax, 0) / (totPax || 1); const wkData = fw.map(x => ({ label: x.label, revenue: x.revenue, lf: x.lf, otb: x.otb, forecast_pax: x.forecast_pax })); const mBars = fm.map(x => ({ label: x.market, revenue: x.revenue, yoy: x.yoy })); return React.createElement('div', { className: 'page' }, React.createElement('div', { className: 'page-head' }, React.createElement('div', { className: 'eyebrow', style: { marginBottom: 8 } }, 'Demand Forecast'), React.createElement('h1', { className: 'headline', style: { fontSize: 46 } }, 'What the ', React.createElement('em', null, 'forward book'), ' is telling us.'), React.createElement('div', { className: 'subhead' }, 'Network demand, load factor and revenue forecast by departure week — on the books today plus the agent\'s forward view.')), React.createElement('div', { className: 'grid grid-4 gap-2', style: { marginBottom: 22 } }, React.createElement(KPI, { label: 'Forecast revenue · 60d', value: fmtEUR(totRev), sub: 'next 60 departure days' }), React.createElement(KPI, { label: 'Forecast passengers', value: fmtN(Math.round(totPax / 1e3)) + 'K', sub: 'next 60 days' }), React.createElement(KPI, { label: 'Forecast load factor', value: fmtPct(avgLf), sub: 'demand-weighted' }), React.createElement(KPI, { label: 'YoY (blended)', value: fmtSignPct(fm.reduce((s, x) => s + x.yoy * x.revenue, 0) / (totRev || 1)), sub: 'vs same period last year' })), React.createElement(Panel, { title: 'Forward revenue & load factor by departure week', sub: 'Forecast · €bars, load-factor line', className: '', }, React.createElement(ComposedChart, { data: wkData, barKey: 'revenue', lineKey: 'lf', labelKey: 'label', barFormat: fmtEUR, lineFormat: v => v.toFixed(0) + '%', barLabel: 'Forecast revenue', lineLabel: 'Load factor', height: 300 })), React.createElement('div', { className: 'grid gap-3', style: { gridTemplateColumns: '1fr 1.3fr', marginTop: 22 } }, React.createElement(Panel, { title: 'Forecast revenue by market', sub: 'Next 60 days' }, React.createElement(BarChart, { data: mBars, valueKey: 'revenue', labelKey: 'label', format: fmtEUR, horizontal: true, color: 'var(--accent)', height: 220 })), React.createElement(Panel, { title: 'Demand drivers & events', sub: 'Active and imminent', flush: true }, React.createElement('table', { className: 'tbl' }, React.createElement('thead', null, React.createElement('tr', null, ['Event', 'Type', 'Window', 'Scope', 'Modelled impact'].map((h, i) => React.createElement('th', { key: i }, h)))), React.createElement('tbody', null, DATA.events.map((e, i) => React.createElement('tr', { key: i }, React.createElement('td', { style: { fontWeight: 600 } }, e.name), React.createElement('td', null, React.createElement('span', { className: 'pill ' + (e.type === 'Seasonal' ? 'pill-peak' : e.type === 'Religious' ? 'pill-teal' : 'pill-info') }, e.type)), React.createElement('td', { className: 'mono text-muted', style: { fontSize: 10.5 } }, e.date_start.slice(5), ' → ', e.date_end.slice(5)), React.createElement('td', { className: 'text-muted' }, e.scope), React.createElement('td', { style: { fontSize: 11 } }, e.impact)))))) )); }; window.Forecast = Forecast;