"use client"; /** * V2Media 설정 패널 * 토스식 단계별 UX: 미디어 타입 카드 선택 -> 기본 설정 -> 타입별 설정 -> 고급 설정(접힘) */ import React, { useState } from "react"; import { Input } from "@/components/ui/input"; import { Switch } from "@/components/ui/switch"; import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "@/components/ui/collapsible"; import { FileText, Image, Video, Music, Settings, ChevronDown, } from "lucide-react"; import { cn } from "@/lib/utils"; // ─── 미디어 타입 카드 정의 ─── const MEDIA_TYPE_CARDS = [ { value: "file", icon: FileText, title: "파일", description: "일반 파일을 업로드해요", }, { value: "image", icon: Image, title: "이미지", description: "사진이나 그림을 올려요", }, { value: "video", icon: Video, title: "비디오", description: "동영상을 업로드해요", }, { value: "audio", icon: Music, title: "오디오", description: "음악이나 녹음을 올려요", }, ] as const; interface V2MediaConfigPanelProps { config: Record; onChange: (config: Record) => void; } export const V2MediaConfigPanel: React.FC = ({ config, onChange, }) => { const [advancedOpen, setAdvancedOpen] = useState(false); const updateConfig = (field: string, value: any) => { onChange({ ...config, [field]: value }); }; const currentMediaType = config.mediaType || config.type || "image"; const isImageType = currentMediaType === "image"; const isPlayerType = currentMediaType === "video" || currentMediaType === "audio"; return (
{/* ─── 1단계: 미디어 타입 선택 (카드) ─── */}

어떤 미디어를 업로드하나요?

{MEDIA_TYPE_CARDS.map((card) => { const Icon = card.icon; const isSelected = currentMediaType === card.value; return ( ); })}
{/* ─── 2단계: 기본 설정 ─── */}
파일 설정
허용 형식 updateConfig("accept", e.target.value)} placeholder=".jpg,.png,.pdf" className="h-8 w-[180px] text-sm" />
{/* ─── 3단계: 업로드 옵션 (Switch + 설명) ─── */}

여러 파일 업로드

한 번에 여러 파일을 선택할 수 있어요

updateConfig("multiple", checked)} />

미리보기

업로드한 파일의 미리보기가 표시돼요

updateConfig("preview", checked)} />

드래그 앤 드롭

파일을 끌어다 놓아서 업로드할 수 있어요

updateConfig("dragDrop", checked)} />
{/* ─── 4단계: 타입별 설정 ─── */} {/* 이미지 타입: 크기 제한 + 자르기 */} {isImageType && (
이미지 설정
최대 너비 (px) updateConfig("maxWidth", e.target.value ? Number(e.target.value) : undefined)} placeholder="자동" className="mt-1 h-8 text-sm" />
최대 높이 (px) updateConfig("maxHeight", e.target.value ? Number(e.target.value) : undefined)} placeholder="자동" className="mt-1 h-8 text-sm" />

자르기 기능

이미지를 원하는 크기로 잘라서 올릴 수 있어요

updateConfig("crop", checked)} />
)} {/* 비디오/오디오 타입: 플레이어 설정 */} {isPlayerType && (
{currentMediaType === "video" ? (

자동 재생

페이지를 열면 자동으로 재생돼요

updateConfig("autoplay", checked)} />

컨트롤 표시

재생, 정지, 볼륨 등 조작 버튼이 보여요

updateConfig("controls", checked)} />

반복 재생

끝나면 처음부터 다시 재생해요

updateConfig("loop", checked)} />
)} {/* ─── 5단계: 고급 설정 (기본 접혀있음) ─── */}
최대 크기 (MB) updateConfig("maxSize", e.target.value ? Number(e.target.value) : undefined)} placeholder="10" min="1" className="h-8 w-[180px] text-sm" />
최대 파일 수 updateConfig("maxFiles", e.target.value ? Number(e.target.value) : undefined)} placeholder="제한 없음" min="1" className="h-8 w-[180px] text-sm" />
); }; V2MediaConfigPanel.displayName = "V2MediaConfigPanel"; export default V2MediaConfigPanel;