import React, { useState, useEffect, useCallback } from 'react'; import { View, Text, StyleSheet, FlatList, TouchableOpacity, SafeAreaView, Alert, ActivityIndicator } from 'react-native'; import { useTheme, useFocusEffect } from '@react-navigation/native'; import { useRouter } from 'expo-router'; import { Ionicons } from '@expo/vector-icons'; import { useAuth } from '../context/AuthProvider'; import { useAppTheme } from '../theme/ThemeProvider'; import CustomDrawer from '../components/CustomDrawer'; import { getArchivedConversations, getMessages, deleteConversation, unarchiveConversation } from '../services/conversation'; import { supabase } from '../utils/supabase'; // Typendefinitionen für Konversationen type ConversationItem = { id: string; modelName: string; title: string; lastMessage: string; timestamp: Date; mode: 'frei' | 'geführt' | 'vorlage'; }; // Hilfsfunktion zur Formatierung des Datums const formatDate = (date: Date) => { const day = date.getDate().toString().padStart(2, '0'); const month = new Intl.DateTimeFormat('de-DE', { month: 'short' }).format(date); const hours = date.getHours().toString().padStart(2, '0'); const minutes = date.getMinutes().toString().padStart(2, '0'); return `${day}. ${month}, ${hours}:${minutes}`; }; export default function ArchiveScreen() { const { colors } = useTheme(); const router = useRouter(); const { user } = useAuth(); const [conversations, setConversations] = useState([]); const [isLoading, setIsLoading] = useState(true); const { isDarkMode } = useAppTheme(); const [isDrawerOpen, setIsDrawerOpen] = useState(false); // Eine Funktion, die Konversationen lädt und wiederverwendet werden kann const loadConversations = async () => { if (!user) return; setIsLoading(true); try { console.log("Lade archivierte Konversationen für User:", user.id); // Lade alle archivierten Konversationen des Benutzers const userConversations = await getArchivedConversations(user.id); console.log(`${userConversations.length} archivierte Konversationen geladen`, new Date().toLocaleTimeString()); // Lade für jede Konversation die letzte Nachricht und das Modell const conversationItems: ConversationItem[] = []; for (const conv of userConversations) { try { // Lade die Nachrichten der Konversation const messages = await getMessages(conv.id); // Lade das Modell aus der Datenbank const { data: modelData } = await supabase .from('models') .select('name') .eq('id', conv.model_id) .single(); // Finde die letzte Nachricht (die nicht vom System ist) const lastMessage = messages .filter(msg => msg.sender !== 'system') .sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime())[0]; if (lastMessage) { conversationItems.push({ id: conv.id, modelName: modelData?.name || 'Unbekanntes Modell', title: conv.title || 'Unbenannte Konversation', lastMessage: lastMessage.message_text, timestamp: new Date(conv.updated_at), mode: conv.conversation_mode === 'free' ? 'frei' : conv.conversation_mode === 'guided' ? 'geführt' : 'vorlage' }); } } catch (error) { console.error(`Fehler beim Laden der Details für Konversation ${conv.id}:`, error); } } setConversations(conversationItems); } catch (error) { console.error('Fehler beim Laden der Konversationen:', error); Alert.alert('Fehler', 'Die Konversationen konnten nicht geladen werden.'); } finally { setIsLoading(false); } }; // Lade die Konversationen beim ersten Rendern und wenn sich der User ändert useEffect(() => { loadConversations(); }, [user]); // Lade Konversationen erneut, wenn der Screen fokussiert wird useFocusEffect( useCallback(() => { if (user) loadConversations(); return () => {}; }, [user]) ); const handleConversationPress = (id: string) => { // Navigiere zum Konversations-Screen mit der ID router.push(`/conversation/${id}`); }; // Löschen einer Konversation const handleDeleteConversation = (id: string) => { Alert.alert( "Konversation löschen", "Möchtest du diese Konversation wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.", [ { text: "Abbrechen", style: "cancel" }, { text: "Löschen", style: "destructive", onPress: async () => { try { const success = await deleteConversation(id); if (success) { // Aus der lokalen Liste entfernen setConversations(prev => prev.filter(conv => conv.id !== id)); Alert.alert("Erfolg", "Die Konversation wurde gelöscht."); } else { Alert.alert("Fehler", "Die Konversation konnte nicht gelöscht werden."); } } catch (error) { console.error('Fehler beim Löschen der Konversation:', error); Alert.alert("Fehler", "Die Konversation konnte nicht gelöscht werden."); } } } ] ); }; // Wiederherstellen einer archivierten Konversation const handleUnarchiveConversation = async (id: string) => { try { const success = await unarchiveConversation(id); if (success) { // Aus der lokalen Liste entfernen setConversations(prev => prev.filter(conv => conv.id !== id)); Alert.alert("Erfolg", "Die Konversation wurde wiederhergestellt."); } else { Alert.alert("Fehler", "Die Konversation konnte nicht wiederhergestellt werden."); } } catch (error) { console.error('Fehler beim Wiederherstellen der Konversation:', error); Alert.alert("Fehler", "Die Konversation konnte nicht wiederhergestellt werden."); } }; // Zustandsverwaltung für die Optionsmenüs der Konversationselemente const [expandedConversationId, setExpandedConversationId] = useState(null); // Toggle-Funktion für das Optionsmenü const toggleOptionsMenu = (id: string) => { setExpandedConversationId(expandedConversationId === id ? null : id); }; const renderConversationItem = ({ item }: { item: ConversationItem }) => { const showOptions = expandedConversationId === item.id; return ( handleConversationPress(item.id)} onLongPress={() => toggleOptionsMenu(item.id)} > {item.title} {formatDate(item.timestamp)} {item.modelName} {item.lastMessage} {item.mode === 'frei' ? 'Freier Modus' : item.mode === 'geführt' ? 'Geführter Modus' : 'Vorlagen-Modus'} toggleOptionsMenu(item.id)}> {showOptions && ( handleUnarchiveConversation(item.id)} > Wiederherstellen handleDeleteConversation(item.id)} > Löschen )} ); }; return ( {/* Permanenter Drawer links */} {isDrawerOpen && ( setIsDrawerOpen(false)} /> )} {/* Hauptinhalt */} setIsDrawerOpen(!isDrawerOpen)} > router.back()} > Archiv {/* Konversationsliste */} {isLoading ? ( Konversationen werden geladen... ) : conversations.length > 0 ? ( item.id} renderItem={renderConversationItem} contentContainerStyle={styles.listContent} /> ) : ( Keine archivierten Konversationen Archivierte Gespräche erscheinen hier )} ); } const styles = StyleSheet.create({ container: { flex: 1, }, mainLayout: { flex: 1, flexDirection: 'row', }, mainContainer: { flex: 1, alignItems: 'center', }, drawerContainer: { width: 260, height: '100%', position: 'absolute', left: 0, top: 0, bottom: 0, zIndex: 10, }, contentContainer: { flex: 1, maxWidth: 1200, width: '100%', }, headerContainer: { flexDirection: 'row', alignItems: 'center', width: '100%', paddingHorizontal: 16, paddingTop: 12, paddingBottom: 8, }, menuButton: { padding: 12, marginRight: 0, zIndex: 5, }, headerContentContainer: { flex: 1, flexDirection: 'row', alignItems: 'center', }, backButton: { padding: 8, marginRight: 8, }, title: { fontSize: 24, fontWeight: 'bold', }, listContainer: { flex: 1, width: '100%', maxWidth: 800, alignSelf: 'center', }, listContent: { paddingHorizontal: 16, paddingBottom: 120, width: '100%', maxWidth: 800, alignSelf: 'center', }, conversationItemWrapper: { borderRadius: 12, marginTop: 12, overflow: 'hidden', }, conversationItem: { flexDirection: 'row', alignItems: 'center', padding: 16, }, conversationContent: { flex: 1, }, optionsContainer: { flexDirection: 'row', justifyContent: 'flex-end', paddingHorizontal: 16, paddingBottom: 12, paddingTop: 4, borderTopWidth: StyleSheet.hairlineWidth, borderTopColor: 'rgba(0,0,0,0.1)', }, optionButton: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 16, paddingVertical: 8, marginLeft: 12, }, optionText: { fontSize: 14, marginLeft: 6, fontWeight: '500', }, conversationHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6, }, titleRow: { flexDirection: 'row', alignItems: 'center', flex: 1, }, titleIcon: { marginRight: 8, }, timestamp: { fontSize: 12, }, modelContainer: { flexDirection: 'row', alignItems: 'center', marginBottom: 6, }, modelName: { fontSize: 12, fontWeight: '400', }, lastMessage: { fontSize: 14, marginBottom: 6, }, modeContainer: { flexDirection: 'row', alignItems: 'center', }, modeText: { fontSize: 12, }, // Container für den Ladezustand loadingContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', paddingHorizontal: 32, marginTop: 40, }, loadingText: { fontSize: 16, marginTop: 16, textAlign: 'center', }, emptyContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', paddingHorizontal: 32, marginTop: 40, }, emptyText: { fontSize: 18, fontWeight: '600', marginTop: 16, textAlign: 'center', }, emptySubtext: { fontSize: 14, marginTop: 8, textAlign: 'center', }, });