import React, { useState } from 'react'; import { View, Text, TextInput, TouchableOpacity, StyleSheet, ScrollView, KeyboardAvoidingView, Platform, ActivityIndicator, Alert, } from 'react-native'; import { useTheme } from '@react-navigation/native'; import { useRouter, Stack } from 'expo-router'; import { Ionicons } from '@expo/vector-icons'; import { useAuth } from '~/context/AuthProvider'; import { useComposeStore } from '~/store/composeStore'; import { useEmailsStore } from '~/store/emailsStore'; import { useAppTheme } from '~/theme/ThemeProvider'; export default function ComposeScreen() { const { colors } = useTheme(); const { isDarkMode } = useAppTheme(); const router = useRouter(); const { getToken } = useAuth(); const { selectedAccountId, accounts } = useEmailsStore(); const { subject, toAddresses, ccAddresses, bodyHtml, sending, loading, updateForm, saveDraft, send, closeCompose, } = useComposeStore(); const [showCc, setShowCc] = useState(ccAddresses.length > 0); const [toInput, setToInput] = useState(toAddresses.map((a) => a.email).join(', ')); const [ccInput, setCcInput] = useState(ccAddresses.map((a) => a.email).join(', ')); const [bodyText, setBodyText] = useState(bodyHtml || ''); const selectedAccount = accounts.find((a) => a.id === selectedAccountId); const parseEmailAddresses = (input: string) => { return input .split(',') .map((email) => email.trim()) .filter((email) => email.length > 0) .map((email) => ({ email })); }; const handleSend = async () => { const to = parseEmailAddresses(toInput); if (to.length === 0) { Alert.alert('Error', 'Please add at least one recipient'); return; } updateForm({ accountId: selectedAccountId || '', toAddresses: to, ccAddresses: parseEmailAddresses(ccInput), subject, bodyHtml: bodyText, }); const token = await getToken(); if (!token) return; const success = await send(token); if (success) { router.back(); } }; const handleSaveDraft = async () => { updateForm({ accountId: selectedAccountId || '', toAddresses: parseEmailAddresses(toInput), ccAddresses: parseEmailAddresses(ccInput), subject, bodyHtml: bodyText, }); const token = await getToken(); if (!token) return; const draft = await saveDraft(token); if (draft) { Alert.alert('Saved', 'Draft has been saved'); } }; const handleClose = () => { if (toInput || subject || bodyText) { Alert.alert('Discard Draft?', 'Do you want to save this email as a draft?', [ { text: 'Discard', style: 'destructive', onPress: () => { closeCompose(); router.back(); }, }, { text: 'Save Draft', onPress: async () => { await handleSaveDraft(); router.back(); }, }, { text: 'Cancel', style: 'cancel' }, ]); } else { closeCompose(); router.back(); } }; return ( ( ), headerRight: () => ( {sending ? ( ) : ( )} ), }} /> {/* From */} From {selectedAccount?.email || 'Select account'} {/* To */} To {!showCc && ( setShowCc(true)}> Cc )} {/* Cc */} {showCc && ( Cc )} {/* Subject */} Subject updateForm({ subject: text })} /> {/* Body */} ); } const styles = StyleSheet.create({ container: { flex: 1, }, headerButton: { padding: 8, }, headerActions: { flexDirection: 'row', alignItems: 'center', }, sendButton: { marginLeft: 12, width: 40, height: 40, borderRadius: 20, justifyContent: 'center', alignItems: 'center', }, content: { flex: 1, }, field: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 16, paddingVertical: 12, borderBottomWidth: StyleSheet.hairlineWidth, }, fieldLabel: { width: 60, fontSize: 14, }, fieldInput: { flex: 1, fontSize: 16, }, fromEmail: { flex: 1, fontSize: 16, }, ccToggle: { fontSize: 14, fontWeight: '600', paddingHorizontal: 8, }, bodyContainer: { flex: 1, minHeight: 300, }, bodyInput: { flex: 1, fontSize: 16, padding: 16, lineHeight: 24, }, });