import { useEffect, useRef } from 'react'; import { Modal, View, Text, Pressable, Animated, Easing } from 'react-native'; // Wichtig (UX-Entscheidung 2026-05-05): Icon im Confirm-Modal NICHT animieren — // User sieht zwei Modals nacheinander (Confirm → Success), beide animierte Icons // = visuelle Doppel-Eskalation, wirkt verwirrend. Daher: Card animiert auf, // Icon erscheint statisch (kein scale-pop). Nur das nachfolgende SuccessAlert // behält seine Icon-Animation als "Belohnungs-Moment". import { Ionicons } from '@expo/vector-icons'; import { useTranslation } from 'react-i18next'; type Props = { visible: boolean; title: string; message?: string; /** Default: i18n "common.cancel" */ cancelLabel?: string; /** Default: i18n "common.confirm" */ confirmLabel?: string; /** Wenn true: Confirm-Button rot statt blau (für destructive Actions). */ destructive?: boolean; /** Icon im Top-Circle. Default: question-mark. */ icon?: React.ComponentProps['name']; /** Icon-Circle-Color. Default: #007AFF (iOS-blue). */ iconColor?: string; onConfirm: () => void; onCancel: () => void; }; /** * Animiertes iOS-style Confirm-Modal — gleicher Animations-Stil wie SuccessAlert, * aber mit zwei Buttons (Cancel + Confirm). Tap-outside cancelt. */ export function ConfirmAlert({ visible, title, message, cancelLabel, confirmLabel, destructive = false, icon = 'help-circle', iconColor = '#007AFF', onConfirm, onCancel, }: Props) { const { t } = useTranslation(); const resolvedCancelLabel = cancelLabel ?? t('common.cancel'); const resolvedConfirmLabel = confirmLabel ?? t('common.confirm'); const cardScale = useRef(new Animated.Value(0.8)).current; const cardOpacity = useRef(new Animated.Value(0)).current; useEffect(() => { if (visible) { cardScale.setValue(0.8); cardOpacity.setValue(0); Animated.parallel([ Animated.spring(cardScale, { toValue: 1, useNativeDriver: true, friction: 7, tension: 80, }), Animated.timing(cardOpacity, { toValue: 1, duration: 220, useNativeDriver: true, easing: Easing.out(Easing.cubic), }), ]).start(); } }, [visible, cardScale, cardOpacity]); const confirmBg = destructive ? '#FF3B30' : '#007AFF'; return ( {}} style={{ width: '85%', maxWidth: 340 }}> {/* Icon-Circle — statisch (keine Pop-Animation, siehe Header-Comment). */} {title} {message && ( {message} )} {/* Two buttons row */} {resolvedCancelLabel} {resolvedConfirmLabel} ); }