/** * LeftMdxPanel - 좌측 MDX 구조 탐색기 * * 기능: * - MDX 파일 업로드 버튼 * - 추출된 섹션들의 계층 구조(Level 1~3) 표시 * - 섹션 클릭 시 중앙 캔버스의 해당 구역 하이라이트 */ import React from 'react'; import { FileText, ChevronRight, Upload, Zap, Layers, List, } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { ScrollArea } from '@/components/ui/scroll-area'; import { Progress } from '@/components/ui/progress'; import { toast } from 'sonner'; import type { NormalizedContent } from '../types/designAgent'; interface LeftMdxPanelProps { normalizedContent: NormalizedContent | null; uploadedFile: File | null; isLoading: boolean; selectedSectionId: string | null; hasSlidePlan: boolean; /** 사용자가 frame / section / layout / zone 등 override 를 변경했을 때 true. * 하단 버튼이 "선택대로 재생성하기" 강조 버튼으로 전환. */ hasPendingChanges?: boolean; onFileUpload: (file: File) => void; onGenerate: () => void; onSectionClick: (sectionId: string) => void; /** 사용자 lock 2026-05-14 — 좌측 패널에 03/04/05 fix 고정 list. 클릭 시 callback. */ onSelectSample?: (which: "03" | "04" | "05") => void; selectedSample?: "03" | "04" | "05" | null; } const SAMPLE_MDX_LIST: { key: "03" | "04" | "05"; label: string; subtitle: string }[] = [ { key: "03", label: "03. DX 시행을 위한 필수 요건", subtitle: "필수 요건 + Process/Product 혁신" }, { key: "04", label: "04. DX 지연 요인", subtitle: "DX 인식 + 정책/조직 실태" }, { key: "05", label: "05. 설계 방식의 왜곡", subtitle: "설계 자동화 오용 + S/W 한계" }, ]; export default function LeftMdxPanel({ normalizedContent, uploadedFile, isLoading, selectedSectionId, hasSlidePlan, hasPendingChanges = false, onFileUpload, onGenerate, onSectionClick, onSelectSample, selectedSample = null, }: LeftMdxPanelProps) { const fileInputRef = React.useRef(null); const handleFileChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) onFileUpload(file); }; return (
{/* ── 헤더: 문서 정보 ── */}

MDX Source

{/* 2026-05-14 — 03/04/05 fix 고정 list. 클릭 시 해당 mdx 자동 fetch + 분석. frame/layout override 는 분석 후 우측 패널에서 가능. */} {onSelectSample && (
{SAMPLE_MDX_LIST.map((s) => { const isActive = selectedSample === s.key; return ( ); })}
)} {uploadedFile ? (

{uploadedFile.name}

{(uploadedFile.size / 1024).toFixed(1)} KB

{!hasSlidePlan && ( )}
) : ( )}
{/* ── 분석 진행 상태 (로딩 시) ── */} {isLoading && (
콘텐츠 분석 중... STAGE 1
)} {/* ── 섹션 트리 리스트 ── */} {!normalizedContent ? (

파일을 업로드하면
문서 구조가 표시됩니다.

) : (
{/* 문서 제목 (Level 1) */}

{normalizedContent.title}

{/* 섹션들 (Level 2+) — native HTML5 drag (framer-motion drag 와 충돌 있어서 native 만 사용). dataTransfer 에 sectionId / section-id / text/plain 다 set 해서 SlideCanvas drop 이 어떤 키로든 받게. */} {normalizedContent.sections.map((section) => { const isSelected = selectedSectionId === section.id; const subSections = section.sub_sections ?? []; return (
{/* 중목차 (S1, S2 ...) */} {/* 소목차 (S1.1, S1.2 ...) — 펼친 상태로 indent 표시. 각자 draggable. */} {subSections.length > 0 && (
{subSections.map((sub) => { const isSubSelected = selectedSectionId === sub.id; return ( ); })}
)}
); })}
)}
{/* ── 하단 분석 버튼 ── */}
{!normalizedContent ? (

MDX 분석 대기 중

) : (
{!hasSlidePlan ? ( ) : hasPendingChanges ? ( // override 변경 있음 — 강조 "선택대로 재생성하기" 버튼
Pending Changes

레이아웃 / 프레임 / 섹션 변경을 backend 에 적용해 새 final.html 을 생성합니다. (※ Step D backend forwarding 연결 후 활성)

) : (
플랜 생성 완료
)}
)}
); }