import { useEffect, useMemo, useRef, useState, type MouseEvent } from 'react'; import { fmtPeriodPickerLabel, parseMilestonePeriods, parsePeriodNoteLines, pickLatestPeriodId, sortPeriodsByRecent, } from '../../lib/milestonePeriods'; import type { Milestone } from '../../types'; interface MilestoneContentListProps { milestone: Pick | null | undefined; emptyMessage: string; onContextMenu?: (event: MouseEvent) => void; } function PeriodPicker({ periods, selectedId, onSelect, }: { periods: ReturnType; selectedId: string; onSelect: (id: string) => void; }) { const [open, setOpen] = useState(false); const rootRef = useRef(null); const selected = periods.find((p) => p.id === selectedId) ?? periods[0]; const selectedIndex = periods.findIndex((p) => p.id === selected?.id); const label = selected ? fmtPeriodPickerLabel(selected, selectedIndex >= 0 ? selectedIndex : 0) : ''; useEffect(() => { if (!open) return; const onPointerDown = (event: PointerEvent) => { if (!rootRef.current?.contains(event.target as Node)) setOpen(false); }; document.addEventListener('pointerdown', onPointerDown); return () => document.removeEventListener('pointerdown', onPointerDown); }, [open]); if (!selected || !label) return null; const canPick = periods.length > 1; return (
{open && canPick && (
    {periods.map((period, index) => { const isActive = period.id === selectedId; return (
  • ); })}
)}
); } export function MilestoneContentList({ milestone, emptyMessage, onContextMenu, }: MilestoneContentListProps) { const periods = useMemo( () => sortPeriodsByRecent(parseMilestonePeriods(milestone)), [milestone], ); const latestId = useMemo(() => pickLatestPeriodId(periods), [periods]); const [selectedPeriodId, setSelectedPeriodId] = useState(null); useEffect(() => { setSelectedPeriodId(latestId); }, [milestone?.id, latestId]); const activePeriod = periods.find((p) => p.id === selectedPeriodId) ?? periods[0] ?? null; const lines = parsePeriodNoteLines(activePeriod?.note); return ( <>

업무내용

{milestone && periods.length > 0 && activePeriod && ( )}
    {!milestone ? (
  • {emptyMessage}
  • ) : periods.length === 0 ? (
  • {emptyMessage}
  • ) : lines.length === 0 ? (
  • 이 기간에 입력된 업무내용이 없습니다.
  • ) : ( lines.map((line, index) => (
  • {line}

  • )) )}
); }