feat(festival-bot): 다이얼로그에 활성 월 선택 UI
축제 봇 추가/수정 다이얼로그에 1~12월 토글 그리드 + 전체 선택/해제 추가. 신규 봇은 전체 월(항상 실행) 기본. 전체 선택은 active_months null로 저장. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
8b36e9b5f7
commit
2af3af9345
1 changed files with 57 additions and 1 deletions
|
|
@ -17,6 +17,8 @@ const INTERVAL_OPTIONS = [
|
|||
{ value: 1440, label: '24시간' },
|
||||
];
|
||||
|
||||
const ALL_MONTHS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
|
||||
|
||||
/**
|
||||
* 커스텀 드롭다운 (Portal 사용)
|
||||
*/
|
||||
|
|
@ -118,8 +120,17 @@ function FestivalBotDialog({ isOpen, onClose, botId = null, onSuccess }) {
|
|||
const [name, setName] = useState('');
|
||||
const [searchUrl, setSearchUrl] = useState('');
|
||||
const [interval, setInterval] = useState(360);
|
||||
const [activeMonths, setActiveMonths] = useState(ALL_MONTHS);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
|
||||
const allMonthsSelected = activeMonths.length === ALL_MONTHS.length;
|
||||
const toggleMonth = (m) =>
|
||||
setActiveMonths((prev) =>
|
||||
prev.includes(m) ? prev.filter((x) => x !== m) : [...prev, m].sort((a, b) => a - b)
|
||||
);
|
||||
const toggleAllMonths = () =>
|
||||
setActiveMonths(allMonthsSelected ? [] : [...ALL_MONTHS]);
|
||||
|
||||
// 축제 봇 상세 조회 (수정 모드)
|
||||
const { data: bot, isLoading: botLoading } = useQuery({
|
||||
queryKey: ['admin', 'festival-bot', botId],
|
||||
|
|
@ -137,11 +148,18 @@ function FestivalBotDialog({ isOpen, onClose, botId = null, onSuccess }) {
|
|||
setName(bot.name || '');
|
||||
setSearchUrl(bot.search_url || '');
|
||||
setInterval(bot.cron_interval || 360);
|
||||
// active_months: null(전체) → 전체 선택, 배열이면 그대로
|
||||
setActiveMonths(
|
||||
Array.isArray(bot.active_months) && bot.active_months.length > 0
|
||||
? bot.active_months
|
||||
: [...ALL_MONTHS]
|
||||
);
|
||||
} else if (!botId) {
|
||||
// 추가 모드
|
||||
// 추가 모드 (기본: 전체 월 = 항상 실행)
|
||||
setName('');
|
||||
setSearchUrl('');
|
||||
setInterval(360);
|
||||
setActiveMonths([...ALL_MONTHS]);
|
||||
}
|
||||
}, [isOpen, bot, botId]);
|
||||
|
||||
|
|
@ -156,6 +174,8 @@ function FestivalBotDialog({ isOpen, onClose, botId = null, onSuccess }) {
|
|||
name: name.trim(),
|
||||
search_url: searchUrl.trim(),
|
||||
cron_interval: interval,
|
||||
// 전체 선택(또는 미선택)은 제한 없음(null)으로 저장
|
||||
active_months: allMonthsSelected ? null : activeMonths,
|
||||
};
|
||||
|
||||
if (isEdit) {
|
||||
|
|
@ -261,6 +281,42 @@ function FestivalBotDialog({ isOpen, onClose, botId = null, onSuccess }) {
|
|||
placeholder="간격 선택"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 활성 월 */}
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-1.5">
|
||||
<label className="text-sm font-medium text-gray-700">활성 월</label>
|
||||
<button
|
||||
type="button"
|
||||
onClick={toggleAllMonths}
|
||||
className="text-xs font-medium text-emerald-600 hover:text-emerald-700"
|
||||
>
|
||||
{allMonthsSelected ? '전체 해제' : '전체 선택'}
|
||||
</button>
|
||||
</div>
|
||||
<div className="grid grid-cols-6 gap-1.5">
|
||||
{ALL_MONTHS.map((m) => {
|
||||
const on = activeMonths.includes(m);
|
||||
return (
|
||||
<button
|
||||
key={m}
|
||||
type="button"
|
||||
onClick={() => toggleMonth(m)}
|
||||
className={`py-2 rounded-lg text-sm font-medium transition-colors ${
|
||||
on
|
||||
? 'bg-emerald-500 text-white'
|
||||
: 'bg-gray-100 text-gray-400 hover:bg-gray-200'
|
||||
}`}
|
||||
>
|
||||
{m}월
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<p className="text-xs text-gray-400 mt-1.5">
|
||||
선택한 월에만 봇이 실행됩니다. 전체 선택 시 항상 실행됩니다.
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue