Files
yourwillyourwish/app/admin/users/page-old.tsx
2026-02-06 21:44:04 -06:00

134 lines
4.7 KiB
TypeScript

"use client";
import { useState, useEffect } from "react";
import { getSession } from "../../../lib/auth/session";
import { redirect } from "next/navigation";
interface User {
id: string;
email: string;
firstName: string;
lastName: string;
role: string;
createdAt: string;
}
export default function AdminUsersPage() {
const [users, setUsers] = useState<User[]>([]);
const [loading, setLoading] = useState(true);
const [searchQuery, setSearchQuery] = useState("");
useEffect(() => {
fetchUsers();
}, []);
const fetchUsers = async () => {
try {
const response = await fetch("/api/admin/users");
if (response.ok) {
const data = await response.json();
setUsers(data.users || []);
}
} catch (error) {
console.error("Failed to fetch users:", error);
} finally {
setLoading(false);
}
};
const filteredUsers = users.filter(
(user) =>
user.email.toLowerCase().includes(searchQuery.toLowerCase()) ||
`${user.firstName} ${user.lastName}`.toLowerCase().includes(searchQuery.toLowerCase())
);
return (
<main className="max-w-7xl mx-auto px-6 py-16">
<div className="mb-8">
<h1 className="text-4xl font-bold mb-4 bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
Users Management
</h1>
<p className="text-lg text-gray-600 dark:text-gray-400">
Manage user accounts and permissions
</p>
</div>
<div className="card p-6 mb-6">
<input
type="text"
placeholder="Search users by name or email..."
className="input-field"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
/>
</div>
{loading ? (
<div className="text-center py-12">
<div className="inline-block w-8 h-8 border-4 border-primary border-r-transparent rounded-full animate-spin"></div>
<p className="mt-4 text-gray-600 dark:text-gray-400">Loading users...</p>
</div>
) : (
<div className="card overflow-hidden">
<div className="overflow-x-auto">
<table className="w-full">
<thead className="bg-gray-50 dark:bg-slate-800">
<tr>
<th className="px-6 py-4 text-left text-xs font-bold text-gray-700 dark:text-gray-300 uppercase">
User
</th>
<th className="px-6 py-4 text-left text-xs font-bold text-gray-700 dark:text-gray-300 uppercase">
Email
</th>
<th className="px-6 py-4 text-left text-xs font-bold text-gray-700 dark:text-gray-300 uppercase">
Role
</th>
<th className="px-6 py-4 text-left text-xs font-bold text-gray-700 dark:text-gray-300 uppercase">
Joined
</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200 dark:divide-slate-700">
{filteredUsers.length === 0 ? (
<tr>
<td colSpan={4} className="px-6 py-12 text-center text-gray-500">
No users found
</td>
</tr>
) : (
filteredUsers.map((user) => (
<tr key={user.id} className="hover:bg-gray-50 dark:hover:bg-slate-800/50">
<td className="px-6 py-4">
<div className="font-semibold text-gray-900 dark:text-white">
{user.firstName} {user.lastName}
</div>
</td>
<td className="px-6 py-4 text-gray-600 dark:text-gray-400">
{user.email}
</td>
<td className="px-6 py-4">
<span
className={`inline-flex px-3 py-1 rounded-full text-xs font-semibold ${
user.role === "ADMIN"
? "bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200"
: "bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200"
}`}
>
{user.role}
</span>
</td>
<td className="px-6 py-4 text-gray-600 dark:text-gray-400">
{new Date(user.createdAt).toLocaleDateString()}
</td>
</tr>
))
)}
</tbody>
</table>
</div>
</div>
)}
</main>
);
}