import { useQuery } from '@tanstack/react-query'; import { Card } from '@barev/ui'; import { useI18n, useTRPC } from '@barev/web'; import { useEffect, useState } from 'react'; import { LEVEL_NAME, LEVEL_TONE, PageHead, type Level } from '../lib.tsx'; import { Qr } from '../qr.tsx'; /** * Клубная карта с живым QR (меняется каждую минуту — скриншот не сработает) и партнёры клуба: * что положено на твоём уровне и сколько осталось по лимиту. */ export function Perks() { const { t, locale } = useI18n(); const trpc = useTRPC(); const me = useQuery(trpc.client.me.queryOptions()); const qr = useQuery({ ...trpc.client.cardQr.queryOptions(), refetchInterval: 20_000, refetchIntervalInBackground: false }); const partners = useQuery(trpc.client.partners.queryOptions()); const level = (me.data?.membership.level ?? 'BAREV') as Level; const tone = LEVEL_TONE[level]; const left = useSecondsLeft(qr.data?.expiresAt); const name = (l: Record) => l[locale] || l.ru || ''; return (
Barev Club · {LEVEL_NAME[level]} {me.data?.firstName}
{qr.data ? :
}
{me.data?.cardCode} {t('client.partners.qrRefresh', { seconds: left })}

{t('client.partners.howTo')}

{partners.data?.length === 0 ? (

{t('client.perks.soonTitle')}

{t('client.perks.soonText')}

) : (
    {partners.data?.map((p) => (
  • {t(`client.partners.cat.${p.category}`)} {p.name} {p.address && {p.address}}
      {(p.offers.length ? p.offers : [{ id: 'main', title: p.offer, eligible: true, remaining: null, minLevel: null, limit: 'NONE' as const, limitCount: 1 }]).map((o) => (
    • {name(o.title)} {!o.eligible ? t('client.partners.needLevel', { level: LEVEL_NAME[(o.minLevel ?? 'BAREV') as Level] }) : o.remaining === null ? o.minLevel ? LEVEL_NAME[o.minLevel as Level] : t('client.partners.allMembers') : o.remaining > 0 ? t(`client.partners.limit_${o.limit}`, { count: o.limitCount }) : t(`client.partners.used_${o.limit}`)}
    • ))}
  • ))}
)}
); } function useSecondsLeft(expiresAt?: Date) { const [now, setNow] = useState(Date.now()); useEffect(() => { const id = setInterval(() => setNow(Date.now()), 1000); return () => clearInterval(id); }, []); return expiresAt ? Math.max(0, Math.ceil((new Date(expiresAt).getTime() - now) / 1000)) : 60; }