import { createT, isLocale, type Locale } from '@barev/i18n'; import type { Metadata } from 'next'; import { getCatalog } from '../lib/data'; import { languageAlternates, SITE } from '../lib/seo'; import { range, SERVICE_PAGES, type ServicePageId } from '../lib/services'; import { BotLink, BotLinkProvider } from './client'; import { HomeFooter } from './home'; import { RichText } from './rich-text'; import { VariantHeader } from './variant'; /** Title, description, canonical и hreflang страницы услуги; цены в описании — из админки */ export async function serviceMetadata(params: Promise<{ locale: string }>, id: ServicePageId): Promise { const { locale } = await params; if (!isLocale(locale)) return {}; const cfg = SERVICE_PAGES[id]; const t = createT(locale); const vars = cfg.vars(await getCatalog(), locale); const k = `landing.svc.${id}`; const title = t(`${k}.meta.title`, vars); const description = t(`${k}.meta.description`, vars); return { title, description, alternates: { canonical: `/${locale}${cfg.path}`, languages: languageAlternates(cfg.path) }, openGraph: { title, description, locale, type: 'website', siteName: 'Barev Club' }, twitter: { card: 'summary_large_image', title, description }, }; } /** * Страница услуги под поисковый запрос: прямой ответ с ценой в первом экране, факты, шаги, * подробности, цены и FAQ. Так её удобно читать людям и цитировать поиску и ИИ. */ export async function ServicePage({ locale, id }: { locale: Locale; id: ServicePageId }) { const cfg = SERVICE_PAGES[id]; const t = createT(locale); const catalog = await getCatalog(); const vars = cfg.vars(catalog, locale); const k = `landing.svc.${id}`; const c = (key: string) => t(`landing.svc.common.${key}`); const tv = (key: string) => t(`${k}.${key}`, vars); const others = Object.values(SERVICE_PAGES).filter((p) => p.id !== id); const url = `${SITE}/${locale}${cfg.path}`; const jsonLd = { '@context': 'https://schema.org', '@graph': [ { '@type': 'Service', '@id': `${url}#service`, name: tv('h1'), serviceType: cfg.serviceType, description: tv('lead'), url, inLanguage: locale, provider: { '@id': `${SITE}/#org` }, areaServed: { '@type': 'City', name: 'Yerevan' }, offers: cfg.offers(catalog).map((o) => ({ '@type': 'Offer', name: o.name, priceCurrency: 'AMD', ...(o.minPrice ? { priceSpecification: { '@type': 'PriceSpecification', minPrice: o.price, priceCurrency: 'AMD' } } : { price: o.price }), url, })), }, { '@type': 'FAQPage', '@id': `${url}#faq`, mainEntity: range(cfg.faq).map((n) => ({ '@type': 'Question', name: tv(`faq.q${n}.q`), acceptedAnswer: { '@type': 'Answer', text: tv(`faq.q${n}.a`) }, })), }, { '@type': 'BreadcrumbList', itemListElement: [ { '@type': 'ListItem', position: 1, name: c('home'), item: `${SITE}/${locale}` }, { '@type': 'ListItem', position: 2, name: tv('crumb'), item: url }, ], }, ], }; return (