Snapshot of uncommitted work: landing, bots, prod infra, partner cabinet, backoffice stage 1

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
zabudko-ruandClaude Opus 5.5 committed 2026-10-21 01:23:32 +04:00
1 parent 45d7512d2b
commit d452824c62
314 files changed
+44394 -121

No files matched your search

+103
View File
@@ -0,0 +1,103 @@
import { useQuery } from '@tanstack/react-query';
import { CATEGORY_ICON, Card, Chip, Icon, Spinner, type CategoryCode } from '@barev/ui';
import { navigate, useI18n, useTRPC } from '@barev/web';
import { LEVEL_NAME, LevelBadge, levelDiscount, OrderRow, toneClass, type Level } from '../lib.tsx';
/** Главная для тех, кто уже живёт в Армении: заказы, быстрые кнопки, направления со скидкой по уровню */
export function Home() {
const { t, dt } = useI18n();
const trpc = useTRPC();
const me = useQuery(trpc.client.me.queryOptions());
const orders = useQuery({ ...trpc.client.orders.list.queryOptions(), refetchInterval: 20_000 });
const catalog = useQuery(trpc.client.catalog.queryOptions());
const level = (me.data?.membership.level ?? 'BAREV') as Level;
const plus = level !== 'BAREV';
const lastDone = orders.data?.history.find((o) => o.status !== 'CANCELLED');
return (
<main className="app">
<header className="bc-between" style={{ alignItems: 'flex-start' }}>
<div>
<div className="bc-small bc-muted">{t('client.home.hello')}</div>
<h1 className="bc-h2">{me.data?.firstName ?? t('client.home.guest')}</h1>
</div>
<LevelBadge level={level} />
</header>
{plus && me.data?.membership.endsAt && (
<Card tone="perks" tight>
<div className="bc-row">
<Icon name="gift" />
<div className="bc-small" style={{ fontWeight: 600 }}>
{t('client.home.levelUntil', { plan: LEVEL_NAME[level], date: dt(me.data.membership.endsAt, { day: 'numeric', month: 'long' }) })}
</div>
</div>
</Card>
)}
{!plus && (
<a href="#/membership" className="upsell">
<b>{t('client.home.upsellTitle', { pct: me.data?.plans.eliteMaxPct ?? 0 })}</b>
<span className="bc-small">{t('client.home.upsellText')}</span>
</a>
)}
<Card style={{ padding: 16 }}>
<div className="bc-between" style={{ padding: '0 4px 8px' }}>
<h2 className="bc-h3">{t('client.home.myOrders')}</h2>
<a href="#/orders" className="bc-small bc-muted">
{t('client.home.allOrders')}
</a>
</div>
{orders.isPending ? (
<Spinner />
) : orders.data && orders.data.active.length > 0 ? (
<div className="bc-stack" style={{ gap: 8 }}>
{orders.data.active.slice(0, 4).map((o) => (
<OrderRow key={o.id} o={o} />
))}
</div>
) : (
<div className="bc-stack" style={{ padding: '4px 4px 6px' }}>
<p className="bc-muted" style={{ margin: 0 }}>
{t('client.home.noOrders')}
</p>
</div>
)}
</Card>
<div className="quick">
<Chip onClick={() => navigate('/order/cleaning')}>
<Icon name="home" size={18} />
{t('services.cleaning.name')}
</Chip>
{lastDone && (
<Chip onClick={() => navigate(`/order/${lastDone.serviceCode}?repeat=${lastDone.id}`)}>
<Icon name="repeat" size={18} />
{t('client.home.repeatLast')}
</Chip>
)}
{!me.data?.agencyName && (
<Chip onClick={() => navigate('/profile?code=1')}>
<Icon name="gift" size={18} />
{t('client.home.enterCode')}
</Chip>
)}
</div>
<div className="tiles">
{(catalog.data?.categories ?? []).map((c) => (
<a key={c.code} href={c.code === 'PERKS' ? '#/perks' : `#/services?c=${c.code}`} className={`tile ${toneClass(c.code)}`}>
<div className="bc-between" style={{ alignItems: 'flex-start' }}>
<div className="tile__title">{t(`categories.${c.code}.name`)}</div>
<Icon name={CATEGORY_ICON[c.code as CategoryCode]} size={24} />
</div>
<div className="bc-small">
{levelDiscount(level, c) > 0 ? t('client.services.yourDiscount', { pct: levelDiscount(level, c) }) : t(`categories.${c.code}.short`)}
</div>
</a>
))}
</div>
</main>
);
}