v4.0.9: 관리자 회원 목록 2열·덱 공개/전체 통계 추가
관리자가 회원별 저장 덱 이용 현황을 한눈에 볼 수 있도록 API 집계와 UI를 보강한다. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
27
admin.html
27
admin.html
@@ -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.6" />
|
||||
<link rel="stylesheet" href="./style/output.css?v=4.0.9" />
|
||||
<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>
|
||||
@@ -35,7 +35,7 @@
|
||||
<input type="search" id="user-search" class="box-border min-w-0 flex-1 rounded-xl border border-slate-200 bg-slate-50 px-4 py-2.5 text-sm outline-none transition focus:border-blue-500 focus:bg-white focus:ring-2 focus:ring-blue-500/15" placeholder="이메일, 사용자명 검색..." />
|
||||
<button type="button" id="user-search-btn" class="cursor-pointer rounded-xl border-0 bg-slate-800 px-5 py-2.5 text-sm font-bold text-white transition hover:bg-slate-700">검색</button>
|
||||
</div>
|
||||
<div id="user-list" class="flex flex-col gap-3"></div>
|
||||
<div id="user-list" class="grid grid-cols-1 gap-3 sm:grid-cols-2"></div>
|
||||
</section>
|
||||
|
||||
<section id="tab-decks" class="hidden">
|
||||
@@ -215,23 +215,26 @@
|
||||
const { users, total } = await UaDeckApi.adminGetUsers(q);
|
||||
const list = document.getElementById('user-list');
|
||||
list.innerHTML =
|
||||
`<p class="mb-4 text-xs text-slate-400">총 ${total}명</p>` +
|
||||
`<p class="col-span-full mb-1 text-xs text-slate-400">총 ${total}명</p>` +
|
||||
users
|
||||
.map((u) => {
|
||||
const isSelf = u.id === currentAdminId;
|
||||
const deckPublic = Number(u.deckPublic ?? 0);
|
||||
const deckTotal = Number(u.deckTotal ?? 0);
|
||||
return `
|
||||
<article class="rounded-2xl border border-slate-200 bg-white px-[1.125rem] py-4 shadow-sm">
|
||||
<div class="flex items-center gap-4">
|
||||
<img src="${escapeHtml(resolveAvatarSrc(u))}" alt="" class="h-12 w-12 shrink-0 rounded-full border-2 border-slate-200 bg-slate-100 object-cover" onerror="this.src='${DEFAULT_AVATAR}'" />
|
||||
<article class="rounded-2xl border border-slate-200 bg-white px-4 py-3.5 shadow-sm">
|
||||
<div class="flex items-start gap-3">
|
||||
<img src="${escapeHtml(resolveAvatarSrc(u))}" alt="" class="h-11 w-11 shrink-0 rounded-full border-2 border-slate-200 bg-slate-100 object-cover" onerror="this.src='${DEFAULT_AVATAR}'" />
|
||||
<div class="min-w-0 flex-1">
|
||||
<h3 class="mb-1 text-[0.9375rem] font-bold leading-snug text-slate-900">${escapeHtml(u.username)}${isSelf ? ' <span class="rounded-md bg-blue-50 px-2 py-0.5 text-[0.625rem] font-bold text-blue-600">나</span>' : ''}</h3>
|
||||
<div class="text-xs leading-normal text-slate-400">${escapeHtml(u.email)}</div>
|
||||
<div class="mt-2 flex flex-wrap gap-1.5">
|
||||
<span class="rounded-md bg-blue-50 px-2 py-0.5 text-[0.625rem] font-bold text-blue-600">${escapeHtml(u.role)}</span>
|
||||
<span class="rounded-md px-2 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>
|
||||
<h3 class="mb-0.5 text-sm font-bold leading-snug text-slate-900">${escapeHtml(u.username)}${isSelf ? ' <span class="rounded-md bg-blue-50 px-1.5 py-0.5 text-[0.625rem] font-bold text-blue-600">나</span>' : ''}</h3>
|
||||
<div class="truncate text-xs text-slate-400">${escapeHtml(u.email)}</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 class="mt-1.5 flex flex-wrap 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>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" data-edit='${JSON.stringify(u).replace(/'/g, ''')}' class="shrink-0 cursor-pointer rounded-lg border-0 bg-slate-100 px-3 py-1.5 text-[0.6875rem] font-bold text-slate-600 hover:bg-slate-200">수정</button>
|
||||
<button type="button" data-edit='${JSON.stringify(u).replace(/'/g, ''')}' class="shrink-0 cursor-pointer rounded-lg border-0 bg-slate-100 px-2.5 py-1.5 text-[0.6875rem] font-bold text-slate-600 hover:bg-slate-200">수정</button>
|
||||
</div>
|
||||
</article>`;
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user