'use client'; import { useState } from 'react'; import { FoxFileUpload } from '@fox/core/components/fox-file-upload'; import { FoxHelperText } from '@fox/core/components/fox-helper-text'; import { FoxTextButton } from '@fox/core/components/fox-text-button'; import { MIN_COMIC_CUTS } from '@/lib/domain/content'; import { FILE_MODULE, fileModuleAccept } from '@/lib/domain/file-module'; import styles from './content-form.module.scss'; interface ContentCutsFieldProps { /** 수정 화면에서 이미 등록된 컷 이미지 URL(1컷부터 순서대로). */ defaultCutUrls?: readonly string[]; /** 새로 고르지 않은 컷이 잃어버리지 않도록 들고 있는 기존 첨부 ID. */ retainedFileId?: string | null; error?: string; } type Cut = { key: number; url: string | null }; /** * 만화 이미지 — 시안 tbl-form(5449:10857)의 컷 업로드. * * 회색 판 위에 흰 컷 카드 4개가 깔리고 「컷 추가」로 계속 늘린다(기획 "4컷 이상 구성도 가능"). * 컷마다 점선 상자 자체가 파일선택 버튼이고, 아래에 「N컷 · 초기화 · 삭제」가 붙는다. * * 초기화는 그 컷의 선택만 비운다 — React key를 갈아 끼워 새로 마운트한다. 비제어 * `FoxFileUpload`가 들고 있는 파일과 네이티브 입력을 밖에서 비울 방법이 그것뿐이다. */ export function ContentCutsField({ defaultCutUrls = [], retainedFileId, error, }: ContentCutsFieldProps) { const [cuts, setCuts] = useState(() => { const count = Math.max(MIN_COMIC_CUTS, defaultCutUrls.length); return Array.from({ length: count }, (_, index) => ({ key: index, url: defaultCutUrls[index] ?? null, })); }); const [nextKey, setNextKey] = useState(cuts.length); function addCut() { setCuts((current) => [...current, { key: nextKey, url: null }]); setNextKey((current) => current + 1); } function resetCut(key: number) { setCuts((current) => current.map((cut) => cut.key === key ? { key: nextKey, url: null } : cut ) ); setNextKey((current) => current + 1); } function removeCut(key: number) { setCuts((current) => current.length <= MIN_COMIC_CUTS ? current : current.filter((cut) => cut.key !== key) ); } return ( <>
{cuts.map((cut, index) => (
{index + 1}컷
))}
{error && } ); }