import React from 'react'; import { Link, useParams } from 'react-router-dom'; import { YStack, XStack } from '@tamagui/stacks'; import { SizableText as Text } from '@tamagui/text'; import { Button } from '@tamagui/button'; import { Input } from '@tamagui/input'; import { Loader2, RefreshCcw, Search } from 'lucide-react'; import AppShell from '../components/AppShell'; import StandaloneShell from '../components/StandaloneShell'; import SurfaceCard from '../components/SurfaceCard'; import PullToRefresh from '@/guest/components/PullToRefresh'; import { getHelpArticles, type HelpArticleSummary } from '@/guest/services/helpApi'; import { useLocale } from '@/guest/i18n/LocaleContext'; import { useTranslation } from '@/guest/i18n/useTranslation'; import EventLogo from '../components/EventLogo'; import { useGuestThemeVariant } from '../lib/guestTheme'; export default function HelpCenterScreen() { const params = useParams<{ token?: string }>(); const { locale } = useLocale(); const { t } = useTranslation(); const { isDark } = useGuestThemeVariant(); const mutedText = isDark ? 'rgba(248, 250, 252, 0.7)' : 'rgba(15, 23, 42, 0.65)'; const [articles, setArticles] = React.useState([]); const [query, setQuery] = React.useState(''); const [state, setState] = React.useState<'idle' | 'loading' | 'ready' | 'error'>('loading'); const [servedFromCache, setServedFromCache] = React.useState(false); const [isOnline, setIsOnline] = React.useState(() => (typeof navigator !== 'undefined' ? navigator.onLine : true)); const basePath = params.token ? `/e/${encodeURIComponent(params.token)}/help` : '/help'; const brandName = 'Fotospiel'; const showStandaloneHeader = !params.token; const loadArticles = React.useCallback(async (forceRefresh = false) => { setState('loading'); try { const result = await getHelpArticles(locale, { forceRefresh }); setArticles(result.articles); setServedFromCache(result.servedFromCache); setState('ready'); } catch (error) { console.error('[HelpCenter] Failed to load articles', error); setState('error'); } }, [locale]); React.useEffect(() => { loadArticles(); }, [loadArticles]); React.useEffect(() => { if (typeof window === 'undefined') return; const handleOnline = () => setIsOnline(true); const handleOffline = () => setIsOnline(false); window.addEventListener('online', handleOnline); window.addEventListener('offline', handleOffline); return () => { window.removeEventListener('online', handleOnline); window.removeEventListener('offline', handleOffline); }; }, []); const showOfflineBadge = servedFromCache && !isOnline; const filteredArticles = React.useMemo(() => { if (!query.trim()) return articles; const needle = query.trim().toLowerCase(); return articles.filter((article) => `${article.title} ${article.summary}`.toLowerCase().includes(needle)); }, [articles, query]); const wrapper = ( loadArticles(true)} pullLabel={t('common.pullToRefresh')} releaseLabel={t('common.releaseToRefresh')} refreshingLabel={t('common.refreshing')} > {showStandaloneHeader ? : null} {t('help.center.title')} {t('help.center.subtitle')} setQuery(event.currentTarget.value)} aria-label={t('help.center.searchPlaceholder')} /> {showOfflineBadge ? ( {t('help.center.offlineDescription')} ) : null} {t('help.center.listTitle')} {state === 'loading' ? ( {t('common.actions.loading')} ) : null} {state === 'error' ? ( {t('help.center.error')} ) : null} {state === 'ready' && filteredArticles.length === 0 ? ( {t('help.center.empty')} ) : null} {state === 'ready' && filteredArticles.length > 0 ? ( {filteredArticles.map((article) => ( {article.title} {article.summary} ))} ) : null} ); if (params.token) { return {wrapper}; } return {wrapper}; }