Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
112 lines
4.9 KiB
TypeScript
112 lines
4.9 KiB
TypeScript
import '../../variants.css';
|
|
import { createT, formatAmd, isLocale, LOCALES, type Locale } from '@barev/i18n';
|
|
import { Icon } from '@barev/ui';
|
|
import { notFound } from 'next/navigation';
|
|
import { BotLink, BotLinkProvider } from '../../../components/client';
|
|
import { GiftCode } from '../../../components/gift-code';
|
|
import { VariantHeader, variantMetadata } 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 variantMetadata(params, '/land3', 'landing.v3.title');
|
|
}
|
|
|
|
/** Версия 3 «Подарок от агентства»: для тех, кто пришёл по QR из договора аренды. Бирка для ключей с месяцем Barev+ */
|
|
export default async function Land3({ 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 home = catalog.categories.find((c) => c.code === 'HOME');
|
|
const cleaningFrom = home?.services.find((s) => s.code === 'cleaning')?.fromPrice ?? 0;
|
|
const homePct = home?.barevPlusDiscountPct ?? 0;
|
|
// так же округляет скидку сервер: вниз до целого драма
|
|
const cleaningWithPlus = cleaningFrom - Math.floor((cleaningFrom * homePct) / 100);
|
|
const discounts = catalog.categories.filter((c) => c.barevPlusDiscountPct > 0);
|
|
|
|
return (
|
|
<BotLinkProvider locale={locale} bot={catalog.botUsername}>
|
|
<div className="v3">
|
|
<div className="v-wrap">
|
|
<VariantHeader locale={locale} path="/land3" />
|
|
|
|
<section className="v3-hero">
|
|
<div className="v3-hero__text">
|
|
<span className="v3-kicker">{t('landing.v3.tag')}</span>
|
|
<h1 className="v3-title">{t('landing.v3.title')}</h1>
|
|
<p className="v3-sub">{t('landing.v3.sub')}</p>
|
|
<BotLink className="bc-btn bc-btn--accent v3-cta">{t('landing.v3.cta')}</BotLink>
|
|
</div>
|
|
<div className="v3-tagwrap" aria-hidden="true">
|
|
<svg className="v3-string" viewBox="0 0 120 160" fill="none">
|
|
<path d="M60 0 C 20 40, 100 80, 60 132" stroke="currentColor" strokeWidth="3" strokeLinecap="round" />
|
|
</svg>
|
|
<div className="v3-tag">
|
|
<span className="v3-tag__hole" />
|
|
<span className="v3-tag__label">{t('landing.agency.gift')}</span>
|
|
<span className="v3-tag__title">{t('landing.v3.giftTitle')}</span>
|
|
<GiftCode withCode={t('landing.v3.giftCode')} withoutCode={t('landing.v3.giftNoCode')} />
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section className="v3-steps">
|
|
<h2 className="v3-h2">{t('landing.v3.stepsTitle')}</h2>
|
|
<ol>
|
|
{([1, 2, 3] as const).map((n) => (
|
|
<li key={n}>
|
|
<span className="v3-num">{n}</span>
|
|
<b>{t(`landing.v3.step${n}`)}</b>
|
|
<span>{t(`landing.v3.step${n}Sub`)}</span>
|
|
</li>
|
|
))}
|
|
</ol>
|
|
</section>
|
|
|
|
<section className="v3-benefits">
|
|
<div className="v3-deal">
|
|
<h2 className="v3-h2">{t('landing.v3.benefitsTitle')}</h2>
|
|
{homePct > 0 && cleaningFrom > 0 && (
|
|
<a href={`/${locale}/clean`} className="v3-deal__card">
|
|
<b>{t('landing.v3.cleaningDeal', { price: amd(cleaningWithPlus), full: amd(cleaningFrom) })}</b>
|
|
<span>{t('landing.v3.cleaningDealSub')}</span>
|
|
<span className="v3-deal__go">{t('landing.hero.cleanCta')}</span>
|
|
</a>
|
|
)}
|
|
</div>
|
|
<ul className="v3-list">
|
|
{discounts.map((c) => (
|
|
<li key={c.code}>
|
|
<Icon name="check" size={20} strokeWidth={2.6} />
|
|
{t('plans.plus.discount', { pct: c.barevPlusDiscountPct, category: t(`categories.${c.code}.name`) })}
|
|
</li>
|
|
))}
|
|
<li>
|
|
<Icon name="check" size={20} strokeWidth={2.6} />
|
|
{t('plans.free.perks')}
|
|
</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<section className="v3-final">
|
|
<p>{t('landing.v3.noCode')}</p>
|
|
<BotLink className="bc-btn bc-btn--dark">{t('landing.v3.cta')}</BotLink>
|
|
</section>
|
|
|
|
<footer className="v-footer">
|
|
<span>{t('landing.footer.brand')}</span>
|
|
<a href={`/${locale}/privacy`}>{t('landing.footer.privacy')}</a>
|
|
</footer>
|
|
</div>
|
|
</div>
|
|
</BotLinkProvider>
|
|
);
|
|
}
|