'use client' import { useState, useEffect, useCallback } from 'react' import { useRouter } from 'next/navigation' import { BPIcon } from '@/components/Logo' import { useLanguage } from '@/lib/LanguageContext' import { useTheme } from '@/lib/ThemeContext' import { useAlerts, getImportanceColor, getRelativeTime } from '@/lib/AlertsContext' import { useMessages, formatMessageTime, getContactInitials } from '@/lib/MessagesContext' import { useActivity, formatDurationCompact } from '@/lib/ActivityContext' import { LanguageDropdown } from '@/components/LanguageDropdown' import { ThemeToggle } from '@/components/ThemeToggle' import { Footer } from '@/components/Footer' import { Sidebar } from '@/components/Sidebar' import { OnboardingWizard, OnboardingData } from '@/components/OnboardingWizard' import { DocumentUpload } from '@/components/DocumentUpload' import { QRCodeUpload } from '@/components/QRCodeUpload' import { DocumentSpace } from '@/components/DocumentSpace' import { ChatOverlay } from '@/components/ChatOverlay' import { AiPrompt } from '@/components/AiPrompt' // LocalStorage Keys const ONBOARDING_KEY = 'bp_onboarding_complete' const USER_DATA_KEY = 'bp_user_data' const DOCUMENTS_KEY = 'bp_documents' const FIRST_VISIT_KEY = 'bp_first_dashboard_visit' const SESSION_ID_KEY = 'bp_session_id' // BreakPilot Studio v2 - Glassmorphism Design interface StoredDocument { id: string name: string type: string size: number uploadedAt: Date url?: string } export default function HomePage() { const router = useRouter() const [selectedTab, setSelectedTab] = useState('dashboard') const [showOnboarding, setShowOnboarding] = useState(null) const [userData, setUserData] = useState(null) const [documents, setDocuments] = useState([]) const [showUploadModal, setShowUploadModal] = useState(false) const [showQRModal, setShowQRModal] = useState(false) const [isFirstVisit, setIsFirstVisit] = useState(false) const [sessionId, setSessionId] = useState('') const [showAlertsDropdown, setShowAlertsDropdown] = useState(false) const { t } = useLanguage() const { isDark } = useTheme() const { alerts, unreadCount, markAsRead } = useAlerts() const { conversations, unreadCount: messagesUnreadCount, contacts, markAsRead: markMessageAsRead } = useMessages() const { stats: activityStats } = useActivity() // Funktion zum Laden von Uploads aus der API const fetchUploadsFromAPI = useCallback(async (sid: string) => { if (!sid) return try { const response = await fetch(`/api/uploads?sessionId=${encodeURIComponent(sid)}`) if (response.ok) { const data = await response.json() if (data.uploads && data.uploads.length > 0) { // Konvertiere API-Uploads zu StoredDocument Format const apiDocs: StoredDocument[] = data.uploads.map((u: any) => ({ id: u.id, name: u.name, type: u.type, size: u.size, uploadedAt: new Date(u.uploadedAt), url: u.dataUrl // Data URL direkt verwenden })) // Merge mit existierenden Dokumenten (ohne Duplikate) setDocuments(prev => { const existingIds = new Set(prev.map(d => d.id)) const newDocs = apiDocs.filter(d => !existingIds.has(d.id)) if (newDocs.length > 0) { return [...prev, ...newDocs] } return prev }) } } } catch (error) { console.error('Error fetching uploads:', error) } }, []) // Prüfe beim Laden, ob Onboarding abgeschlossen ist useEffect(() => { const onboardingComplete = localStorage.getItem(ONBOARDING_KEY) const storedUserData = localStorage.getItem(USER_DATA_KEY) const storedDocs = localStorage.getItem(DOCUMENTS_KEY) const firstVisit = localStorage.getItem(FIRST_VISIT_KEY) let storedSessionId = localStorage.getItem(SESSION_ID_KEY) // Session ID generieren falls nicht vorhanden if (!storedSessionId) { storedSessionId = `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}` localStorage.setItem(SESSION_ID_KEY, storedSessionId) } setSessionId(storedSessionId) if (onboardingComplete === 'true' && storedUserData) { setUserData(JSON.parse(storedUserData)) setShowOnboarding(false) // Dokumente laden if (storedDocs) { setDocuments(JSON.parse(storedDocs)) } // Erster Dashboard-Besuch nach Onboarding? if (!firstVisit) { setIsFirstVisit(true) localStorage.setItem(FIRST_VISIT_KEY, 'true') } // Initialer Fetch von der API fetchUploadsFromAPI(storedSessionId) } else { setShowOnboarding(true) } }, [fetchUploadsFromAPI]) // Polling fuer neue Uploads von der API (alle 3 Sekunden) useEffect(() => { if (!sessionId || showOnboarding) return const interval = setInterval(() => { fetchUploadsFromAPI(sessionId) }, 3000) return () => clearInterval(interval) }, [sessionId, showOnboarding, fetchUploadsFromAPI]) // Dokumente in localStorage speichern useEffect(() => { if (documents.length > 0) { localStorage.setItem(DOCUMENTS_KEY, JSON.stringify(documents)) } }, [documents]) // Handler fuer neue Uploads const handleUploadComplete = (uploadedDocs: any[]) => { const newDocs: StoredDocument[] = uploadedDocs.map(d => ({ id: d.id, name: d.name, type: d.type, size: d.size, uploadedAt: d.uploadedAt, url: d.url })) setDocuments(prev => [...prev, ...newDocs]) setIsFirstVisit(false) } // Dokument loeschen (aus State und API) const handleDeleteDocument = async (id: string) => { setDocuments(prev => prev.filter(d => d.id !== id)) // Auch aus API loeschen try { await fetch(`/api/uploads?id=${encodeURIComponent(id)}`, { method: 'DELETE' }) } catch (error) { console.error('Error deleting from API:', error) } } // Dokument umbenennen const handleRenameDocument = (id: string, newName: string) => { setDocuments(prev => prev.map(d => d.id === id ? { ...d, name: newName } : d)) } // Onboarding abschließen const handleOnboardingComplete = (data: OnboardingData) => { localStorage.setItem(ONBOARDING_KEY, 'true') localStorage.setItem(USER_DATA_KEY, JSON.stringify(data)) setUserData(data) setShowOnboarding(false) } // Zeige Ladebildschirm während der Prüfung if (showOnboarding === null) { return (
Laden...
) } // Zeige Onboarding falls noch nicht abgeschlossen if (showOnboarding) { return } // Ab hier: Dashboard (bestehender Code) // Calculate time saved from activity tracking const timeSaved = formatDurationCompact(activityStats.weekSavedSeconds) const timeSavedDisplay = activityStats.weekSavedSeconds > 0 ? `${timeSaved.value}${timeSaved.unit}` : '0min' const stats = [ { labelKey: 'stat_open_corrections', value: '12', icon: '📋', color: 'from-blue-400 to-blue-600' }, { labelKey: 'stat_completed_week', value: String(activityStats.activityCount), icon: '✅', color: 'from-green-400 to-green-600' }, { labelKey: 'stat_average', value: '2.3', icon: '📈', color: 'from-purple-400 to-purple-600' }, { labelKey: 'stat_time_saved', value: timeSavedDisplay, icon: '⏱', color: 'from-orange-400 to-orange-600' }, ] const recentKlausuren = [ { id: 1, title: 'Deutsch LK - Textanalyse', students: 24, completed: 18, statusKey: 'status_in_progress' }, { id: 2, title: 'Deutsch GK - Erörterung', students: 28, completed: 28, statusKey: 'status_completed' }, { id: 3, title: 'Vorabitur - Gedichtanalyse', students: 22, completed: 10, statusKey: 'status_in_progress' }, ] return (
{/* Animated Background Blobs */}
{/* Sidebar */} {/* ============================================ ARBEITSFLAECHE (Main Content) ============================================ */}
{/* Kopfleiste (Header) */}

{t('dashboard')}

{t('dashboard_subtitle')}

{/* Search, Language & Actions */}
{/* Language Dropdown */} {/* Theme Toggle */} {/* Notifications Bell with Glow Effect */}
{/* Alerts Dropdown */} {showAlertsDropdown && ( <>
setShowAlertsDropdown(false)} />

Aktuelle Alerts

{unreadCount > 0 && ( {unreadCount} neu )}
{alerts.slice(0, 5).map(alert => ( ))} {alerts.length === 0 && (
📭

Keine Alerts

)}
)}
{/* Willkommensnachricht fuer ersten Besuch */} {isFirstVisit && documents.length === 0 && (
🎉

Willkommen bei BreakPilot Studio!

Grossartig, dass Sie hier sind! Laden Sie jetzt Ihr erstes Dokument hoch, um die KI-gestuetzte Korrektur zu erleben. Sie koennen Dateien von Ihrem Computer oder Mobiltelefon hochladen.

)} {/* KI-Assistent */} {/* Stats Kacheln */}
{stats.map((stat, index) => (
{stat.icon}

{t(stat.labelKey)}

{stat.value}

))}
{/* Tab-Content */} {selectedTab === 'dokumente' ? ( /* Dokumente-Tab */
{/* Upload-Optionen */}
{/* Document Space */}

Meine Dokumente

doc.url && window.open(doc.url, '_blank')} />
) : ( /* Dashboard-Tab (Standard) */
{/* Aktuelle Klausuren Kachel */}

{t('recent_klausuren')}

{recentKlausuren.map((klausur) => (
📝

{klausur.title}

{klausur.students} {t('students')}

{t(klausur.statusKey)}
{klausur.completed}/{klausur.students}
))}
{/* Schnellaktionen Kachel */}

{t('quick_actions')}

{/* AI Insight mini */}
🤖 {t('ai_tip')}

{t('ai_tip_text')}

{/* Alerts Kachel */}

🔔 Aktuelle Alerts

{unreadCount > 0 && ( {unreadCount} neu )}
{/* Headlines Liste */}
{alerts.slice(0, 3).map(alert => ( ))} {alerts.length === 0 && (

Keine Alerts vorhanden

)}
{/* Mehr anzeigen */}
{/* Nachrichten Kachel */}

💬 {t('nav_messages')}

{messagesUnreadCount > 0 && ( {messagesUnreadCount} neu )}
{/* Conversations Liste */}
{conversations.slice(0, 3).map(conv => { const contact = contacts.find(c => conv.participant_ids.includes(c.id)) return ( ) })} {conversations.length === 0 && (

Keine Nachrichten vorhanden

)}
{/* Mehr anzeigen */}
)}
{/* Upload Modal */} {showUploadModal && (
setShowUploadModal(false)} />

Dokumente hochladen

{ handleUploadComplete(docs) }} /> {/* Aktions-Buttons */}

{documents.length > 0 ? `${documents.length} Dokument${documents.length !== 1 ? 'e' : ''} gespeichert` : 'Noch keine Dokumente'}

)} {/* QR Code Modal */} {showQRModal && (
setShowQRModal(false)} />
setShowQRModal(false)} />
)} {/* Diegetic Chat Overlay - Cinematic message notifications */} {/* Footer */}
) }