import React, { useEffect, useState } from 'react'; import { Layers, CheckSquare, FileText, ShoppingCart, Brain, } from 'lucide-react'; import { DashboardStats, SharedList, Thought, User } from './lib/types'; import { api, clearToken, getToken, triggerHaptic } from './lib/api'; import { InstantCaptureBar } from './features/capture/InstantCaptureBar'; import { TriageDeck } from './features/triage/TriageDeck'; import { TasksView } from './features/triage/TasksView'; import { WorkspaceView } from './features/workspace/WorkspaceView'; import { SharedListsView } from './features/lists/SharedListsView'; import { SettingsModal } from './features/settings/SettingsModal'; type ActiveTab = 'triage' | 'tasks' | 'workspace' | 'lists'; export const App: React.FC = () => { const [user, setUser] = useState(null); const [stats, setStats] = useState({ inboxCount: 0, tasksOpenCount: 0, tasksDoneCount: 0, docsCount: 0, listsCount: 0, discardedCount: 0, }); const [deck, setDeck] = useState([]); const [lists, setLists] = useState([]); const [activeTab, setActiveTab] = useState('triage'); const [selectedDocId, setSelectedDocId] = useState(null); const [captureFocusCount, setCaptureFocusCount] = useState(0); const [refreshRevision, setRefreshRevision] = useState(0); const [showProfileModal, setShowProfileModal] = useState(false); const refreshAll = async () => { try { const [meRes, deckRes, listsRes] = await Promise.all([ api.getMe(), api.getTriageDeck(), api.getAllLists(), ]); setUser(meRes.user); setStats(meRes.stats); setDeck(deckRes); setLists(listsRes); } catch { // Fallback to quickStart session try { const qs = await api.quickStart(); setUser(qs.user); const [st, dk, ls] = await Promise.all([ api.getStats(), api.getTriageDeck(), api.getAllLists(), ]); setStats(st); setDeck(dk); setLists(ls); } catch { // Offline or waiting for server } } }; useEffect(() => { const init = async () => { if (!getToken()) { try { await api.quickStart(); } catch { // ignore } } await api.flushOfflineQueue(); await refreshAll(); }; init(); const onOnline = async () => { const synced = await api.flushOfflineQueue(); if (synced > 0) refreshAll(); }; window.addEventListener('online', onOnline); return () => window.removeEventListener('online', onOnline); }, []); const handleCaptured = ( thought: Thought, target: 'inbox' | 'task' | 'list_item' | 'document' = 'inbox' ) => { if (target === 'inbox' && thought.status === 'inbox') { setDeck((prev) => [thought, ...prev]); setStats((prev) => ({ ...prev, inboxCount: prev.inboxCount + 1 })); } else if (target === 'document' && thought.convertedRefId) { setSelectedDocId(thought.convertedRefId); setActiveTab('workspace'); } setRefreshRevision((r) => r + 1); refreshAll(); }; const handleOpenDocument = (docId: string) => { setSelectedDocId(docId); setActiveTab('workspace'); }; const handleTriggerAddButton = () => { triggerHaptic(20); // Scroll smoothly to top and focus capture bar window.scrollTo({ top: 0, behavior: 'smooth' }); setCaptureFocusCount((c) => c + 1); }; const handleLogout = async () => { triggerHaptic(20); clearToken(); await api.quickStart(); await refreshAll(); setShowProfileModal(false); }; return (
{/* Top Header Bar */}
{/* Logo & Headline */}
{ setActiveTab('triage'); handleTriggerAddButton(); }} className="flex items-center gap-2.5 cursor-pointer group select-none flex-shrink-0" >
MindSift Der Kopf frei in drei Sekunden
{/* Quick-Capture Input Bubble directly in Header (above Tabs) */}
{/* User Profile Pill */}
{/* Monochrome square tabs attached to header */}
{/* Main Container */}
{/* Tab View Content */}
{activeTab === 'triage' && ( )} {activeTab === 'tasks' && ( )} {activeTab === 'workspace' && ( )} {activeTab === 'lists' && ( )}
{/* Profile, Settings, Discord Alarms, Webhooks, Teams & Admin Modal */} {showProfileModal && ( setShowProfileModal(false)} onUserUpdated={(u) => { setUser(u); refreshAll(); }} onLoggedOut={handleLogout} /> )}
); }; export default App;