import { useEffect, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { Users } from 'lucide-react' import type { EntryCrewFields, PersonSnapshot } from '../types/person.js' import { loadPersonPool } from '../services/personPool.js' import { loadLogbookCrewSelection } from '../services/logbookCrewSelection.js' import { buildSnapshotsForSelection } from '../utils/personSnapshots.js' import type { PersonData } from '../types/person.js' export interface EntryCrewSectionProps { logbookId: string readOnly?: boolean value: EntryCrewFields onChange: (next: EntryCrewFields) => void /** Demo: fixed pool */ preloadedPool?: Map } export default function EntryCrewSection({ logbookId, readOnly = false, value, onChange, preloadedPool }: EntryCrewSectionProps) { const { t } = useTranslation() const [pool, setPool] = useState>(preloadedPool ?? new Map()) useEffect(() => { if (preloadedPool) { setPool(preloadedPool) return } let cancelled = false void (async () => { try { const people = await loadPersonPool() if (cancelled) return setPool(new Map(people.map((p) => [p.payloadId, p.data]))) } catch { /* use snapshots only */ } })() return () => { cancelled = true } }, [preloadedPool]) const displayPool = useMemo(() => { const merged = new Map(pool) for (const snap of Object.values(value.crewSnapshotsById)) { if (!merged.has(snap.id)) { merged.set(snap.id, { name: snap.name, address: snap.address, birthDate: snap.birthDate, phone: snap.phone, nationality: snap.nationality, passportNumber: snap.passportNumber, bloodType: snap.bloodType, allergies: snap.allergies, diseases: snap.diseases, role: snap.role, photo: snap.photo }) } } return merged }, [pool, value.crewSnapshotsById]) const skippers = [...displayPool.entries()].filter(([, d]) => d.role === 'skipper') const crewEntries = [...displayPool.entries()].filter(([, d]) => d.role === 'crew') const applyChange = (skipperId: string | null, crewIds: string[]) => { const snapshots = buildSnapshotsForSelection(skipperId, crewIds, displayPool) onChange({ selectedSkipperId: skipperId, selectedCrewIds: crewIds, crewSnapshotsById: snapshots }) } const toggleCrew = (id: string) => { if (readOnly) return const next = value.selectedCrewIds.includes(id) ? value.selectedCrewIds.filter((x) => x !== id) : [...value.selectedCrewIds, id] applyChange(value.selectedSkipperId, next) } return (

{t('entry_crew.title')}

{t('entry_crew.subtitle')}

{skippers.length === 0 ? (

{t('entry_crew.no_skipper')}

) : (
{skippers.map(([id, data]) => ( ))}
)}
{crewEntries.length === 0 ? (

{t('entry_crew.no_crew')}

) : (
{crewEntries.map(([id, data]) => ( ))}
)}
) } export async function loadDefaultEntryCrewForNewDay( logbookId: string, previousEntry: Record | null ): Promise { if (previousEntry) { const selectedSkipperId = typeof previousEntry.selectedSkipperId === 'string' ? previousEntry.selectedSkipperId : null const selectedCrewIds = Array.isArray(previousEntry.selectedCrewIds) ? previousEntry.selectedCrewIds.filter((id): id is string => typeof id === 'string') : [] const crewSnapshotsById = previousEntry.crewSnapshotsById && typeof previousEntry.crewSnapshotsById === 'object' ? (previousEntry.crewSnapshotsById as Record) : {} return { selectedSkipperId, selectedCrewIds, crewSnapshotsById } } const selection = await loadLogbookCrewSelection(logbookId) return { selectedSkipperId: selection.activeSkipperId, selectedCrewIds: [...selection.activeCrewIds], crewSnapshotsById: { ...selection.snapshotsById } } }