integratedhub/islands/AdminCenter.tsx
2026-02-14 02:20:19 +00:00

114 lines
3.5 KiB
TypeScript

import { useState } from "preact/hooks";
import { Role, UserWithRole } from "../db/sqlUserRepository.ts";
interface AdminCenterProps {
users: UserWithRole[];
roles: Role[];
}
export default function AdminCenter({ users, roles }: AdminCenterProps) {
// Local state for forms per user
const [formState, setFormState] = useState<
Record<string, { roleId: string }>
>(
() => {
const state: Record<string, { roleId: string }> = {};
users.forEach((u) => {
state[u.id] = { roleId: u.role };
});
return state;
},
);
const handleRoleChange = (userId: string, roleId: string) => {
setFormState((prev) => ({ ...prev, [userId]: { roleId } }));
};
return (
<>
<button
type="button"
aria-label="Go back"
onClick={() => globalThis.location.href = "/"}
class="back-button"
>
<svg
width="32"
height="32"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<polyline points="15 18 9 12 15 6" />
</svg>
</button>
<div class="overflow-x-auto">
<table class="min-w-full bg-white rounded-xl shadow-lg">
<thead>
<tr class="bg-blue-100">
<th class="py-2 px-4 text-left">Name</th>
<th class="py-2 px-4 text-left">Email</th>
<th class="py-2 px-4 text-left">Role</th>
<th class="py-2 px-4"></th>
</tr>
</thead>
<tbody>
{users.map((user) => (
<tr key={user.id} class="border-b hover:bg-blue-50">
<td class="py-2 px-4">{user.name}</td>
<td class="py-2 px-4">{user.email}</td>
<td class="py-2 px-4">
<form
method="post"
action="/admin-center"
class="flex items-center gap-2"
>
<input type="hidden" name="rowUserId" value={user.id} />
<input
type="hidden"
name="inputUsers"
value={JSON.stringify(users)}
/>
<input
type="hidden"
name="inputRoles"
value={JSON.stringify(roles)}
/>
<select
name="selectedRole"
class="rounded border px-2 py-1"
value={formState[user.id]?.roleId || ""}
onChange={(e) =>
handleRoleChange(
user.id,
(e.target as HTMLSelectElement).value,
)}
>
<option value="">Select role</option>
{roles.map((role) => (
<option key={role.id} value={role.id}>
{role.description} ({role.id})
</option>
))}
</select>
<button
type="submit"
class="ml-2 px-3 py-1 rounded bg-blue-600 text-white hover:bg-blue-700 transition"
>
Save
</button>
</form>
</td>
<td></td>
</tr>
))}
</tbody>
</table>
</div>
</>
);
}