feat(frontend): add Front/ — Vite/React frontend with backend pipeline integration
Mirror of design_agent_front/design-agent/ for shipping alongside backend.
Vite plugin (vitePluginPhaseZApi) endpoints :
- POST /api/run — spawn `python -m src.phase_z2_pipeline` with overrides
- GET /api/sample-mdx?mdx=03/04/05 — fixed sample MDX
- GET /frame-preview/{n} — figma preview thumbnails
- GET /data/runs/{run_id}/{path} — pipeline artifacts (final.html, step*.json, ...)
Env toggle forward (보고용) :
PHASE_Z_ALLOW_RESTRUCTURE / PHASE_Z_ALLOW_REJECT / PHASE_Z_MAX_RANK=32
Components :
- LeftMdxPanel (03/04/05 fix list + section tree)
- SlideCanvas (iframe + slideOverrideCss prop for inline CSS inject)
- FramePanel (label priority + confidence sort)
- LayoutPanel
README with mermaid diagrams covering the 5-step demo flow.
node_modules / dist / .manus-logs / .env excluded via .gitignore.
This commit is contained in:
104
Front/client/src/components/layouts/LayoutTemplates.tsx
Normal file
104
Front/client/src/components/layouts/LayoutTemplates.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
import React from 'react';
|
||||
|
||||
/**
|
||||
* Step 22를 위한 16:9 베이스 슬라이드 본문 레이아웃 템플릿
|
||||
* 8종 중 우선 2종 샘플 구현
|
||||
*/
|
||||
|
||||
interface LayoutProps {
|
||||
title?: string;
|
||||
sections?: {
|
||||
id: string;
|
||||
title: string;
|
||||
content: string;
|
||||
type?: 'text' | 'image' | 'chart';
|
||||
}[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Layout 1: Focus Split (좌측 텍스트 / 우측 강조형)
|
||||
* 가장 범용적인 슬라이드 레이아웃
|
||||
*/
|
||||
export const FocusSplitLayout: React.FC<LayoutProps> = ({ sections = [] }) => {
|
||||
const mainSection = sections[0] || { title: 'Main Point', content: '핵심 내용을 이곳에 작성합니다.' };
|
||||
const subSection = sections[1] || { title: 'Supporting Detail', content: '보조 설명이나 이미지가 들어갑니다.' };
|
||||
|
||||
return (
|
||||
<div className="w-full h-full flex gap-8 p-6 bg-white animate-in fade-in duration-500">
|
||||
{/* 좌측 메인 영역 (60%) */}
|
||||
<div className="flex-[3] flex flex-col justify-center space-y-6">
|
||||
<div className="space-y-2">
|
||||
<div className="w-12 h-1 bg-blue-600 rounded-full" />
|
||||
<h2 className="text-4xl font-black text-slate-900 leading-tight">
|
||||
{mainSection.title}
|
||||
</h2>
|
||||
</div>
|
||||
<p className="text-xl text-slate-600 leading-relaxed font-medium">
|
||||
{mainSection.content}
|
||||
</p>
|
||||
<div className="flex gap-4 pt-4">
|
||||
<div className="px-4 py-2 bg-slate-50 border border-slate-100 rounded-xl text-sm font-bold text-slate-400 uppercase tracking-widest">
|
||||
Key Insight
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 우측 강조 영역 (40%) */}
|
||||
<div className="flex-[2] relative">
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-blue-50 to-indigo-50 rounded-[2rem] border-2 border-white shadow-inner flex flex-col items-center justify-center p-8 text-center overflow-hidden">
|
||||
<div className="absolute top-0 right-0 w-32 h-32 bg-blue-500/5 rounded-full -mr-16 -mt-16" />
|
||||
<div className="w-16 h-16 bg-white rounded-2xl shadow-lg flex items-center justify-center mb-6">
|
||||
<div className="w-8 h-8 bg-blue-600 rounded-lg animate-pulse" />
|
||||
</div>
|
||||
<h3 className="text-2xl font-bold text-slate-800 mb-3">{subSection.title}</h3>
|
||||
<p className="text-sm text-slate-500 font-medium leading-normal">
|
||||
{subSection.content}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Layout 2: Quadrant Grid (2x2 그리드 핵심 요약형)
|
||||
* 여러 요소를 병렬로 보여줄 때 최적
|
||||
*/
|
||||
export const QuadrantGridLayout: React.FC<LayoutProps> = ({ sections = [] }) => {
|
||||
const items = sections.length >= 4 ? sections.slice(0, 4) : [
|
||||
{ title: 'Strategy', content: '장기적 목표 및 실행 계획 수립' },
|
||||
{ title: 'Operations', content: '효율적인 자원 배분 및 프로세스 최적화' },
|
||||
{ title: 'Technology', content: '디지털 전환을 위한 기술 스택 도입' },
|
||||
{ title: 'Growth', content: '지속 가능한 성장 동력 확보' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="w-full h-full grid grid-cols-2 grid-rows-2 gap-6 p-6 bg-white animate-in zoom-in-95 duration-500">
|
||||
{items.map((item, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="group p-6 rounded-[1.5rem] border-2 border-slate-50 bg-slate-50/30 hover:bg-white hover:border-blue-100 hover:shadow-xl hover:shadow-blue-500/5 transition-all duration-300 flex flex-col justify-between"
|
||||
>
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="flex items-center justify-center w-8 h-8 rounded-full bg-slate-900 text-white text-xs font-black">
|
||||
0{i + 1}
|
||||
</span>
|
||||
<h3 className="text-xl font-black text-slate-800 group-hover:text-blue-600 transition-colors">
|
||||
{item.title}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-sm text-slate-500 leading-relaxed font-medium pl-11">
|
||||
{item.content}
|
||||
</p>
|
||||
</div>
|
||||
<div className="pl-11 pt-4">
|
||||
<div className="w-full h-1 bg-slate-100 rounded-full overflow-hidden">
|
||||
<div className="w-1/3 h-full bg-blue-500 rounded-full group-hover:w-full transition-all duration-700" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user