/* ============================================================
HOME PAGE
============================================================ */
/* ---------- HERO ---------- */
function Hero() {
const { go } = useNav();
return (
Детский благотворительный фонд · Челябинск
Каждому подростку нужен надёжный друг рядом
Мы помогаем детям из детских домов обрести «своего» взрослого — наставника, который будет рядом по-настоящему. Ваша поддержка превращается во встречи, заботу и веру в ребёнка.
Помочь фондуСтать наставником
НАД
Уже десятки наставников рядом с подростками Челябинской области
Наставникперсональный взрослый
1 раз в неделювстречи и общение
Рядом надолгоподдержка и опора
);
}
/* ---------- STAT STRIP ---------- */
const HOME_STATS = [
{ value: 'с 2021', label: 'Помогаем подросткам из детских домов Челябинской области', color: 'var(--green)' },
{ value: '100+', label: 'Подростков участвуют в проекте «Наставничество»', color: 'var(--orange-600)' },
{ value: '3', label: 'Получили президентских гранта на развитие наставничества', color: 'var(--blue-700)' },
{ value: '12+', label: 'Возраст детей, которым нужен наставник', color: 'var(--green)' },
];
function StatStrip() {
return (
{HOME_STATS.map((s, i) => (
))}
);
}
/* ---------- ABOUT TEASER ---------- */
function AboutTeaser() {
const { go } = useNav();
return (
Команда фонда
О нашем фонде
Мы — «Надёжные люди». И мы рядом с теми, кому это важнее всего
Некоммерческая организация из Челябинска. Мы реализуем всероссийский проект «Наставничество» по технологии благотворительного фонда «Солнечный город» — чтобы у каждого подростка из детского дома появился близкий взрослый.
Работаем по проверенной технологии – в реестре практик с доказанной эффективностью
Открыто отчитываемся о каждом полученном рубле
Трижды поддержаны Фондом президентских грантов
Узнать больше
);
}
/* ---------- MENTORSHIP 4 CARDS ---------- */
const MENTOR_CARDS = [
{ icon: 'sprout', tone: 'green', title: 'Что такое наставничество?', text: 'Проект для поддержки подростков из детских домов старше 12 лет — тех, кого реже всего забирают в семью.', to: 'mentorship' },
{ icon: 'handHeart', tone: 'orange', title: 'Кто такой наставник?', text: '«Персональный взрослый» подростка. В детском доме всё общее — а наставник только его, личный и настоящий.', to: 'mentorship' },
{ icon: 'chat', tone: 'blue', title: 'Как это работает?', text: 'Вы просто дружите с ребёнком: общаетесь не реже одного раза в неделю в удобное вам обоим время.', to: 'mentorship' },
{ icon: 'star', tone: 'green', title: 'Как стать наставником?', text: 'Им может стать человек старше 24 лет без судимостей и психических заболеваний. ', to: 'mentorship' },
];
function MentorSection() {
return (
Главный проект фонда
Наставничество — простыми словами
Четыре коротких ответа на главные вопросы. А если захотите глубже — расскажем подробно.
{MENTOR_CARDS.map((c, i) => (
))}
);
}
function MentorCard({ icon, tone, title, text, to }) {
const { go } = useNav();
const map = {
green: { bg: 'var(--green-50)', fg: 'var(--green)' },
orange: { bg: 'var(--orange-50)', fg: 'var(--orange-600)' },
blue: { bg: 'var(--blue-50)', fg: 'var(--blue-700)' },
}[tone];
return (
);
}
/* ---------- IMPACT (where money goes) ---------- */
const IMPACT = [
{ icon: 'users', title: 'Подбор и обучение наставников', text: 'Отбор, обучение и проверка кандидатов в наставники — чтобы рядом с ребёнком был подготовленный взрослый.' },
{ icon: 'chat', title: 'Сопровождение психологом', text: 'Психолог проекта поддерживает каждую пару «наставник — подросток» на всём пути.' },
{ icon: 'gift', title: 'Встречи, поездки и досуг', text: 'Совместные прогулки, разговоры и личное внимание, которых так не хватает в детском доме.' },
{ icon: 'sprout', title: 'Развитие проекта', text: 'Чтобы наставников становилось больше и помощь дошла до каждого подростка, который её ждёт.' },
];
function ImpactSection() {
return (
Куда идут пожертвования
Ваша помощь работает каждый день
Мы тратим средства прозрачно и по делу. Вот на что идёт каждое пожертвование.
Поддержать проект
{IMPACT.map((it, i) => (
0{i + 1}
{it.title}
{it.text}
))}
);
}
/* ---------- STORY / QUOTE ---------- */
function StorySection() {
return (
Раньше я думала, что никому не нужна. А теперь у меня есть человек, который приходит просто ко мне. Не потому что должен — а потому что хочет.
Подросток, 14 летучастник проекта «Наставничество»
* История из практики фонда. Имя скрыто в интересах ребёнка.
);
}
/* ---------- NEWS ---------- */
const FALLBACK_NEWS = [
{ tag: 'События', tone: 'green', date: '12 мая 2026', title: 'Весенний выезд на природу для наставников и подростков', text: 'Провели большую встречу пар на свежем воздухе — игры, костёр и много тёплых разговоров.' },
{ tag: 'Проект', tone: 'blue', date: '28 апреля 2026', title: 'Новый набор в школу наставников открыт', text: 'Приглашаем взрослых, готовых стать опорой для подростка. Обучение и сопровождение — бесплатно.' },
{ tag: 'Спасибо', tone: 'orange', date: '9 апреля 2026', title: 'Отчитываемся: как ваши пожертвования помогли за квартал', text: 'Рассказываем, сколько встреч состоялось и какие события мы смогли подарить детям благодаря вам.' },
];
function formatNewsDate(value) {
try {
return new Intl.DateTimeFormat('ru-RU', { day: 'numeric', month: 'long', year: 'numeric' }).format(new Date(value));
} catch (err) {
return value;
}
}
function normalizeNewsItem(item) {
return {
id: item.id,
tag: item.tag || 'VK',
tone: item.tone || 'blue',
date: formatNewsDate(item.date),
title: item.title,
text: item.excerpt || item.text || '',
href: item.url || 'https://vk.com/fond_nl',
imageUrl: item.imageUrl || null,
};
}
function NewsSection() {
const [items, setItems] = useState(() => FALLBACK_NEWS.map((item, index) => ({ ...item, id: `fallback-${index}` })));
const [updatedAt, setUpdatedAt] = useState('');
useEffect(() => {
let cancelled = false;
fetch('data/vk-posts.json', { cache: 'no-store' })
.then((response) => {
if (!response.ok) throw new Error(`Failed to load VK feed: ${response.status}`);
return response.json();
})
.then((payload) => {
if (cancelled || !payload?.items?.length) return;
setItems(payload.items.slice(0, 3).map(normalizeNewsItem));
setUpdatedAt(payload.updatedAt || '');
})
.catch(() => {});
return () => { cancelled = true; };
}, []);
return (