style(admin): 세트리스트 드래그앤드롭 재정렬 추가

- framer-motion의 Reorder를 사용해 세트리스트 곡 순서를 드래그로 변경 가능
- 카드 왼쪽에 GripVertical 핸들 영역 분리, 오른쪽에 기존 폼 필드
- 내부 input/버튼은 드래그 임계값 덕분에 자유롭게 조작 가능

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
caadiq 2026-04-23 17:22:14 +09:00
parent 5472725e9c
commit 18efd952c4

View file

@ -1,5 +1,6 @@
import { useState, useRef, useEffect } from "react";
import { Plus, Trash2, Users, Search, Copy, ChevronDown } from "lucide-react";
import { Reorder } from "framer-motion";
import { Plus, Trash2, Users, Search, Copy, ChevronDown, GripVertical } from "lucide-react";
import ConfirmDialog from "@/components/pc/admin/common/ConfirmDialog";
import SongSearchDialog from "./SongSearchDialog";
@ -36,6 +37,7 @@ function SetlistSection({ rounds, setlists, setSetlists, members, selectedMember
}));
};
//
const [deleteConfirm, setDeleteConfirm] = useState({
isOpen: false,
@ -283,10 +285,24 @@ function SetlistSection({ rounds, setlists, setSetlists, members, selectedMember
</div>
)}
<div ref={containerRef} className="flex flex-col gap-4">
{setlist.map((song, index) => (
<div key={song.id}>
<div className="p-4 bg-gray-50 rounded-xl space-y-3">
<Reorder.Group
axis="y"
values={setlist}
onReorder={(next) => updateCurrentSetlist(next)}
ref={containerRef}
className="flex flex-col gap-4"
>
{setlist.map((song, index) => (
<Reorder.Item
key={song.id}
value={song}
className="flex items-stretch bg-gray-50 rounded-xl overflow-hidden cursor-grab active:cursor-grabbing"
>
{/* 드래그 핸들 (시각적 표시용, 카드 전체가 드래그 가능) */}
<div className="flex items-center px-2 text-gray-300">
<GripVertical size={18} />
</div>
<div className="flex-1 p-4 space-y-3 min-w-0">
{/* 헤더 */}
<div className="flex items-center justify-between">
<span className="text-sm font-medium text-gray-700">
@ -375,10 +391,10 @@ function SetlistSection({ rounds, setlists, setSetlists, members, selectedMember
})}
</div>
</div>
</div>
</div>
))}
</div>
</Reorder.Item>
))}
</Reorder.Group>
<div className="flex gap-2 mt-4">
<button