From 39758a18b04c7af2bb0d629cda69e1b978196672 Mon Sep 17 00:00:00 2001 From: Boris Kovalskii <36034823+JustYay@users.noreply.github.com> Date: Thu, 11 Jun 2026 09:17:05 +1000 Subject: [PATCH] feat: hide info tabs by display mode visibility --- src/pages/Info.tsx | 48 +++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/src/pages/Info.tsx b/src/pages/Info.tsx index 9434baf..edaa072 100644 --- a/src/pages/Info.tsx +++ b/src/pages/Info.tsx @@ -3,7 +3,7 @@ import { useQuery } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; import { PiCaretDown } from 'react-icons/pi'; import DOMPurify from 'dompurify'; -import { infoApi, FaqPage } from '../api/info'; +import { infoApi, FaqPage, InfoVisibility } from '../api/info'; import { infoPagesApi } from '../api/infoPages'; import { promoApi, LoyaltyTierInfo } from '../api/promo'; import type { FaqItem, ReplacesTab } from '../api/infoPages'; @@ -331,6 +331,12 @@ export default function Info() { staleTime: 60_000, }); + const { data: visibility } = useQuery({ + queryKey: ['info-visibility'], + queryFn: infoApi.getVisibility, + staleTime: 60_000, + }); + // Filter to only pages that don't replace a built-in tab and don't collide with built-in IDs const extraPages = useMemo( () => (customPages ?? []).filter((p) => !p.replaces_tab && !BUILTIN_TABS.has(p.slug)), @@ -425,20 +431,36 @@ export default function Info() { refetchOnMount: 'always', }); - const builtinTabs: Array<{ id: string; label: string; icon: React.FC; emoji?: string }> = [ - { id: 'faq', label: t('info.faq'), icon: QuestionIcon }, - { id: 'rules', label: t('info.rules'), icon: DocumentIcon }, - { id: 'privacy', label: t('info.privacy'), icon: ShieldIcon }, - { id: 'offer', label: t('info.offer'), icon: DocumentIcon }, - { id: 'loyalty', label: t('info.loyalty'), icon: StarIcon }, - ]; + const tabs = useMemo(() => { + const builtinTabs: Array<{ id: string; label: string; icon: React.FC; emoji?: string }> = [ + { id: 'faq', label: t('info.faq'), icon: QuestionIcon }, + { id: 'rules', label: t('info.rules'), icon: DocumentIcon }, + { id: 'privacy', label: t('info.privacy'), icon: ShieldIcon }, + { id: 'offer', label: t('info.offer'), icon: DocumentIcon }, + { id: 'loyalty', label: t('info.loyalty'), icon: StarIcon }, + ]; - const customTabs = extraPages.map((p) => { - const label = p.title[locale] || p.title['ru'] || p.title['en'] || p.slug; - return { id: p.slug, label, icon: DocumentIcon, emoji: p.icon ?? undefined }; - }); + const visibleBuiltinTabs = builtinTabs.filter((tab) => { + if (tab.id === 'loyalty') return true; + if (tabReplacements?.[tab.id as ReplacesTab]) return true; + if (!visibility) return true; + return visibility[tab.id as keyof InfoVisibility]; + }); - const tabs = [...builtinTabs, ...customTabs]; + const customTabs = extraPages.map((p) => { + const label = p.title[locale] || p.title['ru'] || p.title['en'] || p.slug; + return { id: p.slug, label, icon: DocumentIcon, emoji: p.icon ?? undefined }; + }); + + return [...visibleBuiltinTabs, ...customTabs]; + }, [visibility, tabReplacements, extraPages, locale, t]); + + useEffect(() => { + if (tabs.length === 0) return; + if (!tabs.some((tab) => tab.id === activeTab)) { + setActiveTab(tabs[0].id); + } + }, [tabs, activeTab]); const toggleFaq = useCallback((id: number) => { setExpandedFaq((prev) => (prev === id ? null : id));