이메일 인증 재발송과 관리자 승인 개선

This commit is contained in:
2026-06-25 16:51:29 +09:00
parent 5fbd58bd07
commit a5b7d720d6
26 changed files with 688 additions and 91 deletions

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./style/output.css?v=4.0.9" />
<link rel="stylesheet" href="./style/output.css?v=4.0.15" />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700;800;900&family=Noto+Sans+KR:wght@400;700;900&display=swap" rel="stylesheet" />
<title>관리자 - UNIARE</title>
</head>
@@ -117,6 +117,7 @@
</div>
<p id="modal-error" class="mt-2 hidden text-[0.8125rem] text-red-500"></p>
<div class="my-4 h-px bg-slate-200"></div>
<button type="button" id="approve-email-verification" class="mb-2 hidden w-full cursor-pointer rounded-xl border border-emerald-200 bg-emerald-50 px-4 py-2.5 text-[0.8125rem] font-bold text-emerald-700 hover:bg-emerald-100">이메일 인증 승인</button>
<button type="button" id="open-password-modal" class="w-full cursor-pointer rounded-xl border border-slate-200 bg-white px-4 py-2.5 text-[0.8125rem] font-bold text-slate-600 hover:bg-slate-50">비밀번호 변경하기</button>
<div class="mt-3 flex gap-2">
<button type="button" id="modal-cancel" class="flex-1 cursor-pointer rounded-xl border-0 bg-slate-100 px-4 py-2.5 text-[0.8125rem] font-bold text-slate-600 hover:bg-slate-200">취소</button>
@@ -152,7 +153,7 @@
</div>
</div>
<script src="/script/api.js"></script>
<script src="/script/api.js?v=4.0.15"></script>
<script src="/script/image-utils.js"></script>
<script src="/script/auth-header.js"></script>
<script>
@@ -277,6 +278,7 @@
<div class="flex gap-1">
<span class="rounded-md bg-blue-50 px-1.5 py-0.5 text-[0.625rem] font-bold text-blue-600">${escapeHtml(u.role)}</span>
<span class="rounded-md px-1.5 py-0.5 text-[0.625rem] font-bold ${u.isActive ? 'bg-emerald-50 text-emerald-600' : 'bg-slate-100 text-slate-500'}">${u.isActive ? '활성' : '비활성'}</span>
<span class="rounded-md px-1.5 py-0.5 text-[0.625rem] font-bold ${u.emailVerifiedAt ? 'bg-emerald-50 text-emerald-600' : 'bg-amber-50 text-amber-700'}">${u.emailVerifiedAt ? '이메일 인증' : '이메일 미인증'}</span>
</div>
<div class="mt-1.5 text-xs font-semibold text-slate-600" title="공개 덱 / 전체 저장 덱">덱 ${deckPublic}/${deckTotal} <span class="font-normal text-slate-400">(공개/전체)</span></div>
</div>
@@ -316,6 +318,10 @@
document.getElementById('toggle-role-editor').classList.toggle('hidden', isSelf);
document.getElementById('edit-role-hint').classList.toggle('hidden', !isSelf);
document.getElementById('edit-status-hint').classList.toggle('hidden', !isSelf);
document.getElementById('approve-email-verification').classList.toggle(
'hidden',
Boolean(u.emailVerifiedAt),
);
document.getElementById('modal-error').classList.add('hidden');
setModalOpen(editModal, true);
@@ -500,6 +506,24 @@
document.getElementById('password-error').classList.add('hidden');
setModalOpen(passwordModal, true);
});
document.getElementById('approve-email-verification').addEventListener('click', async () => {
if (!editingUser || editingUser.emailVerifiedAt) return;
if (!confirm(`${editingUser.email} 계정의 이메일 인증을 승인하시겠습니까?`)) return;
const errEl = document.getElementById('modal-error');
errEl.classList.add('hidden');
try {
const result = await UaDeckApi.adminVerifyUserEmail(editingUser.id);
editingUser.emailVerifiedAt = result.emailVerifiedAt;
document.getElementById('approve-email-verification').classList.add('hidden');
await loadUsers(document.getElementById('user-search').value);
alert('이메일 인증을 승인했습니다.');
} catch (err) {
errEl.textContent = err.message;
errEl.classList.remove('hidden');
}
});
document.getElementById('toggle-role-editor').addEventListener('click', () => {
if (!editingUser || editingUser.id === currentAdminId) return;
setRoleEditorOpen(!isRoleEditorOpen);