10.3 사용자 검색/정지/권한 변경 o

This commit is contained in:
koreacomp5
2025-10-09 18:31:37 +09:00
parent 4167fcb332
commit 375f4c5681
5 changed files with 148 additions and 1 deletions

View File

@@ -0,0 +1,71 @@
"use client";
import useSWR from "swr";
import { useState } from "react";
const fetcher = (url: string) => fetch(url).then((r) => r.json());
export default function AdminUsersPage() {
const [q, setQ] = useState("");
const { data, mutate } = useSWR<{ users: any[] }>(`/api/admin/users?q=${encodeURIComponent(q)}`, fetcher);
const users = data?.users ?? [];
return (
<div>
<h1> </h1>
<div style={{ display: "flex", gap: 8, marginBottom: 12 }}>
<input placeholder="검색(nickname/phone/name)" value={q} onChange={(e) => setQ(e.target.value)} />
</div>
<table style={{ width: "100%", borderCollapse: "collapse" }}>
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{users.map((u) => (
<Row key={u.userId} u={u} onChanged={mutate} />
))}
</tbody>
</table>
</div>
);
}
function Row({ u, onChanged }: { u: any; onChanged: () => void }) {
const [status, setStatus] = useState(u.status);
const [roles, setRoles] = useState<string[]>(u.roles ?? []);
async function save() {
await fetch(`/api/admin/users/${u.userId}/status`, { method: "PATCH", headers: { "content-type": "application/json" }, body: JSON.stringify({ status }) });
await fetch(`/api/admin/users/${u.userId}/roles`, { method: "PATCH", headers: { "content-type": "application/json" }, body: JSON.stringify({ roles }) });
onChanged();
}
const allRoles = ["admin", "editor", "user"] as const;
return (
<tr>
<td>{u.nickname}</td>
<td>{u.name}</td>
<td>{u.phone}</td>
<td>
<select value={status} onChange={(e) => setStatus(e.target.value)}>
<option value="active">active</option>
<option value="suspended">suspended</option>
<option value="withdrawn">withdrawn</option>
</select>
</td>
<td>
{allRoles.map((r) => (
<label key={r} style={{ marginRight: 8 }}>
<input type="checkbox" checked={roles.includes(r)} onChange={(e) => setRoles((prev) => (e.target.checked ? Array.from(new Set([...prev, r])) : prev.filter((x) => x !== r)))} /> {r}
</label>
))}
</td>
<td><button onClick={save}></button></td>
</tr>
);
}