import { useState } from 'react'; import { ActivityIndicator, Image, Text, TouchableOpacity, View, } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; import { useTranslation } from 'react-i18next'; import { isValidDomain, normalizeDomain, type Tier, } from '../../hooks/useCustomDomains'; import { useColors, type ColorScheme } from '../../lib/theme'; import { FormSheet } from '../FormSheet'; import { SheetFieldStack } from '../SheetFieldStack'; type InputKind = 'web' | 'mail'; type Props = { visible: boolean; tier: Tier; onClose: () => void; onAdd: (pattern: string, kind: InputKind) => Promise<{ ok: boolean; error?: string; alreadyGlobal?: boolean }>; }; export function AddDomainSheet({ visible, tier, onClose, onAdd }: Props) { const { t } = useTranslation(); const colors = useColors(); const [kind, setKind] = useState('web'); const [input, setInput] = useState(''); const [confirmPermanent, setConfirmPermanent] = useState(false); const [adding, setAdding] = useState(false); const [error, setError] = useState(null); const [fieldsDone, setFieldsDone] = useState(false); const normalizedWeb = kind === 'web' ? normalizeDomain(input) : ''; function close() { setInput(''); setConfirmPermanent(false); setError(null); setFieldsDone(false); onClose(); } function handleKindChange(next: InputKind) { if (next === kind) return; setKind(next); setInput(''); setError(null); setFieldsDone(false); } function isInputValid(): boolean { if (kind === 'web') return isValidDomain(input); return input.trim().length > 0; } async function handleAdd() { if (!isInputValid() || !confirmPermanent || adding) return; setAdding(true); setError(null); const pattern = kind === 'web' ? input : input.trim(); const result = await onAdd(pattern, kind); setAdding(false); if (result.ok) { close(); return; } if (result.alreadyGlobal) { setError(t('blocker.add_sheet_already_global', { domain: normalizedWeb || input.trim() })); } else { setError(result.error ?? t('blocker.add_sheet_add_failed')); } } const warningText = tier.plan === 'free' ? t('blocker.add_sheet_warning_free') : t('blocker.add_sheet_warning_pro'); const inputLabel = kind === 'web' ? t('blocker.add_web_label') : t('blocker.add_mail_label'); const inputPlaceholder = kind === 'web' ? t('blocker.add_web_placeholder') : t('blocker.add_mail_placeholder'); const helpText = kind === 'web' ? t('blocker.add_web_help') : t('blocker.add_mail_help'); const validateField = kind === 'web' ? (v: string) => isValidDomain(v) ? undefined : t('blocker.add_sheet_invalid') : (v: string) => v.trim().length > 0 ? undefined : t('blocker.add_mail_invalid'); return ( } fields={[ { key: 'pattern', label: inputLabel, placeholder: inputPlaceholder, value: input, onChangeText: (v) => { setInput(v); setError(null); }, normalize: kind === 'web' ? normalizeDomain : undefined, keyboardType: kind === 'web' ? 'url' : 'default', autoCapitalize: 'none', autoCorrect: false, validate: validateField, }, ]} onComplete={() => setFieldsDone(true)} > {/* Help-Text */} {helpText} {/* Favicon-Preview (nur Web) */} {kind === 'web' && ( {normalizedWeb} )} {/* Mail-Typ Icon-Preview */} {kind === 'mail' && ( {input.trim() || inputPlaceholder} )} {/* Warnung */} {warningText} {/* Confirm-Checkbox */} setConfirmPermanent((v) => !v)} activeOpacity={0.7} style={{ flexDirection: 'row', alignItems: 'flex-start', gap: 10, paddingVertical: 4, marginBottom: 14, }} > {confirmPermanent && } {t('blocker.add_sheet_confirm_permanent')} {error && ( {error} )} {/* Add-Button */} {adding ? ( ) : ( {t('blocker.add_sheet_title')} )} ); } // ─── TypePicker ────────────────────────────────────────────────────────────── function TypePicker({ kind, onChange }: { kind: InputKind; onChange: (k: InputKind) => void }) { const { t } = useTranslation(); const colors = useColors(); return ( onChange('web')} colors={colors} /> onChange('mail')} colors={colors} /> ); } function TypePill({ icon, label, active, onPress, colors, }: { icon: 'globe-outline' | 'mail-outline'; label: string; active: boolean; onPress: () => void; colors: ColorScheme; }) { return ( {label} ); }