import { useQuery } from '@tanstack/react-query'; import { Center, Icon, Spinner } from '@barev/ui'; import { I18nProvider, match, pickLocale, telegramLanguage, useI18n, useLocation, useTelegramBack, useTRPC } from '@barev/web'; import type { ReactNode } from 'react'; import { Consent } from './screens/Consent.tsx'; import { Docs } from './screens/Docs.tsx'; import { Move } from './screens/Move.tsx'; import { Segment } from './screens/Segment.tsx'; import { ServiceRequest } from './screens/ServiceRequest.tsx'; import { Home } from './screens/Home.tsx'; import { Membership } from './screens/Membership.tsx'; import { OrderDetail } from './screens/OrderDetail.tsx'; import { OrderForm } from './screens/OrderForm.tsx'; import { Orders } from './screens/Orders.tsx'; import { Perks } from './screens/Perks.tsx'; import { Profile } from './screens/Profile.tsx'; import { Services } from './screens/Services.tsx'; import { Chat } from './screens/Chat.tsx'; const ROOTS = ['/', '/services', '/perks', '/profile', '/docs']; export function App({ hasInitData }: { hasInitData: boolean }) { const trpc = useTRPC(); const me = useQuery({ ...trpc.client.me.queryOptions(), enabled: hasInitData }); const locale = pickLocale(me.data?.locale, telegramLanguage(), navigator.language); return ( {!hasInitData || me.error?.data?.httpStatus === 401 ? ( ) : me.isPending ? (
) : me.error ? ( ) : !me.data.consented ? ( ) : !me.data.segment ? ( ) : ( )}
); } /** * Два сценария: MOVING — план переезда, документы, консьерж; LIVING — услуги со скидками, партнёры, заказы. * Остальные экраны (услуги, подписка, заказы) доступны из обоих. */ function Routes({ segment }: { segment: 'MOVING' | 'LIVING' }) { const { path } = useLocation(); useTelegramBack(path, ROOTS); let screen: ReactNode; let m: Record | null; if (path === '/') screen = segment === 'MOVING' ? : ; else if (path === '/docs') screen = ; else if ((m = match('/request/:code', path))) screen = ; else if (path === '/services') screen = ; else if ((m = match('/order/:code', path))) screen = ; else if (path === '/orders') screen = ; else if ((m = match('/orders/:id', path))) screen = ; else if (path === '/perks') screen = ; else if (path === '/profile') screen = ; else if (path === '/membership') screen = ; else if (path === '/chat') screen = ; else screen = segment === 'MOVING' ? : ; const withNav = ROOTS.includes(path) || path === '/orders'; return ( <> {screen} {withNav && (segment === 'MOVING' ? : )} ); } /** Меню переезда: План / Документы / Консьерж (чат с ботом) / Услуги / Профиль */ function MoveNav({ path }: { path: string }) { const { t } = useI18n(); const item = (href: string, icon: Parameters[0]['name'], label: string) => ( {label} ); return ( ); } /** ORD-1: Главная / Услуги / + / Скидки / Профиль */ function BottomNav({ path }: { path: string }) { const { t } = useI18n(); const item = (href: string, icon: Parameters[0]['name'], label: string) => ( {label} ); return ( ); } function OpenInTelegram() { const { t } = useI18n(); return (

{t('client.openInTelegram.title')}

{t('client.openInTelegram.text')}

); } function LoadError() { const { t } = useI18n(); return (

{t('errors.generic')}

); }