"use client"; import { useState, useEffect, useCallback } from "react"; import { useRouter } from "next/navigation"; import { AppShell } from "@/components/AppShell"; import { useAuth } from "@/components/AuthProvider"; import { APP_NAME } from "@/lib/constants"; import { ArrowLeft, Loader2, Plus, Trash2, Key, Shield, ShieldOff, User, X, } from "lucide-react"; import Link from "next/link"; interface UserData { id: string; email: string; name: string | null; isAdmin: boolean; createdAt: number; } export default function AdminPage() { const router = useRouter(); const { user } = useAuth(); const [users, setUsers] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); // Modal states const [showAddUser, setShowAddUser] = useState(false); const [showResetPassword, setShowResetPassword] = useState(null); const [showDeleteConfirm, setShowDeleteConfirm] = useState(null); // Form states const [newEmail, setNewEmail] = useState(""); const [newPassword, setNewPassword] = useState(""); const [newName, setNewName] = useState(""); const [newIsAdmin, setNewIsAdmin] = useState(false); const [resetPassword, setResetPassword] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); const loadUsers = useCallback(async () => { try { const res = await fetch("/api/admin/users"); if (res.status === 403) { router.push("/"); return; } if (res.ok) { setUsers(await res.json()); } else { setError("Failed to load users"); } } catch { setError("Failed to load users"); } finally { setIsLoading(false); } }, [router]); useEffect(() => { if (user && !user.isAdmin) { router.push("/"); return; } loadUsers(); }, [user, router, loadUsers]); const handleAddUser = async (e: React.FormEvent) => { e.preventDefault(); setIsSubmitting(true); setError(null); try { const res = await fetch("/api/admin/users", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email: newEmail, password: newPassword, name: newName, isAdmin: newIsAdmin, }), }); if (res.ok) { setShowAddUser(false); setNewEmail(""); setNewPassword(""); setNewName(""); setNewIsAdmin(false); loadUsers(); } else { const data = await res.json(); setError(data.error || "Failed to create user"); } } catch { setError("Failed to create user"); } finally { setIsSubmitting(false); } }; const handleResetPassword = async (e: React.FormEvent) => { e.preventDefault(); if (!showResetPassword) return; setIsSubmitting(true); setError(null); try { const res = await fetch(`/api/admin/users/${showResetPassword.id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ password: resetPassword }), }); if (res.ok) { setShowResetPassword(null); setResetPassword(""); } else { const data = await res.json(); setError(data.error || "Failed to reset password"); } } catch { setError("Failed to reset password"); } finally { setIsSubmitting(false); } }; const handleDeleteUser = async () => { if (!showDeleteConfirm) return; setIsSubmitting(true); setError(null); try { const res = await fetch(`/api/admin/users/${showDeleteConfirm.id}`, { method: "DELETE", }); if (res.ok) { setShowDeleteConfirm(null); loadUsers(); } else { const data = await res.json(); setError(data.error || "Failed to delete user"); } } catch { setError("Failed to delete user"); } finally { setIsSubmitting(false); } }; const toggleAdmin = async (targetUser: UserData) => { try { const res = await fetch(`/api/admin/users/${targetUser.id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ isAdmin: !targetUser.isAdmin }), }); if (res.ok) { loadUsers(); } else { const data = await res.json(); setError(data.error || "Failed to update user"); } } catch { setError("Failed to update user"); } }; if (!user?.isAdmin) { return null; } return (

{APP_NAME}

User Management

{error && (
{error}
)}
{isLoading ? (
) : (
{users.map((u) => (

{u.email}

{u.name || "No name"} • {u.isAdmin && "Admin • "} {new Date(u.createdAt).toLocaleDateString()}

))}
)} {/* Add User Modal */} {showAddUser && (

Add User

setNewEmail(e.target.value)} required className="w-full px-3 py-2 bg-background border border-border rounded-lg focus:outline-none focus:border-muted" />
setNewPassword(e.target.value)} required minLength={6} className="w-full px-3 py-2 bg-background border border-border rounded-lg focus:outline-none focus:border-muted" />
setNewName(e.target.value)} className="w-full px-3 py-2 bg-background border border-border rounded-lg focus:outline-none focus:border-muted" />
)} {/* Reset Password Modal */} {showResetPassword && (

Reset Password

Reset password for {showResetPassword.email}

setResetPassword(e.target.value)} required minLength={6} className="w-full px-3 py-2 bg-background border border-border rounded-lg focus:outline-none focus:border-muted" />
)} {/* Delete Confirmation Modal */} {showDeleteConfirm && (

Delete User?

This will permanently delete {showDeleteConfirm.email} and all their entries. This cannot be undone.

)}
); }