/* app.jsx — корневое приложение, состояние, Tweaks */
const { useState: useS, useEffect } = React;
const WA = window.WC;
const UA = window.U;
const FAV_KEY = 'wc26_favs';
function loadFavs() {
try {
const raw = localStorage.getItem(FAV_KEY);
if (raw) return new Set(JSON.parse(raw));
} catch (e) {}
return new Set(WA.defaultFavs);
}
function App() {
const tw = typeof useTweaks === 'function'
? useTweaks({ theme: 'light', accent: '#b8863a', font: 'oswald', simDate: 'off' })
: [{ theme: 'light', accent: '#b8863a', font: 'oswald', simDate: 'off' }, () => {}];
const tweaks = tw[0];
const setTweak = tw[1];
const [favs, setFavs] = useS(loadFavs);
const [showBars, setShowBars] = useS(false);
const [showBridges, setShowBridges] = useS(false);
const cur = tweaks.simDate && tweaks.simDate !== 'off' ? tweaks.simDate : UA.realToday();
useEffect(() => {
try { localStorage.setItem(FAV_KEY, JSON.stringify([...favs])); } catch (e) {}
}, [favs]);
useEffect(() => {
const r = document.documentElement;
r.setAttribute('data-theme', tweaks.theme === 'night' ? 'night' : 'light');
r.setAttribute('data-font', tweaks.font || 'oswald');
if (tweaks.accent) {
r.style.setProperty('--accent', tweaks.accent);
r.style.setProperty('--accent-ink', accentInk(tweaks.accent));
}
}, [tweaks.theme, tweaks.font, tweaks.accent]);
function toggleFav(code) {
setFavs((prev) => {
const n = new Set(prev);
if (n.has(code)) n.delete(code); else n.add(code);
return n;
});
}
return (
<>
setShowBars(true)} onOpenBridges={() => setShowBridges(true)} />
{/* Компактная CTA-секция для пабов */}
Где смотреть
7 площадок
2 города
Гастрономические пабы Петербурга и Москвы. Большие экраны, бельгийское пиво и авторская кухня.
{showBars && setShowBars(false)} />}
{showBridges && setShowBridges(false)} />}
{typeof TweaksPanel === 'function' &&
setTweak('theme', v)}
options={[{ value: 'light', label: 'Свет' }, { value: 'night', label: 'Ночь' }]} />
setTweak('font', v)}
options={[{ value: 'oswald', label: 'Постер' }, { value: 'modern', label: 'Гротеск' }, { value: 'classic', label: 'Классика' }]} />
setTweak('accent', v)}
options={['#b8863a', '#c0392b', '#1f6f54', '#3563c9', '#7b3fa0']} />
setTweak('simDate', v)}
options={simDateOptions()} />
Меняет «текущий день», чтобы проверить, как обновляются баннеры «сегодня» и «завтра».
}
>
);
}
function simDateOptions() {
const opts = [
{ value: 'off', label: 'Реальная дата (' + UA.realToday() + ')' },
{ value: '2026-06-05', label: '5 июня — за неделю до старта' },
{ value: '2026-06-10', label: '10 июня — канун открытия' },
];
const sample = ['2026-06-11', '2026-06-13', '2026-06-15', '2026-06-17', '2026-06-21', '2026-06-24', '2026-06-27'];
sample.forEach((d) => {
const n = UA.matchesOn(d).length;
opts.push({ value: d, label: UA.fmtLong(d) + ' — ' + n + ' ' + window.matchWord(n) });
});
opts.push({ value: '2026-07-20', label: '20 июля — после финала' });
return opts;
}
function accentInk(hex) {
const c = hex.replace('#', '');
const r = parseInt(c.substr(0, 2), 16), g = parseInt(c.substr(2, 2), 16), b = parseInt(c.substr(4, 2), 16);
const lum = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
return lum > 0.62 ? '#1b1205' : '#fff8ea';
}
ReactDOM.createRoot(document.getElementById('root')).render();