import * as React from 'react'; import { MessageSquare, Check } from 'lucide-react'; import { cn } from '../../lib/utils'; import { formatRelativeTime } from '../../utils'; /** One critique note in a review thread (used per content section or overall). */ export interface ReviewNote { id: string; body: string; author?: string; /** When the note was recorded — rendered as a relative time if present. */ at?: string | Date; resolved?: boolean; /** Optional section/anchor the note is about. */ section?: string; } export interface ReviewNotesProps { /** The notes to render. */ notes: ReviewNote[]; /** Provide to show a composer. Called with the new note body. */ onAdd?: (body: string) => void; /** Provide to show a Resolve action on unresolved notes. */ onResolve?: (id: string) => void; emptyMessage?: string; title?: string; /** Hide the composer + resolve actions (view-only). */ readOnly?: boolean; className?: string; } /** * A lightweight note/critique thread (768w.16.10.4) — the section-level or overall * companion to ReviewScorecard. Purely presentational + bring-your-own-data: it * lists notes (author, relative time, resolved styling), exposes a Resolve action * and a composer when the callbacks are provided, and never fetches or persists. */ export function ReviewNotes({ notes, onAdd, onResolve, emptyMessage = 'No notes yet.', title = 'Notes', readOnly, className, }: ReviewNotesProps) { const [draft, setDraft] = React.useState(''); const canCompose = !readOnly && !!onAdd; const submit = () => { const body = draft.trim(); if (!body) return; onAdd?.(body); setDraft(''); }; return (
{notes.length === 0 ? (

{emptyMessage}

) : ( )} {canCompose && (