// home.jsx — Главная участника: приветствие и тариф, «Продолжить» по цели из анкеты,
// ближайшие события, разделы базы. Не участнику вместо неё — экран «Доступ по подписке»
// (paywall.jsx), незалогиненному — вход (login.jsx). Выбор делает app.jsx.
const useFetch = (url, deps = []) => {
const [data, setData] = React.useState(null);
React.useEffect(()=>{
let alive = true;
fetch(url, { credentials:'same-origin' }).then(r => r.json()).then(j => alive && setData(j)).catch(() => alive && setData({ ok: false }));
return () => { alive = false; };
}, deps);
return data;
};
window.useFetch = useFetch;
const EV_KIND_LABEL = { webinar:'Вебинар', qa:'Q&A', mastermind:'Мастермайнд', offline:'Офлайн' };
function EventsList({ events }) {
const tier = ME().member.tier;
if (!events) return
Загружаем расписание…
;
if (!events.length) return Ближайших событий пока нет — расписание месяца появится здесь.
;
return (
{events.slice(0, 4).map((e, i) => {
const closed = e.access === 'pro' && tier !== 'pro';
return (
{fmtDay(e.date)}
{e.time} МСК
{EV_KIND_LABEL[e.kind] || 'Событие'}
{e.access === 'pro' && }
{e.title}
{[e.host, e.note].filter(Boolean).join(' · ')}{closed ? ' · в тарифе PRO' : ''}
);
})}
);
}
window.EventsList = EventsList;
function Home({ nav }) {
const { user, member, profile } = ME();
const prof = useFetch('/api/profile');
const ev = useFetch('/api/events');
const kb = useKB();
const goal = profile && ((CFG().goals || []).find(g => g.id === profile.goal));
const goalTitle = profile ? (profile.goal === 'other' ? profile.goal_custom : goal && goal.title) : null;
const rec = (prof && prof.recommended) || [];
const next = rec.find(r => !r.locked) || rec[0];
const today = new Date().toLocaleDateString('ru-RU', { weekday:'long', day:'numeric', month:'long' });
const clusters = (kb && kb.clusters) || CFG().clusters || [];
const cnt = (id) => ((kb && kb.items) || []).filter(i => i.cluster === id).length;
return (
{today}
{firstName(user.name) ? `Привет, ${firstName(user.name)}.` : 'Привет.'}
Вы в сообществе хакку · тариф{' '}
{TIER_LABEL[member.tier]}
{member.paid_until && !member.admin ? `, оплачено до ${fmtDate(member.paid_until).replace(/\.$/, '')}` : ''}.
{/* «Продолжить» по цели из анкеты */}
{goalTitle ? `Ваша цель · ${goalTitle}` : 'С чего начать'}
{next ? (
<>
{next.title}
{next.summary}
>
) : (
<>
Расскажите, зачем вы здесь.
Две минуты на анкету — и подберём первые материалы под вашу цель.
>
)}
{rec.length > 1 && (
)}
Ближайшие события
{/* TODO: календарь месяца и ссылки на подключение — после синка с расписанием */}
);
}
window.Home = Home;