"use client"; import { Button, Input, Textarea, Label } from '../ui'; import { Trash2, Plus, ChevronDown, ChevronUp, Eye, EyeOff } from 'lucide-react'; import { useState, useEffect } from 'react'; import type { ChangelogEntry } from '../../types/product-release'; interface ChangelogManagerProps { title: string; entries: ChangelogEntry[]; onChange: (entries: ChangelogEntry[]) => void; className?: string; /** Expand all items - useful after AI enrichment fills entries */ expandAll?: boolean; /** * When true, render a per-entry public/internal visibility toggle (Eye/EyeOff icon) * in each entry's header. New entries default to 'public'. Used by investor updates * — leave undefined for product releases so they keep their existing UX. */ showVisibilityToggle?: boolean; } export function ChangelogManager({ title, entries, onChange, className = '', expandAll = false, showVisibilityToggle = false, }: ChangelogManagerProps) { const [expandedIndices, setExpandedIndices] = useState>(new Set()); // When expandAll changes to true and there are entries, expand all useEffect(() => { if (expandAll && entries.length > 0) { setExpandedIndices(new Set(entries.map((_, i) => i))); } }, [expandAll, entries.length]); const addEntry = () => { const newEntry: ChangelogEntry = { title: '', description: '', ...(showVisibilityToggle && { visibility: 'public' as const }), }; onChange([...entries, newEntry]); // Expand the newly added entry setExpandedIndices(prev => new Set([...prev, entries.length])); }; const toggleVisibility = (index: number) => { const updated = [...entries]; const current = updated[index].visibility ?? 'public'; updated[index] = { ...updated[index], visibility: current === 'public' ? 'internal' : 'public' }; onChange(updated); }; const removeEntry = (index: number) => { onChange(entries.filter((_, i) => i !== index)); // Remove from expanded and adjust indices for items after removed one setExpandedIndices(prev => { const newSet = new Set(); prev.forEach(i => { if (i < index) newSet.add(i); else if (i > index) newSet.add(i - 1); }); return newSet; }); }; const updateEntry = (index: number, field: keyof ChangelogEntry, value: string) => { const updated = [...entries]; updated[index] = { ...updated[index], [field]: value }; onChange(updated); }; const toggleExpanded = (index: number) => { setExpandedIndices(prev => { const newSet = new Set(prev); if (newSet.has(index)) { newSet.delete(index); } else { newSet.add(index); } return newSet; }); }; return (
{entries.map((entry, index) => { const isExpanded = expandedIndices.has(index); const hasContent = entry.title.trim().length > 0; return (
{/* Header - always visible */}
{hasContent ? (

{entry.title}

) : (

New entry (click to edit)

)}
{showVisibilityToggle && ( )}
{/* Expanded content */} {isExpanded && (
{/* Title */}
updateEntry(index, 'title', e.target.value)} onKeyDown={(e) => e.key === 'Enter' && e.preventDefault()} className="bg-ods-bg" />
{/* Description */}