Files
invyone/frontend/components/v2/V2ComponentsDemo.tsx
T
DDD1542 7d204bfffd
Build & Deploy to K8s / build-and-deploy (push) Failing after 14m3s
refactor: complete canonical table cleanup
2026-05-21 11:55:08 +09:00

335 lines
13 KiB
TypeScript

"use client";
/**
* V2ComponentsDemo
*
* V2 컴포넌트들을 테스트하고 미리볼 수 있는 데모 페이지
*/
import React, { useState } from "react";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
import { ArrowLeft } from "lucide-react";
// V2 컴포넌트들 (옛 입력/선택은 Phase D.3 에서 폐기 — canonical `input` 으로 흡수됨)
// V2List 는 Phase F.8 에서 폐기 — canonical table 로 흡수.
import { V2Layout } from "./V2Layout";
import { V2Group } from "./V2Group";
// V2Media — Phase D.5 폐기. canonical input 의 file 분기로 흡수.
import { V2Biz } from "./V2Biz";
import { V2Hierarchy } from "./V2Hierarchy";
// 조건부 로직 데모는 Phase D.3 에서 폐기 (옛 입력/선택 의존이 핵심이었음)
// 타입
import { HierarchyNode } from "@/types/v2-components";
interface V2ComponentsDemoProps {
onBack?: () => void;
}
export function V2ComponentsDemo({ onBack }: V2ComponentsDemoProps) {
const [activeTab, setActiveTab] = useState("layout");
// 데모용 상태 (옛 입력/선택 데모 state — Phase D.3 에서 제거됨)
// sampleTableData / List 탭은 Phase F.8 에서 제거 — canonical table demo 별도 화면.
const sampleHierarchyData: HierarchyNode[] = [
{
id: "1",
label: "본사",
children: [
{
id: "1-1",
label: "영업부",
children: [
{ id: "1-1-1", label: "영업1팀" },
{ id: "1-1-2", label: "영업2팀" },
],
},
{
id: "1-2",
label: "개발부",
children: [
{ id: "1-2-1", label: "프론트엔드팀" },
{ id: "1-2-2", label: "백엔드팀" },
],
},
],
},
];
return (
<div className="flex h-full flex-col bg-background">
{/* 헤더 */}
<div className="flex items-center gap-4 border-b p-4">
{onBack && (
<Button variant="outline" size="sm" onClick={onBack}>
<ArrowLeft className="mr-2 h-4 w-4" />
</Button>
)}
<div className="flex-1">
<h1 className="text-2xl font-bold">V2 </h1>
<p className="text-sm text-muted-foreground">
10
</p>
</div>
<Badge variant="secondary">Phase 1-3 </Badge>
</div>
{/* 탭 컨텐츠 */}
<div className="flex-1 overflow-auto p-4">
<Tabs value={activeTab} onValueChange={setActiveTab}>
<TabsList className="grid w-full grid-cols-2 lg:grid-cols-6">
<TabsTrigger value="layout">Layout</TabsTrigger>
<TabsTrigger value="group" className="hidden lg:flex">Group</TabsTrigger>
<TabsTrigger value="biz" className="hidden lg:flex">Biz</TabsTrigger>
<TabsTrigger value="hierarchy" className="hidden lg:flex">Hierarchy</TabsTrigger>
</TabsList>
{/* 조건부 동작 데모 탭 — Phase D.3 에서 폐기 (옛 입력/선택 의존) */}
{/* 옛 입력/선택 탭 — Phase D.3 에서 폐기. canonical `input` 데모는 별도 화면에서 확인 */}
{/* List 탭 — Phase F.8 에서 폐기. canonical table demo 는 별도 화면에서 확인 */}
{/* V2Layout 탭 */}
<TabsContent value="layout" className="mt-6">
<Card>
<CardHeader>
<CardTitle>V2Layout</CardTitle>
<CardDescription>
- 12 , split, flex
</CardDescription>
</CardHeader>
<CardContent className="space-y-6">
{/* 12컬럼 그리드 시스템 */}
<div>
<h4 className="text-sm font-medium mb-3">12 </h4>
<p className="text-xs text-muted-foreground mb-4">
shadcn/Tailwind 12 . col-span-*
</p>
{/* 12컬럼 전체 보기 */}
<V2Layout
id="demo-grid-12"
v2Type="V2Layout"
config={{ type: "grid", columns: 12, gap: "4px", use_12_column: true }}
>
{Array.from({ length: 12 }).map((_, i) => (
<div key={i} className="p-2 bg-primary/20 rounded text-center text-xs">
{i + 1}
</div>
))}
</V2Layout>
</div>
<Separator />
{/* col-span 예시 */}
<div>
<h4 className="text-sm font-medium mb-3">col-span </h4>
<V2Layout
id="demo-grid-span"
v2Type="V2Layout"
config={{ type: "grid", columns: 12, gap: "8px", use_12_column: true }}
>
<div className="col-span-12 p-3 bg-primary/10 rounded text-center text-sm">
col-span-12 ()
</div>
<div className="col-span-6 p-3 bg-emerald-100 rounded text-center text-sm">
col-span-6 ()
</div>
<div className="col-span-6 p-3 bg-emerald-100 rounded text-center text-sm">
col-span-6 ()
</div>
<div className="col-span-4 p-3 bg-amber-100 rounded text-center text-sm">
col-span-4 (1/3)
</div>
<div className="col-span-4 p-3 bg-amber-100 rounded text-center text-sm">
col-span-4 (1/3)
</div>
<div className="col-span-4 p-3 bg-amber-100 rounded text-center text-sm">
col-span-4 (1/3)
</div>
<div className="col-span-3 p-3 bg-purple-100 rounded text-center text-sm">
col-span-3 (1/4)
</div>
<div className="col-span-3 p-3 bg-purple-100 rounded text-center text-sm">
col-span-3 (1/4)
</div>
<div className="col-span-3 p-3 bg-purple-100 rounded text-center text-sm">
col-span-3 (1/4)
</div>
<div className="col-span-3 p-3 bg-purple-100 rounded text-center text-sm">
col-span-3 (1/4)
</div>
<div className="col-span-8 p-3 bg-destructive/10 rounded text-center text-sm">
col-span-8 (2/3)
</div>
<div className="col-span-4 p-3 bg-destructive/10 rounded text-center text-sm">
col-span-4 (1/3)
</div>
</V2Layout>
</div>
<Separator />
{/* Split Layout */}
<div>
<h4 className="text-sm font-medium mb-3">Split Layout ( )</h4>
<V2Layout
id="demo-split"
v2Type="V2Layout"
config={{ type: "split", direction: "horizontal", split_ratio: [30, 70] }}
style={{ height: "200px" }}
>
<div className="p-4 bg-primary/10 h-full flex items-center justify-center">
</div>
<div className="p-4 bg-emerald-100 h-full flex items-center justify-center">
</div>
</V2Layout>
</div>
</CardContent>
</Card>
</TabsContent>
{/* V2Group 탭 */}
<TabsContent value="group" className="mt-6">
<Card>
<CardHeader>
<CardTitle>V2Group</CardTitle>
<CardDescription>
- tabs, accordion, section, card-section
</CardDescription>
</CardHeader>
<CardContent className="space-y-6">
{/* Tabs */}
<V2Group
id="demo-tabs"
v2Type="V2Group"
config={{
type: "tabs",
tabs: [
{ id: "tab1", title: "탭 1", content: <div className="p-4"> 1 </div> },
{ id: "tab2", title: "탭 2", content: <div className="p-4"> 2 </div> },
{ id: "tab3", title: "탭 3", content: <div className="p-4"> 3 </div> },
],
}}
/>
<Separator />
{/* Accordion */}
<V2Group
id="demo-accordion"
v2Type="V2Group"
config={{
type: "accordion",
title: "접을 수 있는 섹션",
collapsible: true,
default_expanded: true,
}}
>
<p> .</p>
</V2Group>
<Separator />
{/* Card Section */}
<V2Group
id="demo-card"
v2Type="V2Group"
config={{
type: "card-section",
title: "카드 섹션",
}}
>
<p> .</p>
</V2Group>
</CardContent>
</Card>
</TabsContent>
{/* V2Media 탭 — Phase D.5 에서 폐기. canonical input 의 file 분기로 흡수 */}
{/* V2Biz 탭 */}
<TabsContent value="biz" className="mt-6">
<Card>
<CardHeader>
<CardTitle>V2Biz</CardTitle>
<CardDescription>
- numbering, category, flow ()
</CardDescription>
</CardHeader>
<CardContent className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<V2Biz
id="demo-numbering"
v2Type="V2Biz"
config={{ type: "numbering" }}
/>
<V2Biz
id="demo-category"
v2Type="V2Biz"
config={{ type: "category" }}
/>
<V2Biz
id="demo-related"
v2Type="V2Biz"
config={{ type: "related-buttons" }}
/>
</div>
</CardContent>
</Card>
</TabsContent>
{/* V2Hierarchy 탭 */}
<TabsContent value="hierarchy" className="mt-6">
<Card>
<CardHeader>
<CardTitle>V2Hierarchy</CardTitle>
<CardDescription>
- tree, org, bom, cascading
</CardDescription>
</CardHeader>
<CardContent className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{/* Tree View */}
<div>
<h4 className="text-sm font-medium mb-3"> </h4>
<V2Hierarchy
id="demo-tree"
v2Type="V2Hierarchy"
config={{ type: "tree", view_mode: "tree", editable: false }}
data={sampleHierarchyData}
/>
</div>
{/* Cascading Dropdowns */}
<div>
<h4 className="text-sm font-medium mb-3"> </h4>
<V2Hierarchy
id="demo-cascading"
v2Type="V2Hierarchy"
config={{ type: "cascading", view_mode: "dropdown", max_level: 3 }}
data={sampleHierarchyData}
/>
</div>
</div>
</CardContent>
</Card>
</TabsContent>
</Tabs>
</div>
</div>
);
}
export default V2ComponentsDemo;