style(concert): 네이티브 select를 커스텀 드롭다운으로 변경

- 선택된 회차 + 날짜 표시, 화살표 아이콘 회전 애니메이션
- 활성 항목 primary 하이라이트
- 외부 클릭 시 자동 닫기

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
caadiq 2026-03-31 18:09:26 +09:00
parent cdb94972a3
commit 637172ddd7

View file

@ -1,5 +1,5 @@
import { useState, useRef, useEffect } from "react";
import { Plus, Trash2, Users, Search, Copy } from "lucide-react";
import { Plus, Trash2, Users, Search, Copy, ChevronDown } from "lucide-react";
import ConfirmDialog from "@/components/pc/admin/common/ConfirmDialog";
import SongSearchDialog from "./SongSearchDialog";
@ -49,6 +49,23 @@ function SetlistSection({ rounds, setlists, setSetlists, members, selectedMember
//
const [copyFrom, setCopyFrom] = useState(null);
//
const [roundDropdownOpen, setRoundDropdownOpen] = useState(false);
const roundDropdownRef = useRef(null);
//
useEffect(() => {
const handleClickOutside = (e) => {
if (roundDropdownRef.current && !roundDropdownRef.current.contains(e.target)) {
setRoundDropdownOpen(false);
}
};
if (roundDropdownOpen) {
document.addEventListener("mousedown", handleClickOutside);
}
return () => document.removeEventListener("mousedown", handleClickOutside);
}, [roundDropdownOpen]);
//
const addSong = () => {
const newSong = {
@ -228,20 +245,41 @@ function SetlistSection({ rounds, setlists, setSetlists, members, selectedMember
)}
</div>
{/* 회차 선택 드롭다운 (2개 이상일 때만) */}
{/* 회차 선택 커스텀 드롭다운 (2개 이상일 때만) */}
{rounds.length > 1 && (
<div className="mb-4">
<select
value={activeRoundId}
onChange={(e) => setActiveRoundId(Number(e.target.value))}
className="px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"
<div className="relative mb-4" ref={roundDropdownRef}>
<button
type="button"
onClick={() => setRoundDropdownOpen(!roundDropdownOpen)}
className="flex items-center justify-between gap-2 w-48 px-3 py-2 border border-gray-200 rounded-lg text-sm bg-white hover:border-gray-300 transition-colors"
>
{rounds.map((round, index) => (
<option key={round.id} value={round.id}>
{index + 1}회차{round.date ? ` (${round.date})` : ''}
</option>
))}
</select>
<span className="truncate">
{activeRoundIndex + 1}회차
{rounds[activeRoundIndex]?.date ? ` (${rounds[activeRoundIndex].date})` : ''}
</span>
<ChevronDown size={14} className={`text-gray-400 transition-transform ${roundDropdownOpen ? 'rotate-180' : ''}`} />
</button>
{roundDropdownOpen && (
<div className="absolute left-0 top-full mt-1 w-48 bg-white border border-gray-200 rounded-lg shadow-lg z-10 py-1">
{rounds.map((round, index) => (
<button
key={round.id}
type="button"
onClick={() => {
setActiveRoundId(round.id);
setRoundDropdownOpen(false);
}}
className={`w-full px-3 py-2 text-sm text-left transition-colors ${
round.id === activeRoundId
? 'bg-primary/10 text-primary font-medium'
: 'hover:bg-gray-50 text-gray-700'
}`}
>
{index + 1}회차{round.date ? ` (${round.date})` : ''}
</button>
))}
</div>
)}
</div>
)}