import React from 'react'; import { YStack, XStack } from '@tamagui/stacks'; import { SizableText as Text } from '@tamagui/text'; import { Button } from '@tamagui/button'; import { Share2, QrCode, Link, Users, Loader2, RefreshCcw } from 'lucide-react'; import AppShell from '../components/AppShell'; import { useEventData } from '../context/EventDataContext'; import { buildEventShareLink } from '../services/eventLink'; import { usePollStats } from '../hooks/usePollStats'; import { fetchEventQrCode } from '../services/qrApi'; import { useGuestThemeVariant } from '../lib/guestTheme'; import { useTranslation } from '@/shared/guest/i18n/useTranslation'; import { getBentoSurfaceTokens } from '../lib/bento'; import { pushGuestToast } from '../lib/toast'; export default function ShareScreen() { const { event, token } = useEventData(); const { t } = useTranslation(); const { isDark } = useGuestThemeVariant(); const surface = getBentoSurfaceTokens(isDark); const [copyState, setCopyState] = React.useState<'idle' | 'copied' | 'failed'>('idle'); const { stats } = usePollStats(token ?? null); const [qrCodeDataUrl, setQrCodeDataUrl] = React.useState(''); const [qrLoading, setQrLoading] = React.useState(false); const [qrError, setQrError] = React.useState(false); const shareUrl = buildEventShareLink(event, token); const loadQrCode = React.useCallback(async () => { if (!token) return; setQrLoading(true); setQrError(false); try { const payload = await fetchEventQrCode(token, 240); setQrCodeDataUrl(payload.qr_code_data_url ?? ''); } catch (error) { console.error('Failed to load QR code', error); setQrCodeDataUrl(''); setQrError(true); } finally { setQrLoading(false); } }, [token]); const handleCopy = React.useCallback(async () => { if (!shareUrl) { return; } try { await navigator.clipboard?.writeText(shareUrl); setCopyState('copied'); pushGuestToast({ text: t('share.copySuccess', 'Link copied!'), type: 'success' }); } catch (error) { console.error('Copy failed', error); setCopyState('failed'); pushGuestToast({ text: t('share.copyError', 'Link could not be copied.'), type: 'error' }); } finally { window.setTimeout(() => setCopyState('idle'), 2000); } }, [shareUrl, t]); const handleShare = React.useCallback(async () => { if (!shareUrl) return; const title = event?.name ?? t('share.defaultEvent', 'Fotospiel'); const data: ShareData = { title, text: title, url: shareUrl }; if (navigator.share && (!navigator.canShare || navigator.canShare(data))) { try { await navigator.share(data); } catch (error) { // user dismissed } } else { await handleCopy(); } }, [event?.name, handleCopy, shareUrl]); React.useEffect(() => { if (!token) { setQrCodeDataUrl(''); setQrLoading(false); setQrError(false); return; } loadQrCode(); }, [loadQrCode, token]); const guestCountLabel = (stats.onlineGuests ?? 0).toString(); const inviteDisabled = !shareUrl; return ( {t('share.invite.title', 'Invite guests')} {t('share.invite.description', 'Share the event link or show the QR code to join.')} {qrCodeDataUrl ? ( {t('share.invite.qrAlt', ) : qrLoading ? ( ) : ( )} {t('share.invite.qrLabel', 'Show QR')} {qrLoading ? ( {t('share.invite.qrLoading', 'Generating QR…')} ) : null} {qrError ? ( ) : null} {copyState === 'copied' ? t('share.copySuccess', 'Copied') : copyState === 'failed' ? t('share.copyError', 'Copy failed') : t('share.invite.copyLabel', 'Copy link')} {shareUrl ? ( {shareUrl} ) : null} {t('share.invite.guestsTitle', 'Guests joined')} {guestCountLabel} {t('home.stats.online', 'Guests online')} {event?.name ? t('share.invite.guestsSubtitleEvent', { event: event.name }, 'Share {event} with your guests.') : t('share.invite.guestsSubtitle', 'Share the event with your guests.')} ); }