import { useState } from 'react'; import { ActivityIndicator, Alert, ScrollView, Text, TouchableOpacity, View, } from 'react-native'; import { useBottomTabBarHeight } from 'react-native-bottom-tabs'; import { useTranslation } from 'react-i18next'; import { Ionicons } from '@expo/vector-icons'; import { AppHeader } from '../../components/AppHeader'; import { MailStatsRow } from '../../components/mail/MailStatsRow'; import { MailAccountCard } from '../../components/mail/MailAccountCard'; import { MailEmptyState } from '../../components/mail/MailEmptyState'; import { MailActivityLog } from '../../components/mail/MailActivityLog'; import { MailBlockedByDayChart } from '../../components/mail/MailBlockedByDayChart'; import { MailDistributionChart } from '../../components/mail/MailDistributionChart'; import { ConnectMailSheet } from '../../components/mail/ConnectMailSheet'; import { EditMailTitleSheet } from '../../components/mail/EditMailTitleSheet'; import { SuccessAlert } from '../../components/SuccessAlert'; import { useMailStatus } from '../../hooks/useMailStatus'; import { useMailDisconnect } from '../../hooks/useMailDisconnect'; import { useMailStats } from '../../hooks/useMailStats'; import { useUserPlan } from '../../hooks/useUserPlan'; import { useColors } from '../../lib/theme'; import { useMailConnectDraft } from '../../stores/mailConnectDraft'; const PLAN_LABEL: Record = { free: 'Free', pro: 'Pro', legend: 'Legend' }; function MailOverLimitBanner({ usedCount, maxAccounts, planLabel, pausedEmails, colors, }: { usedCount: number; maxAccounts: number; planLabel: string; pausedEmails: string[]; colors: import('../../lib/theme').ColorScheme; }) { const { t } = useTranslation(); const over = usedCount - maxAccounts; if (over <= 0) return null; return ( {t('plan_limit.mail_banner_title')} {t(over === 1 ? 'plan_limit.mail_banner_body_one' : 'plan_limit.mail_banner_body_other', { used: usedCount, plan: planLabel, max: maxAccounts, over, })} {pausedEmails.length > 0 && ( {pausedEmails.join(', ')} )} ); } export default function MailScreen() { const { t } = useTranslation(); const tabBarHeight = useBottomTabBarHeight(); const colors = useColors(); const { plan } = useUserPlan(); const { connected, accounts, totalBlocked, maxAccounts, loading, refresh } = useMailStatus(plan); const { disconnect, disconnecting } = useMailDisconnect(); const hasAccounts = accounts.length > 0; const { blockedByDay, blockedByConnection } = useMailStats(hasAccounts); const [sheetVisible, setSheetVisible] = useState(false); const [successVisible, setSuccessVisible] = useState(false); const [disconnectingId, setDisconnectingId] = useState(null); const [expandedAccount, setExpandedAccount] = useState(null); const [activityLogExpanded, setActivityLogExpanded] = useState(false); const [oauthTitleSheetConnectionId, setOauthTitleSheetConnectionId] = useState(null); const { pendingOAuthConnectionId, setPendingOAuthConnectionId } = useMailConnectDraft(); const nextScanAt = accounts .map((a) => a.nextScanAt) .filter((v): v is string => v !== null) .sort()[0] ?? null; const pausedAccounts = accounts.filter((a) => a.paused === true); const overLimit = maxAccounts !== Infinity && accounts.length > maxAccounts; const limitReached = maxAccounts !== Infinity && accounts.length >= maxAccounts; const distinctProviders = [ ...new Set(accounts.map((a) => a.provider.toLowerCase())), ]; function handleAddPress() { if (limitReached) { Alert.alert(t('mail.upgrade_alert_title'), t('mail.upgrade_alert_desc')); return; } setSheetVisible(true); } async function handleDisconnect(id: string) { setDisconnectingId(id); await disconnect(id); setDisconnectingId(null); if (expandedAccount === id) setExpandedAccount(null); refresh(); } function handleConnectSuccess() { refresh(); if (pendingOAuthConnectionId) { setOauthTitleSheetConnectionId(pendingOAuthConnectionId); setPendingOAuthConnectionId(null); } else { setSuccessVisible(true); } } function toggleAccount(id: string) { setExpandedAccount((prev) => (prev === id ? null : id)); } if (loading) { return ( ); } return ( {/* Über-Limit-Banner */} {overLimit && pausedAccounts.length > 0 && ( a.email)} colors={colors} /> )} {/* Stats card */} {hasAccounts && ( )} {/* Section header + add button */} {hasAccounts && ( {t('mail.section_accounts')} {maxAccounts === Infinity ? t('mail.section_accounts_count_unlimited', { used: accounts.length }) : t('mail.section_accounts_count', { used: accounts.length, max: maxAccounts, })} {t('mail.add_account')} )} {/* Account cards or empty */} {accounts.length === 0 ? ( ) : ( {accounts.map((account, idx) => { const connStat = blockedByConnection.find((c) => c.connectionId === account.id); return ( toggleAccount(account.id)} onDisconnect={handleDisconnect} onIntervalChanged={refresh} onEditSuccess={handleConnectSuccess} disconnecting={disconnectingId === account.id && disconnecting} blockedLast30d={connStat?.count} /> ); })} )} {/* Charts — nur wenn Accounts vorhanden */} {hasAccounts && ( )} {/* Activity log */} {hasAccounts && ( setActivityLogExpanded((p) => !p)} providers={distinctProviders} /> )} setSheetVisible(false)} onSuccess={handleConnectSuccess} /> {oauthTitleSheetConnectionId && ( { setOauthTitleSheetConnectionId(null); setSuccessVisible(true); }} onSuccess={() => { setOauthTitleSheetConnectionId(null); setSuccessVisible(true); refresh(); }} /> )} setSuccessVisible(false)} /> ); }