diff --git a/frontend/components/v2/config-panels/V2GroupConfigPanel.tsx b/frontend/components/v2/config-panels/V2GroupConfigPanel.tsx index 190d4015..d81abe5c 100644 --- a/frontend/components/v2/config-panels/V2GroupConfigPanel.tsx +++ b/frontend/components/v2/config-panels/V2GroupConfigPanel.tsx @@ -2,16 +2,78 @@ /** * V2Group 설정 패널 - * 통합 그룹 컴포넌트의 세부 설정을 관리합니다. + * 토스식 단계별 UX: 그룹 타입 카드 선택 -> 타입별 설정 -> 고급 설정(접힘) */ -import React from "react"; -import { Label } from "@/components/ui/label"; +import React, { useState } from "react"; import { Input } from "@/components/ui/input"; -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; -import { Checkbox } from "@/components/ui/checkbox"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { Switch } from "@/components/ui/switch"; import { Button } from "@/components/ui/button"; -import { Plus, Trash2 } from "lucide-react"; +import { + Collapsible, + CollapsibleContent, + CollapsibleTrigger, +} from "@/components/ui/collapsible"; +import { + LayoutList, + Rows3, + ChevronsDownUp, + SquareStack, + AppWindow, + FileInput, + Settings, + ChevronDown, + Plus, + Trash2, +} from "lucide-react"; +import { cn } from "@/lib/utils"; + +// ─── 그룹 타입 카드 정의 ─── +const GROUP_TYPE_CARDS = [ + { + value: "section", + icon: LayoutList, + title: "섹션", + description: "기본 영역 구분이에요", + }, + { + value: "tabs", + icon: Rows3, + title: "탭", + description: "탭으로 내용을 나눠요", + }, + { + value: "accordion", + icon: ChevronsDownUp, + title: "아코디언", + description: "접었다 펼 수 있어요", + }, + { + value: "card", + icon: SquareStack, + title: "카드 섹션", + description: "카드 형태로 묶어요", + }, + { + value: "modal", + icon: AppWindow, + title: "모달", + description: "팝업으로 표시해요", + }, + { + value: "form-modal", + icon: FileInput, + title: "폼 모달", + description: "입력 폼 팝업이에요", + }, +] as const; interface V2GroupConfigPanelProps { config: Record; @@ -22,10 +84,17 @@ export const V2GroupConfigPanel: React.FC = ({ config, onChange, }) => { + const [advancedOpen, setAdvancedOpen] = useState(false); + const updateConfig = (field: string, value: any) => { onChange({ ...config, [field]: value }); }; + const currentGroupType = config.groupType || config.type || "section"; + const isSectionType = currentGroupType === "section" || currentGroupType === "accordion"; + const isModalType = currentGroupType === "modal" || currentGroupType === "form-modal"; + const isTabsType = currentGroupType === "tabs"; + const tabs = config.tabs || []; const addTab = () => { @@ -45,138 +114,165 @@ export const V2GroupConfigPanel: React.FC = ({ }; return ( -
- {/* GROUP TYPE 섹션 */} -
-

GROUP TYPE

-
- 그룹 타입 -
- -
+
+ {/* ─── 1단계: 그룹 타입 선택 (카드) ─── */} +
+

어떤 방식으로 영역을 구성하나요?

+
+ {GROUP_TYPE_CARDS.map((card) => { + const Icon = card.icon; + const isSelected = currentGroupType === card.value; + return ( + + ); + })}
- {/* TITLE 섹션 */} -
-

TITLE

+ {/* ─── 2단계: 기본 설정 ─── */} +
+ 기본 설정 +
제목 -
- updateConfig("title", e.target.value)} - placeholder="그룹 제목" - className="h-7 text-xs" - /> -
+ updateConfig("title", e.target.value)} + placeholder="그룹 제목" + className="h-8 w-[180px] text-sm" + />
- {/* TABS 섹션 - 탭 타입일 때만 */} - {config.groupType === "tabs" && ( -
-
-

TABS

+ {/* ─── 3단계: 타입별 설정 ─── */} + + {/* 탭 타입: 탭 목록 관리 */} + {isTabsType && ( +
+
+
+ + 탭 목록 +
-
- {tabs.map((tab: any, index: number) => ( -
- updateTab(index, "id", e.target.value)} - placeholder="ID" - className="h-7 text-xs flex-1" - /> - updateTab(index, "label", e.target.value)} - placeholder="라벨" - className="h-7 text-xs flex-1" - /> - -
- ))} - {tabs.length === 0 && ( -

- 탭을 추가해주세요 -

- )} -
+ + {tabs.length > 0 ? ( +
+ {tabs.map((tab: any, index: number) => ( +
+ updateTab(index, "id", e.target.value)} + placeholder="ID" + className="h-8 flex-1 text-sm" + /> + updateTab(index, "label", e.target.value)} + placeholder="라벨" + className="h-8 flex-1 text-sm" + /> + +
+ ))} +
+ ) : ( +
+ +

아직 탭이 없어요

+

위의 추가 버튼으로 탭을 만들어보세요

+
+ )}
)} - {/* SECTION OPTIONS 섹션 - 섹션/아코디언일 때 */} - {(config.groupType === "section" || config.groupType === "accordion" || !config.groupType) && ( -
-

SECTION OPTIONS

- -
- 접기/펴기 가능 - +
+
+

접기/펴기

+

+ 사용자가 섹션을 접었다 펼 수 있어요 +

+
+ updateConfig("collapsible", checked)} />
{config.collapsible && ( -
- 기본으로 펼침 - updateConfig("defaultOpen", checked)} - /> +
+
+
+

기본으로 펼침

+

+ 처음에 펼쳐진 상태로 보여줘요 +

+
+ updateConfig("defaultOpen", checked)} + /> +
)}
)} - {/* MODAL OPTIONS 섹션 - 모달/폼모달일 때 */} - {(config.groupType === "modal" || config.groupType === "form-modal") && ( -
-

MODAL OPTIONS

+ {/* 모달/폼모달 타입: 모달 옵션 */} + {isModalType && ( +
+
+
+ + 모달 설정 +
-
- 모달 크기 -
+
+ 모달 크기