import { ChevronLeft, ChevronRight, MoreHorizontal, Plus, SlidersHorizontal, Trash2 } from 'lucide-react'; import { useEffect, useMemo, useState, type FormEvent } from 'react'; import { Badge, Button, Card, CardHeader, Modal } from '../../components/ui'; import { useToast } from '../../components/toast'; import { authApiEndpoints } from '../../data/mock'; import { PageTitle } from '../../layout/AppLayout'; import { LoadingModal, useMinimumLoading } from '../operations/operation-utils'; import { createLauncherCommonSetting, deleteLauncherCommonSetting, listLauncherCommonSettings, updateLauncherCommonSetting, type LauncherCommonSetting } from './launcher-api'; type FormState = { key: string; name: string; type: string; value: string; description: string; isActive: boolean; isSecret: boolean; }; const emptyForm: FormState = { key: '', name: '', type: 'endpoint', value: '', description: '', isActive: true, isSecret: false }; const settingsPageSize = 10; function maskValue(setting: LauncherCommonSetting) { if (!setting.isSecret) return setting.value; if (!setting.value) return '-'; return '******'; } function toForm(setting?: LauncherCommonSetting): FormState { if (!setting) return emptyForm; return { key: setting.key, name: setting.name, type: setting.type, value: setting.value, description: setting.description ?? '', isActive: setting.isActive, isSecret: setting.isSecret }; } export function LauncherCommonSettingsPage() { const { toast } = useToast(); const [apiOpen, setApiOpen] = useState(false); const [settings, setSettings] = useState([]); const [loading, setLoading] = useState(true); const [modalOpen, setModalOpen] = useState(false); const [editing, setEditing] = useState(null); const [form, setForm] = useState(emptyForm); const [saving, setSaving] = useState(false); const [page, setPage] = useState(1); const loadingVisible = useMinimumLoading(loading); const totalPages = Math.max(1, Math.ceil(settings.length / settingsPageSize)); const pagedSettings = settings.slice((page - 1) * settingsPageSize, page * settingsPageSize); const summary = useMemo(() => ({ total: settings.length, endpoint: settings.filter((item) => item.type === 'endpoint').length, database: settings.filter((item) => item.type === 'database').length, active: settings.filter((item) => item.isActive).length }), [settings]); const refresh = () => { setLoading(true); listLauncherCommonSettings() .then(setSettings) .catch((error: Error) => { toast({ type: 'error', title: '공통 설정 조회 실패', message: error.message }); }) .finally(() => setLoading(false)); }; useEffect(() => { refresh(); }, []); useEffect(() => { setPage((currentPage) => Math.min(currentPage, totalPages)); }, [totalPages]); const openCreate = () => { setEditing(null); setForm(emptyForm); setModalOpen(true); }; const openEdit = (setting: LauncherCommonSetting) => { setEditing(setting); setForm(toForm(setting)); setModalOpen(true); }; const submit = (event: FormEvent) => { event.preventDefault(); setSaving(true); const payload = { key: form.key.trim(), name: form.name.trim(), type: form.type.trim(), value: form.value.trim(), description: form.description.trim(), isActive: form.isActive, isSecret: form.isSecret }; const request = editing ? updateLauncherCommonSetting(editing.id, payload) : createLauncherCommonSetting(payload); request .then(() => { toast({ type: 'success', message: editing ? '설정을 수정했습니다.' : '설정을 추가했습니다.' }); setModalOpen(false); refresh(); }) .catch((error: Error) => { toast({ type: 'error', title: editing ? '설정 수정 실패' : '설정 추가 실패', message: error.message }); }) .finally(() => setSaving(false)); }; const remove = () => { if (!editing) return; setSaving(true); deleteLauncherCommonSetting(editing.id) .then(() => { toast({ type: 'success', message: '설정을 삭제했습니다.' }); setModalOpen(false); refresh(); }) .catch((error: Error) => { toast({ type: 'error', title: '설정 삭제 실패', message: error.message }); }) .finally(() => setSaving(false)); }; return ( <> } />
{[ ['설정 항목', `${summary.total}개`], ['Endpoint', `${summary.endpoint}개`], ['Database', `${summary.database}개`], ['활성 상태', `${summary.active}개`] ].map(([label, value]) => (

{label}

{value}

))}
{!loading && settings.length === 0 ? ( ) : null} {pagedSettings.map((setting) => ( ))}
설정 Key Type Value 관리
등록된 설정이 없습니다.

{setting.name}

{setting.description ?

{setting.description}

: null}
{setting.key} {setting.type} {maskValue(setting)}
{loading ? '불러오는 중' : `총 ${settings.length}건 · ${page} / ${totalPages}`}
setModalOpen(false)} className="!max-w-2xl" footer={ <> {editing ? ( ) : null} } >