import { useCallback, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import { Ship, Save, Check } from 'lucide-react' import type { LogbookVesselSelectionData, VesselData } from '../types/vessel.js' import type { DecryptedVessel } from '../services/vesselPool.js' import { loadVesselPool } from '../services/vesselPool.js' import { loadLogbookVesselSelection, saveLogbookVesselSelectionFromId } from '../services/logbookVesselSelection.js' import { resolveVesselForLogbook } from '../services/resolveVessel.js' import { vesselDataFromSnapshot } from '../utils/vesselSnapshot.js' import { PlausibleEvents, trackPlausibleEvent } from '../services/analytics.js' export interface LogbookVesselPickerProps { logbookId: string readOnly?: boolean preloadedPool?: Array<{ payloadId: string; data: VesselData }> preloadedSelection?: LogbookVesselSelectionData selectionOnly?: boolean onOpenProfile?: () => void } export default function LogbookVesselPicker({ logbookId, readOnly = false, preloadedPool, preloadedSelection, selectionOnly = false, onOpenProfile }: LogbookVesselPickerProps) { const { t } = useTranslation() const [loading, setLoading] = useState(!preloadedSelection) const [saving, setSaving] = useState(false) const [saved, setSaved] = useState(false) const [error, setError] = useState(null) const [pool, setPool] = useState([]) const [activeVesselId, setActiveVesselId] = useState(null) const [resolvedVessel, setResolvedVessel] = useState(null) const loadData = useCallback(async () => { setLoading(true) setError(null) try { const selection = preloadedSelection ?? (logbookId === 'demo' ? null : await loadLogbookVesselSelection(logbookId)) if (selection) { setActiveVesselId(selection.activeVesselId) } if (preloadedPool) { setPool(preloadedPool.map((p) => ({ payloadId: p.payloadId, data: p.data }))) } else if (selectionOnly && selection?.vesselSnapshot) { const data = vesselDataFromSnapshot(selection.vesselSnapshot) if (data) { setPool([{ payloadId: selection.vesselSnapshot.id, data }]) } } else { setPool(await loadVesselPool()) } const vessel = await resolveVesselForLogbook(logbookId, { preloadedSelection: selection ?? undefined }) setResolvedVessel(vessel) } catch (err: unknown) { setError(err instanceof Error ? err.message : 'Failed to load vessel selection') } finally { setLoading(false) } }, [logbookId, preloadedPool, preloadedSelection, selectionOnly]) useEffect(() => { void loadData() }, [loadData]) const handleSave = async () => { if (readOnly || logbookId === 'demo') return setSaving(true) setError(null) setSaved(false) try { const selection = await saveLogbookVesselSelectionFromId(logbookId, activeVesselId) const vessel = vesselDataFromSnapshot(selection.vesselSnapshot) setResolvedVessel(vessel) setSaved(true) trackPlausibleEvent(PlausibleEvents.VESSEL_SAVED, { context: 'logbook_selection' }) setTimeout(() => setSaved(false), 3000) } catch (err: unknown) { setError(err instanceof Error ? err.message : 'Failed to save') } finally { setSaving(false) } } if (loading) { return (

{t('vessel_pool.loading')}

) } return (

{t('logbook_vessel.title')}

{t('logbook_vessel.subtitle')}

{selectionOnly &&

{t('logbook_vessel.selection_only_hint')}

} {!selectionOnly && !readOnly && onOpenProfile && (

)} {error &&
{error}
}
{pool.length === 0 ? (

{t('logbook_vessel.no_vessels_in_pool')}

) : (
{pool.map((v) => ( ))} {!readOnly && ( )}
)}
{resolvedVessel && (

{resolvedVessel.name}

{resolvedVessel.homePort && (
{t('vessel.port')}
{resolvedVessel.homePort}
)} {resolvedVessel.registrationNumber && (
{t('vessel.registration')}
{resolvedVessel.registrationNumber}
)} {resolvedVessel.mmsi && (
{t('vessel.mmsi')}
{resolvedVessel.mmsi}
)}
)} {!readOnly && logbookId !== 'demo' && (
{saved && (
{t('logbook_vessel.saved')}
)}
)}
) }