import { useState, useCallback } from 'react'; import { motion, AnimatePresence } from 'motion/react'; import { YoutubeFilled, InstagramFilled, GlobeFilled, VideoFilled, TiktokFilled, BoltFilled, CheckFilled, CalendarFilled, FileTextFilled, ShareFilled, } from '../icons/FilledIcons'; import { SectionWrapper } from '../report/ui/SectionWrapper'; import type { WorkflowData, WorkflowItem, WorkflowStage, WorkflowContentType } from '../../types/plan'; interface WorkflowTrackerProps { data: WorkflowData; } const STAGES: { key: WorkflowStage; label: string; short: string }[] = [ { key: 'planning', label: '기획 확정', short: '기획' }, { key: 'ai-draft', label: 'AI 초안', short: 'AI 초안' }, { key: 'review', label: '검토/수정', short: '검토' }, { key: 'approved', label: '승인', short: '승인' }, { key: 'scheduled', label: '배포 예약', short: '배포' }, ]; const STAGE_COLORS: Record = { planning: { bg: 'bg-slate-100', text: 'text-slate-600', border: 'border-slate-200', dot: 'bg-slate-400' }, 'ai-draft':{ bg: 'bg-[#EFF0FF]', text: 'text-[#3A3F7C]', border: 'border-[#C5CBF5]', dot: 'bg-[#7A84D4]' }, review: { bg: 'bg-[#FFF6ED]', text: 'text-[#7C5C3A]', border: 'border-[#F5E0C5]', dot: 'bg-[#D4A872]' }, approved: { bg: 'bg-[#F3F0FF]', text: 'text-[#4A3A7C]', border: 'border-[#D5CDF5]', dot: 'bg-[#9B8AD4]' }, scheduled: { bg: 'bg-[#F3F0FF]', text: 'text-[#4A3A7C]', border: 'border-[#D5CDF5]', dot: 'bg-[#6C5CE7]' }, }; const channelIconMap: Record = { youtube: YoutubeFilled, instagram: InstagramFilled, globe: GlobeFilled, video: TiktokFilled, share: ShareFilled, }; function StageBar({ currentStage }: { currentStage: WorkflowStage }) { const currentIdx = STAGES.findIndex((s) => s.key === currentStage); return (
{STAGES.map((stage, idx) => { const isPast = idx < currentIdx; const isCurrent = idx === currentIdx; return (
{isPast ? : idx + 1}
{stage.short}
{idx < STAGES.length - 1 && (
)}
); })}
); } function WorkflowCard({ item, onStageChange, onNotesChange }: { item: WorkflowItem; onStageChange: (id: string, stage: WorkflowStage) => void; onNotesChange: (id: string, notes: string) => void; }) { const [expanded, setExpanded] = useState(false); const [editingNotes, setEditingNotes] = useState(false); const [notesValue, setNotesValue] = useState(item.userNotes ?? ''); const stageColor = STAGE_COLORS[item.stage]; const ChannelIcon = channelIconMap[item.channelIcon] ?? GlobeFilled; const currentStageIdx = STAGES.findIndex((s) => s.key === item.stage); const nextStage = STAGES[currentStageIdx + 1]; const saveNotes = () => { onNotesChange(item.id, notesValue); setEditingNotes(false); }; return ( {/* Card Header */} {/* Expanded Body */} {expanded && (
{/* Stage Progress */} {/* AI Draft Content */} {item.contentType === 'video' && item.videoDraft && (

AI 스크립트 초안

{item.videoDraft.duration}
                    {item.videoDraft.script}
                  

촬영 지시서

    {item.videoDraft.shootingGuide.map((guide, i) => (
  • {i + 1} {guide}
  • ))}
)} {item.contentType === 'image-text' && item.imageTextDraft && (

AI {item.imageTextDraft.type === 'cardnews' ? '카드뉴스 카피' : '블로그 초안'}

{item.imageTextDraft.headline}

    {item.imageTextDraft.copy.map((line, i) => (
  • {line}
  • ))}
{item.imageTextDraft.layoutHint && (

{item.imageTextDraft.layoutHint}

)}
)} {/* User Notes */}

수정 요청 / 메모

{!editingNotes && ( )}
{editingNotes ? (