/opt/canhelp/apps/web/src/app
NameSizeModeActions
(auth)/-0755rm
admin/-0755rm
become-specialist/-0755rm
chat/-0755rm
dashboard/-0755rm
delete-account/-0755rm
favorites/-0755rm
maintenance/-0755rm
notifications/-0755rm
payment/-0755rm
pricing/-0755rm
privacy/-0755rm
profile/-0755rm
schedule/-0755rm
site/-0755rm
specialist-setup/-0755rm
specialist-tasks/-0755rm
specialists/-0755rm
support/-0755rm
tasks/-0755rm
users/-0755rm
apple-icon.png626050644editdlrm
globals.css95430644editdlrm
icon.png626050644editdlrm
icon.svg48820644editdlrm
layout.tsx43450644editdlrm
not-found.tsx5500644editdlrm
page.tsx243370644editdlrm
robots.ts7890644editdlrm
sitemap.ts36640644editdlrm
Edit: /opt/canhelp/apps/web/src/app/page.tsx (24337B)
import Link from 'next/link' import { cookies } from 'next/headers' import { getCategories, getLocations } from '@/lib/api' import { getTranslations, type Locale } from '@/lib/translations' import type { Category } from '@canhelp/shared' import { HomeCityCloud } from '@/components/HomeCityCloud' import { ShareButton } from '@/components/ShareButton' import { CommunityArt } from '@/components/HomeSectionArt' import { Section } from '@/components/Section' import { HeroSearch } from '@/components/HeroSearch' import { HeroFloatingIcons } from '@/components/HeroFloatingIcons' import { FaqAccordion } from '@/components/FaqAccordion' import { BecomeSpecialistButton } from '@/components/BecomeSpecialistButton' import { PromoCountdown } from '@/components/PromoCountdown' import { HomeCategoryGrid } from '@/components/HomeCategoryGrid' export default async function HomePage() { const cookieStore = await cookies() const rawLocale = cookieStore.get('canhelp_locale')?.value as Locale | undefined const locale: Locale = ['el', 'en', 'uk', 'ru'].includes(rawLocale ?? '') ? rawLocale! : 'el' const t = getTranslations(locale) // Determine user role server-side const INTERNAL = process.env.INTERNAL_API_URL || 'http://localhost:4000' const cookieHeader = cookieStore.getAll().map((c) => `${c.name}=${c.value}`).join('; ') let userRole: string | null = null try { const sessRes = await fetch(`${INTERNAL}/api/auth/get-session`, { headers: { Cookie: cookieHeader }, }) if (sessRes.ok) { const sess = await sessRes.json() userRole = sess?.user?.role ?? null } } catch {} // Admin can override the role for preview purposes via cookie const previewRole = cookieStore.get('canhelp_preview_role')?.value const effectiveRole = (userRole === 'admin' && previewRole) ? previewRole : userRole const isSpecialist = effectiveRole === 'specialist' let categories: Category[] = [] let locationTree: any[] = [] let platformStats = { specialistCount: 0, taskCount: 0, categoryCount: 0 } try { ;[categories, locationTree] = await Promise.all([getCategories(), getLocations()]) } catch {} try { const statsRes = await fetch(`${INTERNAL}/api/stats`, { next: { revalidate: 600 } }) if (statsRes.ok) platformStats = await statsRes.json() } catch {} return (
{/* Hero */}
{/* Stats strip */}
{platformStats.specialistCount > 0 ? platformStats.specialistCount : '—'}
{t('stats.specialists')}
{platformStats.taskCount > 0 ? platformStats.taskCount : '—'}
{t('stats.tasks')}
{platformStats.categoryCount > 0 ? platformStats.categoryCount : '—'}
{t('stats.categories')}
{t('stats.free')}
{/* Promo countdown — only for guests */} {!userRole && (
)} {/* Categories */}

{isSpecialist ? t('section.categories.specialist') : t('section.categories')}

{/* How it works */}

{t('section.how')}

{([1, 2, 3] as const).map((n) => (
{n}

{isSpecialist ? t(`how.specialist.step${n}.title`) : t(`how.step${n}.title`)}

{isSpecialist ? t(`how.specialist.step${n}.desc`) : t(`how.step${n}.desc`)}

))}
{/* Specialist promo — only shown to customers / guests */} {!isSpecialist && (
{t('become_specialist.free_badge')}

{t('become_specialist.hero.title')}

{t('become_specialist.hero.subtitle')}

{([1, 2, 3] as const).map((n) => (
{n}

{t(`become_specialist.step${n}.title`)}

{t(`become_specialist.step${n}.desc`)}

))}
{([1, 2, 3, 4] as const).map((n) => ( ✓ {t(`become_specialist.benefit${n}`)} ))}
{t('become_specialist.cta')}
)} {/* Community / Share section */}

{t('section.community')}

{t('community.subtitle')}

🛠️

{t('community.point1.title')}

{t('community.point1.desc')}

🙋

{t('community.point2.title')}

{t('community.point2.desc')}

🌱

{t('community.point3.title')}

{t('community.point3.desc')}

{/* Referral / Partner Program */}
{t('referral.home.badge')}

{t('section.referral')}

{t('referral.home.subtitle')}

{([1, 2, 3] as const).map((n) => (
{n}

{t(`referral.home.step${n}.title`)}

{t(`referral.home.step${n}.desc`)}

))}
{t('referral.home.cta')}
{/* FAQ */}

{t('section.faq')}

({ q: t(`faq.q${n}`), a: t(`faq.a${n}`), }))} />
{/* Mobile App Download section */}
{/* Two mobile app previews */}
CanHelp

Найдите помощь рядом

Новая заявка

{['Электрик', 'Сантехник', 'Уборка'].map((service) => (

{service}

Рядом с вами

))}
Предложения

Электрик

На рассмотрении

Открыть предложение

Новые заказы

РемонтАфины
{/* Text + QR codes */}

CanHelp Mobile

{t('app.download_title', 'Скачайте мобильное приложение CanHelp')}

{t('app.download_desc', 'Всегда под рукой. Доступно для Android и iOS.')}

{/* Store buttons */} {/* QR codes */}
{/* eslint-disable-next-line @next/next/no-img-element */} QR App Store
App Store · QR
{/* eslint-disable-next-line @next/next/no-img-element */} QR Google Play
Google Play · QR
{/* Cities & Districts cloud */} {locationTree.length > 0 && (

{isSpecialist ? t('section.cities.specialist') : t('section.cities')}

)}
) }