2025-12-19 15:44:38 +09:00
|
|
|
"use client";
|
|
|
|
|
|
|
|
|
|
/**
|
2026-01-28 17:36:19 +09:00
|
|
|
* V2Layout 설정 패널
|
2025-12-19 15:44:38 +09:00
|
|
|
* 통합 레이아웃 컴포넌트의 세부 설정을 관리합니다.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import React from "react";
|
|
|
|
|
import { Label } from "@/components/ui/label";
|
|
|
|
|
import { Input } from "@/components/ui/input";
|
|
|
|
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
|
|
|
|
import { Checkbox } from "@/components/ui/checkbox";
|
|
|
|
|
|
2026-01-28 17:36:19 +09:00
|
|
|
interface V2LayoutConfigPanelProps {
|
2025-12-19 15:44:38 +09:00
|
|
|
config: Record<string, any>;
|
|
|
|
|
onChange: (config: Record<string, any>) => void;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-28 17:36:19 +09:00
|
|
|
export const V2LayoutConfigPanel: React.FC<V2LayoutConfigPanelProps> = ({
|
2025-12-19 15:44:38 +09:00
|
|
|
config,
|
|
|
|
|
onChange,
|
|
|
|
|
}) => {
|
|
|
|
|
const updateConfig = (field: string, value: any) => {
|
|
|
|
|
onChange({ ...config, [field]: value });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
2026-03-11 16:42:06 +09:00
|
|
|
<div className="space-y-1">
|
|
|
|
|
{/* LAYOUT TYPE 섹션 */}
|
|
|
|
|
<div className="border-b border-border/50 pb-3 mb-3">
|
|
|
|
|
<h4 className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground py-2">LAYOUT TYPE</h4>
|
|
|
|
|
<div className="flex items-center justify-between py-1.5">
|
|
|
|
|
<span className="text-xs text-muted-foreground">레이아웃 타입</span>
|
|
|
|
|
<div className="w-[140px]">
|
|
|
|
|
<Select
|
|
|
|
|
value={config.layoutType || config.type || "grid"}
|
|
|
|
|
onValueChange={(value) => updateConfig("layoutType", value)}
|
|
|
|
|
>
|
|
|
|
|
<SelectTrigger className="h-7 text-xs">
|
|
|
|
|
<SelectValue placeholder="타입 선택" />
|
|
|
|
|
</SelectTrigger>
|
|
|
|
|
<SelectContent>
|
|
|
|
|
<SelectItem value="grid">그리드</SelectItem>
|
|
|
|
|
<SelectItem value="split">분할 패널</SelectItem>
|
|
|
|
|
<SelectItem value="flex">플렉스</SelectItem>
|
|
|
|
|
<SelectItem value="divider">구분선</SelectItem>
|
|
|
|
|
<SelectItem value="screen-embed">화면 임베드</SelectItem>
|
|
|
|
|
</SelectContent>
|
|
|
|
|
</Select>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-12-19 15:44:38 +09:00
|
|
|
</div>
|
|
|
|
|
|
2026-03-11 16:42:06 +09:00
|
|
|
{/* GRID SETTINGS 섹션 */}
|
2025-12-19 15:44:38 +09:00
|
|
|
{(config.layoutType === "grid" || !config.layoutType) && (
|
2026-03-11 16:42:06 +09:00
|
|
|
<div className="border-b border-border/50 pb-3 mb-3">
|
|
|
|
|
<h4 className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground py-2">GRID SETTINGS</h4>
|
|
|
|
|
<div className="flex items-center justify-between py-1.5">
|
|
|
|
|
<span className="text-xs text-muted-foreground">12컬럼 그리드 사용</span>
|
2025-12-19 15:44:38 +09:00
|
|
|
<Checkbox
|
|
|
|
|
checked={config.use12Column !== false}
|
|
|
|
|
onCheckedChange={(checked) => updateConfig("use12Column", checked)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2026-03-11 16:42:06 +09:00
|
|
|
<div className="flex gap-2">
|
|
|
|
|
<div className="flex-1">
|
2025-12-19 15:44:38 +09:00
|
|
|
<Label className="text-[10px] text-muted-foreground">컬럼 수</Label>
|
|
|
|
|
<Select
|
|
|
|
|
value={String(config.columns || 12)}
|
|
|
|
|
onValueChange={(value) => updateConfig("columns", Number(value))}
|
|
|
|
|
>
|
2026-03-11 16:42:06 +09:00
|
|
|
<SelectTrigger className="h-7 text-xs">
|
2025-12-19 15:44:38 +09:00
|
|
|
<SelectValue />
|
|
|
|
|
</SelectTrigger>
|
|
|
|
|
<SelectContent>
|
|
|
|
|
<SelectItem value="1">1</SelectItem>
|
|
|
|
|
<SelectItem value="2">2</SelectItem>
|
|
|
|
|
<SelectItem value="3">3</SelectItem>
|
|
|
|
|
<SelectItem value="4">4</SelectItem>
|
|
|
|
|
<SelectItem value="6">6</SelectItem>
|
|
|
|
|
<SelectItem value="12">12</SelectItem>
|
|
|
|
|
</SelectContent>
|
|
|
|
|
</Select>
|
|
|
|
|
</div>
|
2026-03-11 16:42:06 +09:00
|
|
|
<div className="flex-1">
|
2025-12-19 15:44:38 +09:00
|
|
|
<Label className="text-[10px] text-muted-foreground">간격 (px)</Label>
|
|
|
|
|
<Input
|
|
|
|
|
value={config.gap || "16"}
|
|
|
|
|
onChange={(e) => updateConfig("gap", e.target.value)}
|
|
|
|
|
placeholder="16"
|
2026-03-11 16:42:06 +09:00
|
|
|
className="h-7 text-xs"
|
2025-12-19 15:44:38 +09:00
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
2026-03-11 16:42:06 +09:00
|
|
|
{/* SPLIT SETTINGS 섹션 */}
|
2025-12-19 15:44:38 +09:00
|
|
|
{config.layoutType === "split" && (
|
2026-03-11 16:42:06 +09:00
|
|
|
<div className="border-b border-border/50 pb-3 mb-3">
|
|
|
|
|
<h4 className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground py-2">SPLIT SETTINGS</h4>
|
|
|
|
|
<div className="flex items-center justify-between py-1.5">
|
|
|
|
|
<span className="text-xs text-muted-foreground">분할 방향</span>
|
|
|
|
|
<div className="w-[140px]">
|
|
|
|
|
<Select
|
|
|
|
|
value={config.direction || "horizontal"}
|
|
|
|
|
onValueChange={(value) => updateConfig("direction", value)}
|
|
|
|
|
>
|
|
|
|
|
<SelectTrigger className="h-7 text-xs">
|
|
|
|
|
<SelectValue />
|
|
|
|
|
</SelectTrigger>
|
|
|
|
|
<SelectContent>
|
|
|
|
|
<SelectItem value="horizontal">가로</SelectItem>
|
|
|
|
|
<SelectItem value="vertical">세로</SelectItem>
|
|
|
|
|
</SelectContent>
|
|
|
|
|
</Select>
|
|
|
|
|
</div>
|
2025-12-19 15:44:38 +09:00
|
|
|
</div>
|
2026-03-11 16:42:06 +09:00
|
|
|
<div className="flex gap-2 py-1.5">
|
|
|
|
|
<div className="flex-1">
|
|
|
|
|
<Label className="text-[10px] text-muted-foreground">비율 (%)</Label>
|
2025-12-19 15:44:38 +09:00
|
|
|
<Input
|
|
|
|
|
type="number"
|
|
|
|
|
value={config.splitRatio?.[0] || 50}
|
|
|
|
|
onChange={(e) => updateConfig("splitRatio", [Number(e.target.value), 100 - Number(e.target.value)])}
|
|
|
|
|
placeholder="50"
|
|
|
|
|
min="10"
|
|
|
|
|
max="90"
|
2026-03-11 16:42:06 +09:00
|
|
|
className="h-7 text-xs"
|
2025-12-19 15:44:38 +09:00
|
|
|
/>
|
2026-03-11 16:42:06 +09:00
|
|
|
</div>
|
|
|
|
|
<div className="flex-1">
|
|
|
|
|
<Label className="text-[10px] text-muted-foreground">나머지</Label>
|
2025-12-19 15:44:38 +09:00
|
|
|
<Input
|
|
|
|
|
type="number"
|
|
|
|
|
value={config.splitRatio?.[1] || 50}
|
|
|
|
|
disabled
|
2026-03-11 16:42:06 +09:00
|
|
|
className="h-7 text-xs bg-muted"
|
2025-12-19 15:44:38 +09:00
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-03-11 16:42:06 +09:00
|
|
|
<div className="flex items-center justify-between py-1.5">
|
|
|
|
|
<span className="text-xs text-muted-foreground">크기 조절 가능</span>
|
2025-12-19 15:44:38 +09:00
|
|
|
<Checkbox
|
|
|
|
|
checked={config.resizable !== false}
|
|
|
|
|
onCheckedChange={(checked) => updateConfig("resizable", checked)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
2026-03-11 16:42:06 +09:00
|
|
|
{/* FLEX SETTINGS 섹션 */}
|
2025-12-19 15:44:38 +09:00
|
|
|
{config.layoutType === "flex" && (
|
2026-03-11 16:42:06 +09:00
|
|
|
<div className="border-b border-border/50 pb-3 mb-3">
|
|
|
|
|
<h4 className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground py-2">FLEX SETTINGS</h4>
|
|
|
|
|
<div className="flex items-center justify-between py-1.5">
|
|
|
|
|
<span className="text-xs text-muted-foreground">방향</span>
|
|
|
|
|
<div className="w-[140px]">
|
|
|
|
|
<Select
|
|
|
|
|
value={config.direction || "row"}
|
|
|
|
|
onValueChange={(value) => updateConfig("direction", value)}
|
|
|
|
|
>
|
|
|
|
|
<SelectTrigger className="h-7 text-xs">
|
|
|
|
|
<SelectValue />
|
|
|
|
|
</SelectTrigger>
|
|
|
|
|
<SelectContent>
|
|
|
|
|
<SelectItem value="row">가로</SelectItem>
|
|
|
|
|
<SelectItem value="column">세로</SelectItem>
|
|
|
|
|
<SelectItem value="row-reverse">가로 (역순)</SelectItem>
|
|
|
|
|
<SelectItem value="column-reverse">세로 (역순)</SelectItem>
|
|
|
|
|
</SelectContent>
|
|
|
|
|
</Select>
|
|
|
|
|
</div>
|
2025-12-19 15:44:38 +09:00
|
|
|
</div>
|
2026-03-11 16:42:06 +09:00
|
|
|
<div className="flex gap-2">
|
|
|
|
|
<div className="flex-1">
|
2025-12-19 15:44:38 +09:00
|
|
|
<Label className="text-[10px] text-muted-foreground">정렬</Label>
|
|
|
|
|
<Select
|
|
|
|
|
value={config.justifyContent || "flex-start"}
|
|
|
|
|
onValueChange={(value) => updateConfig("justifyContent", value)}
|
|
|
|
|
>
|
2026-03-11 16:42:06 +09:00
|
|
|
<SelectTrigger className="h-7 text-xs">
|
2025-12-19 15:44:38 +09:00
|
|
|
<SelectValue />
|
|
|
|
|
</SelectTrigger>
|
|
|
|
|
<SelectContent>
|
|
|
|
|
<SelectItem value="flex-start">시작</SelectItem>
|
|
|
|
|
<SelectItem value="center">가운데</SelectItem>
|
|
|
|
|
<SelectItem value="flex-end">끝</SelectItem>
|
|
|
|
|
<SelectItem value="space-between">양끝 정렬</SelectItem>
|
|
|
|
|
<SelectItem value="space-around">균등 배치</SelectItem>
|
|
|
|
|
</SelectContent>
|
|
|
|
|
</Select>
|
|
|
|
|
</div>
|
2026-03-11 16:42:06 +09:00
|
|
|
<div className="flex-1">
|
2025-12-19 15:44:38 +09:00
|
|
|
<Label className="text-[10px] text-muted-foreground">교차축 정렬</Label>
|
|
|
|
|
<Select
|
|
|
|
|
value={config.alignItems || "stretch"}
|
|
|
|
|
onValueChange={(value) => updateConfig("alignItems", value)}
|
|
|
|
|
>
|
2026-03-11 16:42:06 +09:00
|
|
|
<SelectTrigger className="h-7 text-xs">
|
2025-12-19 15:44:38 +09:00
|
|
|
<SelectValue />
|
|
|
|
|
</SelectTrigger>
|
|
|
|
|
<SelectContent>
|
|
|
|
|
<SelectItem value="flex-start">시작</SelectItem>
|
|
|
|
|
<SelectItem value="center">가운데</SelectItem>
|
|
|
|
|
<SelectItem value="flex-end">끝</SelectItem>
|
|
|
|
|
<SelectItem value="stretch">늘리기</SelectItem>
|
|
|
|
|
</SelectContent>
|
|
|
|
|
</Select>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-03-11 16:42:06 +09:00
|
|
|
<div className="flex items-center justify-between py-1.5">
|
|
|
|
|
<span className="text-xs text-muted-foreground">간격 (px)</span>
|
|
|
|
|
<div className="w-[140px]">
|
|
|
|
|
<Input
|
|
|
|
|
value={config.gap || "16"}
|
|
|
|
|
onChange={(e) => updateConfig("gap", e.target.value)}
|
|
|
|
|
placeholder="16"
|
|
|
|
|
className="h-7 text-xs"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2025-12-19 15:44:38 +09:00
|
|
|
</div>
|
2026-03-11 16:42:06 +09:00
|
|
|
<div className="flex items-center justify-between py-1.5">
|
|
|
|
|
<span className="text-xs text-muted-foreground">줄바꿈 허용</span>
|
2025-12-19 15:44:38 +09:00
|
|
|
<Checkbox
|
|
|
|
|
checked={config.wrap || false}
|
|
|
|
|
onCheckedChange={(checked) => updateConfig("wrap", checked)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
2026-03-11 16:42:06 +09:00
|
|
|
{/* SCREEN EMBED 섹션 */}
|
2025-12-19 15:44:38 +09:00
|
|
|
{config.layoutType === "screen-embed" && (
|
2026-03-11 16:42:06 +09:00
|
|
|
<div className="border-b border-border/50 pb-3 mb-3">
|
|
|
|
|
<h4 className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground py-2">SCREEN EMBED</h4>
|
|
|
|
|
<div className="flex items-center justify-between py-1.5">
|
|
|
|
|
<span className="text-xs text-muted-foreground">화면 ID</span>
|
|
|
|
|
<div className="w-[140px]">
|
|
|
|
|
<Input
|
|
|
|
|
type="number"
|
|
|
|
|
value={config.screenId || ""}
|
|
|
|
|
onChange={(e) => updateConfig("screenId", e.target.value ? Number(e.target.value) : undefined)}
|
|
|
|
|
placeholder="화면 ID"
|
|
|
|
|
className="h-7 text-xs"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-12-19 15:44:38 +09:00
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2026-01-28 17:36:19 +09:00
|
|
|
V2LayoutConfigPanel.displayName = "V2LayoutConfigPanel";
|
2025-12-19 15:44:38 +09:00
|
|
|
|
2026-01-28 17:36:19 +09:00
|
|
|
export default V2LayoutConfigPanel;
|