'use client' import { useState, useCallback } from 'react' import { motion, AnimatePresence } from 'framer-motion' import { Plus, Trash2, ChevronDown, ChevronUp, Code, FileText } from 'lucide-react' import type { InstallMdStep } from '@/types' import { createEmptyStep, generateId } from '@/lib/install-md-generator' interface StepEditorProps { steps: InstallMdStep[] onChange: (steps: InstallMdStep[]) => void } export default function StepEditor({ steps, onChange }: StepEditorProps) { const [expandedSteps, setExpandedSteps] = useState>(new Set(steps.map(s => s.id))) const toggleExpanded = useCallback((id: string) => { setExpandedSteps(prev => { const next = new Set(prev) if (next.has(id)) { next.delete(id) } else { next.add(id) } return next }) }, []) const handleAddStep = useCallback(() => { const newStep = createEmptyStep() onChange([...steps, newStep]) setExpandedSteps(prev => new Set(prev).add(newStep.id)) }, [steps, onChange]) const handleRemoveStep = useCallback((id: string) => { if (steps.length <= 1) return onChange(steps.filter(step => step.id !== id)) setExpandedSteps(prev => { const next = new Set(prev) next.delete(id) return next }) }, [steps, onChange]) const handleUpdateStep = useCallback((id: string, updates: Partial) => { onChange(steps.map(step => step.id === id ? { ...step, ...updates } : step )) }, [steps, onChange]) const handleMoveStep = useCallback((fromIndex: number, toIndex: number) => { if (toIndex < 0 || toIndex >= steps.length) return const newSteps = [...steps] const [removed] = newSteps.splice(fromIndex, 1) newSteps.splice(toIndex, 0, removed) onChange(newSteps) }, [steps, onChange]) const handleAddCodeBlock = useCallback((stepId: string) => { const step = steps.find(s => s.id === stepId) if (!step) return handleUpdateStep(stepId, { codeBlocks: [ ...step.codeBlocks, { language: 'bash', code: '', label: '' } ] }) }, [steps, handleUpdateStep]) const handleUpdateCodeBlock = useCallback(( stepId: string, blockIndex: number, updates: Partial<{ language: string; code: string; label: string }> ) => { const step = steps.find(s => s.id === stepId) if (!step) return const newCodeBlocks = step.codeBlocks.map((block, i) => i === blockIndex ? { ...block, ...updates } : block ) handleUpdateStep(stepId, { codeBlocks: newCodeBlocks }) }, [steps, handleUpdateStep]) const handleRemoveCodeBlock = useCallback((stepId: string, blockIndex: number) => { const step = steps.find(s => s.id === stepId) if (!step) return const newCodeBlocks = step.codeBlocks.filter((_, i) => i !== blockIndex) handleUpdateStep(stepId, { codeBlocks: newCodeBlocks }) }, [steps, handleUpdateStep]) return (
{steps.map((step, index) => { const isExpanded = expandedSteps.has(step.id) return ( {/* Step Header */}
{/* Move Buttons */}
{/* Step Number */}
{index + 1}
{/* Title Input */} handleUpdateStep(step.id, { title: e.target.value })} placeholder="Step title (e.g., Install the CLI)" className="flex-1 px-3 py-2 bg-transparent border-0 focus:outline-none text-white placeholder-neutral-500 font-medium" /> {/* Expand/Collapse */} {/* Remove */}
{/* Step Content */} {isExpanded && (
{/* Description */}