feat: add admin test data reset

This commit is contained in:
unknown
2026-07-20 19:48:40 +09:00
parent 7617c9f371
commit c45c47109c
4 changed files with 127 additions and 2 deletions

View File

@@ -14,14 +14,15 @@ import {
updateAdminUserRoles,
runEmailDiagnostics,
runSmsDiagnostics,
resetVisitRequestTestData,
uploadAdminTeams,
uploadAdminUserRoles,
updateWatcher1Settings,
getWatcher1Settings,
} from '../api';
import { AdminExcelImportResult, AdminUser, EmailDiagnosticsResult, PurposeCode, Role, SmsDiagnosticsResult, Team, Watcher1Settings } from '../types';
import { AdminExcelImportResult, AdminUser, EmailDiagnosticsResult, PurposeCode, Role, SmsDiagnosticsResult, Team, VisitRequestResetResult, Watcher1Settings } from '../types';
type Tab = 'watcher' | 'purpose' | 'teams' | 'roles' | 'sms' | 'email';
type Tab = 'watcher' | 'purpose' | 'teams' | 'roles' | 'sms' | 'email' | 'data';
const EMPTY_PURPOSE = {
code: '',
@@ -141,6 +142,8 @@ export const AdminManagementPage: React.FC = () => {
const [userRoleUploadResult, setUserRoleUploadResult] = useState<AdminExcelImportResult | null>(null);
const [smsDiagnostics, setSmsDiagnostics] = useState<SmsDiagnosticsResult | null>(null);
const [emailDiagnostics, setEmailDiagnostics] = useState<EmailDiagnosticsResult | null>(null);
const [resetConfirm, setResetConfirm] = useState('');
const [resetResult, setResetResult] = useState<VisitRequestResetResult | null>(null);
const [notice, setNotice] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null);
const [busy, setBusy] = useState(false);
@@ -203,6 +206,27 @@ export const AdminManagementPage: React.FC = () => {
}
};
const resetVisitData = async () => {
if (resetConfirm.trim() !== '초기화') {
setError('확인 입력란에 "초기화"를 입력하세요.');
return;
}
setBusy(true);
setError(null);
setNotice(null);
setResetResult(null);
try {
const result = await resetVisitRequestTestData(resetConfirm);
setResetResult(result);
setResetConfirm('');
setNotice(`출입신청 테스트 데이터 초기화 완료: 신청 ${result.visitRequests}건 삭제`);
} catch (err) {
setError(err instanceof Error ? err.message : '테스트 데이터 초기화 실패');
} finally {
setBusy(false);
}
};
const editPurpose = (p: PurposeCode) => {
setEditingPurposeId(p.id);
setPurposeForm({
@@ -440,6 +464,7 @@ export const AdminManagementPage: React.FC = () => {
<button className={tab === 'roles' ? 'tab-active' : ''} onClick={() => setTab('roles')}></button>
<button className={tab === 'sms' ? 'tab-active' : ''} onClick={() => setTab('sms')}>SMS </button>
<button className={tab === 'email' ? 'tab-active' : ''} onClick={() => setTab('email')}>Email </button>
<button className={tab === 'data' ? 'tab-active' : ''} onClick={() => setTab('data')}> </button>
</div>
{tab === 'watcher' && (
@@ -616,6 +641,43 @@ export const AdminManagementPage: React.FC = () => {
</>
)}
{tab === 'data' && (
<div className="card">
<div className="admin-upload-head">
<h3> </h3>
</div>
<p className="muted">
, , / , . , , , , , .
</p>
<div className="admin-upload-controls">
<input
value={resetConfirm}
onChange={(e) => setResetConfirm(e.target.value)}
placeholder="초기화"
/>
<button
className="btn-danger"
type="button"
disabled={busy || resetConfirm.trim() !== '초기화'}
onClick={() => void resetVisitData()}
>
</button>
</div>
{resetResult && (
<table className="table diagnostic-table">
<tbody>
<tr><th></th><td>{resetResult.visitRequests}</td></tr>
<tr><th></th><td>{resetResult.visitors}</td></tr>
<tr><th> </th><td>{resetResult.approvals}</td></tr>
<tr><th>/ </th><td>{resetResult.accessEvents}</td></tr>
<tr><th> </th><td>{resetResult.passDeliveries}</td></tr>
</tbody>
</table>
)}
</div>
)}
{tab === 'sms' && (
<div className="card">
<div className="admin-upload-head">