Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
145 lines
6.1 KiB
TypeScript
145 lines
6.1 KiB
TypeScript
import '../variants.css';
|
|
import '../home.css';
|
|
import { createT, formatAmd, isLocale, LOCALES, pickMessages, type Locale } from '@barev/i18n';
|
|
import type { Viewport } from 'next';
|
|
import { notFound } from 'next/navigation';
|
|
import { BotLink, BotLinkProvider } from '../../components/client';
|
|
import { AudienceSwitch, ClubPlans, HomeFooter, homeMetadata } from '../../components/home';
|
|
import { QuizButton, QuizProvider } from '../../components/quiz';
|
|
import { ClubJsonLd } from '../../components/seo';
|
|
import { VariantHeader } from '../../components/variant';
|
|
import { getCatalog } from '../../lib/data';
|
|
|
|
export const revalidate = 300;
|
|
export const dynamicParams = false;
|
|
export function generateStaticParams() {
|
|
return LOCALES.map((locale) => ({ locale }));
|
|
}
|
|
export function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
|
|
return homeMetadata(params, '');
|
|
}
|
|
export const viewport: Viewport = { themeColor: '#4A1028' };
|
|
|
|
/** Шаги переезда: когда, что делаем и короткий факт (цена или срок) справа */
|
|
const STEPS = ['airport', 'flat', 'docs', 'permit', 'perks', 'chat'] as const;
|
|
const WHEN: Record<(typeof STEPS)[number], string> = {
|
|
airport: 'whenArrive',
|
|
flat: 'whenFirst',
|
|
docs: 'whenSettled',
|
|
permit: 'whenLater',
|
|
perks: 'whenDaily',
|
|
chat: 'whenAnytime',
|
|
};
|
|
|
|
/** Шаги таймлайна со своей страницей услуги — заголовок шага ведёт на неё */
|
|
const LINKS: Partial<Record<(typeof STEPS)[number], string>> = { airport: '/airport', docs: '/social-card', permit: '/residence-permit' };
|
|
|
|
/**
|
|
* Главная «Переезжаю»: огромное «Barev», таймлайн от аэропорта до ВНЖ, тарифы клуба и квиз-подбор.
|
|
* Версия для тех, кто уже живёт в Армении, — /live.
|
|
*/
|
|
export default async function Home({ params }: { params: Promise<{ locale: string }> }) {
|
|
const { locale: raw } = await params;
|
|
if (!isLocale(raw)) notFound();
|
|
const locale: Locale = raw;
|
|
const t = createT(locale);
|
|
const amd = (n: number) => formatAmd(locale, n);
|
|
const catalog = await getCatalog();
|
|
const messages = pickMessages(locale, ['landing.quiz.', 'errors.']);
|
|
|
|
const meta = (key: (typeof STEPS)[number]) => {
|
|
switch (key) {
|
|
case 'airport':
|
|
return null;
|
|
case 'flat':
|
|
return null;
|
|
case 'docs':
|
|
return null;
|
|
case 'permit':
|
|
return null;
|
|
case 'perks':
|
|
// скидки партнёров ещё не запущены — вместо ссылки плашка «Скоро» в стиле «Подробнее»
|
|
return (
|
|
<span className="bc-btn h-more h-more--soon" aria-disabled="true">
|
|
{t('landing.home.perksSoon')}
|
|
</span>
|
|
);
|
|
case 'chat':
|
|
return <BotLink className="bc-btn v2-btn">{t('landing.home.chatCta')}</BotLink>;
|
|
}
|
|
};
|
|
|
|
return (
|
|
<BotLinkProvider locale={locale} bot={catalog.botUsername}>
|
|
<QuizProvider locale={locale} messages={messages} consultPrice={amd(catalog.offer.consultation)}>
|
|
<div className="v2">
|
|
<ClubJsonLd locale={locale} path="" bot={catalog.botUsername} plusPrice={catalog.barevPlus.monthlyPrice} offer={catalog.offer} />
|
|
<div className="v-wrap">
|
|
<VariantHeader locale={locale} path="" className="vh--dark" logoColor="#F6C3D3" />
|
|
<AudienceSwitch locale={locale} current="move" />
|
|
|
|
<section className="v2-hero">
|
|
<div className="v2-word" aria-hidden="true">
|
|
Barev
|
|
</div>
|
|
<ul className="v2-hello" aria-hidden="true">
|
|
{t('landing.v2.hello')
|
|
.split('\n')
|
|
.map((h) => (
|
|
<li key={h}>{h}</li>
|
|
))}
|
|
</ul>
|
|
<div className="v2-hero__text">
|
|
<h1 className="v2-title">{t('landing.home.title')}</h1>
|
|
<div className="h-hero__side">
|
|
<p className="v2-sub">{t('landing.home.sub')}</p>
|
|
<div className="h-actions">
|
|
<QuizButton className="bc-btn h-cta">{t('landing.home.cta')}</QuizButton>
|
|
<BotLink className="bc-btn h-cta-ghost">{t('landing.home.ctaChat')}</BotLink>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<ol className="v2-line">
|
|
{STEPS.map((key) => {
|
|
// квартиры (/apartments) пока есть только на русском
|
|
const link = key === 'flat' ? (locale === 'ru' ? '/apartments' : undefined) : LINKS[key];
|
|
return (
|
|
<li key={key} className="v2-step" data-live={key === 'airport' || key === 'chat' || Boolean(link && key === 'flat')}>
|
|
<div className="v2-step__when">{t(`landing.home.${WHEN[key]}`)}</div>
|
|
<div className="v2-step__body">
|
|
<h2>{link ? <a href={`/${locale}${link}`}>{t(`landing.home.${key}Title`)}</a> : t(`landing.home.${key}Title`)}</h2>
|
|
<p>{t(`landing.home.${key}Text`)}</p>
|
|
</div>
|
|
<div className="v2-step__meta">
|
|
{meta(key)}
|
|
{link && (
|
|
<a href={`/${locale}${link}`} className="bc-btn h-more">
|
|
{t('landing.home.more')} →
|
|
</a>
|
|
)}
|
|
</div>
|
|
</li>
|
|
);
|
|
})}
|
|
</ol>
|
|
|
|
<ClubPlans locale={locale} plusPrice={catalog.barevPlus.monthlyPrice} offer={catalog.offer} />
|
|
|
|
<section className="v2-final">
|
|
<div>
|
|
<h2>{t('landing.home.finalTitle')}</h2>
|
|
<p>{t('landing.home.finalText')}</p>
|
|
</div>
|
|
<QuizButton className="bc-btn v2-final__cta">{t('landing.home.cta')}</QuizButton>
|
|
</section>
|
|
|
|
<HomeFooter locale={locale} />
|
|
</div>
|
|
</div>
|
|
</QuizProvider>
|
|
</BotLinkProvider>
|
|
);
|
|
}
|