import React, { useState, useEffect } from 'react' import { useTranslation } from 'react-i18next' import { useLiveQuery } from 'dexie-react-hooks' import { db } from '../services/db.js' import { fetchLogbooks, createLogbook, deleteLogbook, type DecryptedLogbook } from '../services/logbook.js' import { logoutUser } from '../services/auth.js' import { useDialog } from './ModalDialog.tsx' import { BookOpen, Plus, Trash2, LogOut, Languages, RefreshCw, Ship, User, Wifi, WifiOff } from 'lucide-react' interface LogbookDashboardProps { onSelectLogbook: (id: string, title: string) => void onLogout: () => void } export default function LogbookDashboard({ onSelectLogbook, onLogout }: LogbookDashboardProps) { const { t, i18n } = useTranslation() const { showConfirm } = useDialog() const [logbooks, setLogbooks] = useState([]) const [newTitle, setNewTitle] = useState('') const [loading, setLoading] = useState(false) const [refreshing, setRefreshing] = useState(false) const [error, setError] = useState(null) const [online, setOnline] = useState(navigator.onLine) const [username] = useState(localStorage.getItem('active_username') || 'Skipper') // Reactive sync queue count const pendingCount = useLiveQuery(() => db.syncQueue.count()) || 0 // Listen to connectivity changes useEffect(() => { const handleOnline = () => setOnline(true) const handleOffline = () => setOnline(false) window.addEventListener('online', handleOnline) window.addEventListener('offline', handleOffline) return () => { window.removeEventListener('online', handleOnline) window.removeEventListener('offline', handleOffline) } }, []) // Load logbooks on mount useEffect(() => { loadLogbooks() }, []) const loadLogbooks = async (isRefresh = false) => { if (isRefresh) setRefreshing(true) else setLoading(true) setError(null) try { const data = await fetchLogbooks() setLogbooks(data) } catch (err: any) { setError(err.message || 'Failed to load logbooks') } finally { setLoading(false) setRefreshing(false) } } const handleCreate = async (e: React.FormEvent) => { e.preventDefault() if (!newTitle.trim()) return setLoading(true) setError(null) try { const created = await createLogbook(newTitle.trim()) setLogbooks((prev) => [created, ...prev]) setNewTitle('') } catch (err: any) { setError(err.message || 'Failed to create logbook') } finally { setLoading(false) } } const handleDelete = async (id: string, e: React.MouseEvent) => { e.stopPropagation() // Prevent selecting the logbook when clicking delete if (await showConfirm(t('dashboard.delete_confirm'), t('dashboard.title'), t('logs.confirm_yes'), t('logs.confirm_no'))) { setLoading(true) setError(null) try { await deleteLogbook(id) setLogbooks((prev) => prev.filter((lb) => lb.id !== id)) } catch (err: any) { setError(err.message || 'Failed to delete logbook') } finally { setLoading(false) } } } const handleLogout = () => { logoutUser() onLogout() } const toggleLanguage = () => { const nextLang = i18n.language.startsWith('de') ? 'en' : 'de' i18n.changeLanguage(nextLang) } return (
{/* Premium Dashboard Header */}

{t('app.name')}

{t('app.tagline')}

{/* Connection Indicator */}
0 ? 'unsynced' : 'online') : 'offline'}`} title={online ? (pendingCount > 0 ? 'Pending Sync' : 'Synced') : 'Offline'}> {online ? ( pendingCount > 0 ? ( <> {t('sync.status_unsynced')} ({pendingCount}) ) : ( <> {t('sync.status_synced')} ) ) : ( <> {t('sync.status_offline')} )}
{/* Skipper profile */}
{username}
{/* Lang toggle */} {/* Logout */}
{/* Main Dashboard Layout */}
{/* Left Side: Create form */}

{t('dashboard.create_btn')}

setNewTitle(e.target.value)} disabled={loading} required />
{error &&
{error}
}
{/* Right Side: Logbooks list */}

{t('dashboard.title')}

{loading && !refreshing ? (
{t('dashboard.loading')}
) : logbooks.length === 0 ? (
{t('dashboard.no_logbooks')}
) : (
{logbooks.map((lb) => (
onSelectLogbook(lb.id, lb.title)}>

{lb.title}

{lb.isSynced ? t('dashboard.status_synced') : t('dashboard.status_local')} {new Date(lb.updatedAt).toLocaleDateString(i18n.language, { year: 'numeric', month: 'short', day: 'numeric' })}
))}
)}
) }