style(admin): 세트리스트 드래그앤드롭 재정렬 추가
- framer-motion의 Reorder를 사용해 세트리스트 곡 순서를 드래그로 변경 가능 - 카드 왼쪽에 GripVertical 핸들 영역 분리, 오른쪽에 기존 폼 필드 - 내부 input/버튼은 드래그 임계값 덕분에 자유롭게 조작 가능 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5472725e9c
commit
18efd952c4
1 changed files with 24 additions and 8 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
import { useState, useRef, useEffect } from "react";
|
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 ConfirmDialog from "@/components/pc/admin/common/ConfirmDialog";
|
||||||
import SongSearchDialog from "./SongSearchDialog";
|
import SongSearchDialog from "./SongSearchDialog";
|
||||||
|
|
@ -36,6 +37,7 @@ function SetlistSection({ rounds, setlists, setSetlists, members, selectedMember
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 삭제 확인 다이얼로그
|
// 삭제 확인 다이얼로그
|
||||||
const [deleteConfirm, setDeleteConfirm] = useState({
|
const [deleteConfirm, setDeleteConfirm] = useState({
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
|
|
@ -283,10 +285,24 @@ function SetlistSection({ rounds, setlists, setSetlists, members, selectedMember
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div ref={containerRef} className="flex flex-col gap-4">
|
<Reorder.Group
|
||||||
{setlist.map((song, index) => (
|
axis="y"
|
||||||
<div key={song.id}>
|
values={setlist}
|
||||||
<div className="p-4 bg-gray-50 rounded-xl space-y-3">
|
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">
|
<div className="flex items-center justify-between">
|
||||||
<span className="text-sm font-medium text-gray-700">
|
<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>
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
</Reorder.Item>
|
||||||
</div>
|
))}
|
||||||
|
</Reorder.Group>
|
||||||
|
|
||||||
<div className="flex gap-2 mt-4">
|
<div className="flex gap-2 mt-4">
|
||||||
<button
|
<button
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue