"use client"; import React, { useRef, useState } from "react"; type Role = "ADMIN" | "GUEST" | "SCIENTIST"; const roleLabels: Record = { ADMIN: "Admin", GUEST: "Guest", SCIENTIST: "Scientist", }; type User = { id: number; email: string; name: string; role: Role; password: string; createdAt: string; }; // todo add fulfilling of requests // todo create api route to get users, with auth for only admin // todo add management of only junior scientists if senior scientist // todo (optional) add display of each user's previous orders when selecting them const initialUsers: User[] = [ { email: "john@example.com", name: "John Doe", role: "ADMIN", password: "secret1", createdAt: "2024-06-21T09:15:01Z", id: 1 }, { email: "jane@example.com", name: "Jane Smith", role: "GUEST", password: "secret2", createdAt: "2024-06-21T10:01:09Z", id: 2 }, { email: "bob@example.com", name: "Bob Brown", role: "SCIENTIST", password: "secret3", createdAt: "2024-06-21T12:13:45Z", id: 3, }, { email: "alice@example.com", name: "Alice Johnson", role: "GUEST", password: "secret4", createdAt: "2024-06-20T18:43:20Z", id: 4, }, { email: "eve@example.com", name: "Eve Black", role: "ADMIN", password: "secret5", createdAt: "2024-06-20T19:37:10Z", id: 5 }, { email: "dave@example.com", name: "Dave Clark", role: "GUEST", password: "pw", createdAt: "2024-06-19T08:39:10Z", id: 6 }, { email: "fred@example.com", name: "Fred Fox", role: "GUEST", password: "pw", createdAt: "2024-06-19T09:11:52Z", id: 7 }, { email: "ginny@example.com", name: "Ginny Hall", role: "SCIENTIST", password: "pw", createdAt: "2024-06-17T14:56:27Z", id: 8 }, { email: "harry@example.com", name: "Harry Lee", role: "ADMIN", password: "pw", createdAt: "2024-06-16T19:28:11Z", id: 9 }, { email: "ivy@example.com", name: "Ivy Volt", role: "ADMIN", password: "pw", createdAt: "2024-06-15T21:04:05Z", id: 10 }, { email: "kate@example.com", name: "Kate Moss", role: "SCIENTIST", password: "pw", createdAt: "2024-06-14T11:16:35Z", id: 11 }, { email: "leo@example.com", name: "Leo Garrison", role: "GUEST", password: "pw", createdAt: "2024-06-12T08:02:51Z", id: 12 }, { email: "isaac@example.com", name: "Isaac Yang", role: "GUEST", password: "pw", createdAt: "2024-06-12T15:43:29Z", id: 13 }, ]; const sortFields = [ // Sort box options { label: "Name", value: "name" }, { label: "Email", value: "email" }, ] as const; type SortField = (typeof sortFields)[number]["value"]; type SortDir = "asc" | "desc"; const dirLabels: Record = { asc: "ascending", desc: "descending" }; const fieldLabels: Record = { name: "Name", email: "Email" }; export default function AdminPage() { const [users, setUsers] = useState(initialUsers); const [selectedEmail, setSelectedEmail] = useState(null); // Local edit state for SCIENTIST form const [editUser, setEditUser] = useState(null); // Reset editUser when the selected user changes React.useEffect(() => { if (!selectedEmail) setEditUser(null); else { const user = users.find((u) => u.email === selectedEmail); setEditUser(user ? { ...user } : null); } }, [selectedEmail, users]); // Search/filter/sort state const [searchField, setSearchField] = useState<"name" | "email">("name"); const [searchText, setSearchText] = useState(""); const [roleFilter, setRoleFilter] = useState("all"); const [sortField, setSortField] = useState("name"); const [sortDir, setSortDir] = useState("asc"); // Dropdown states const [filterDropdownOpen, setFilterDropdownOpen] = useState(false); const [sortDropdownOpen, setSortDropdownOpen] = useState(false); const filterDropdownRef = useRef(null); const sortDropdownRef = useRef(null); React.useEffect(() => { const handleClick = (e: MouseEvent) => { if (filterDropdownRef.current && !filterDropdownRef.current.contains(e.target as Node)) setFilterDropdownOpen(false); if (sortDropdownRef.current && !sortDropdownRef.current.contains(e.target as Node)) setSortDropdownOpen(false); }; document.addEventListener("mousedown", handleClick); return () => document.removeEventListener("mousedown", handleClick); }, []); // Filtering, searching, sorting logic const filteredUsers = users.filter((user) => roleFilter === "all" || user.role === roleFilter); const searchedUsers = filteredUsers.filter((user) => user[searchField].toLowerCase().includes(searchText.toLowerCase())); const sortedUsers = [...searchedUsers].sort((a, b) => { let cmp = a[sortField].localeCompare(b[sortField]); return sortDir === "asc" ? cmp : -cmp; }); // Form input change handler const handleEditChange = (e: React.ChangeEvent) => { if (!editUser) return; const { name, value } = e.target; setEditUser((prev) => (prev ? { ...prev, [name]: value } : null)); }; // Update button logic (compare original selectedUser and editUser) const selectedUser = users.find((u) => u.email === selectedEmail); const isEditChanged = React.useMemo(() => { if (!editUser || !selectedUser) return false; // Compare primitive fields return ( editUser.name !== selectedUser.name || editUser.role !== selectedUser.role || editUser.password !== selectedUser.password ); }, [editUser, selectedUser]); // Update/save changes const handleUpdate = (e: React.FormEvent) => { e.preventDefault(); if (!editUser) return; setUsers((prev) => prev.map((u) => (u.email === editUser.email ? { ...editUser } : u))); // todo create receiving api route // todo send to api route // After successful update, update selectedUser local state // (editUser will auto-sync due to useEffect on users) }; // Delete user logic const handleDelete = () => { if (!selectedUser) return; if (!window.confirm(`Are you sure you want to delete "${selectedUser.name}"? This cannot be undone.`)) return; setUsers((prev) => prev.filter((u) => u.email !== selectedUser.email)); setSelectedEmail(null); setEditUser(null); }; const allRoles: Role[] = ["ADMIN", "GUEST", "SCIENTIST"]; // Tooltip handling for email field const [showEmailTooltip, setShowEmailTooltip] = useState(false); return (
{/* SIDEBAR */}
{/* Search Bar */}
setSearchText(e.target.value)} />
{/* Filter and Sort Buttons */}
{/* Filter */}
{filterDropdownOpen && (
{allRoles.map((role) => ( ))}
)}
{/* Sort */}
{sortDropdownOpen && (
{sortFields.map((opt) => ( ))}
)}
{/* Asc/Desc Toggle */}
{/* Sort status text */} Users sorted by {fieldLabels[sortField]} {dirLabels[sortDir]} {/* USERS LIST: full height, scrollable */}
    {sortedUsers.map((user) => (
  • setSelectedEmail(user.email)} className={`rounded-lg cursor-pointer border ${selectedEmail === user.email ? "bg-blue-100 border-blue-400" : "hover:bg-gray-200 border-transparent"} transition px-2 py-1 mb-1`} >
    {user.name} {roleLabels[user.role]}
    {user.email}
  • ))} {sortedUsers.length === 0 &&
  • No users found.
  • }
{/* MAIN PANEL */}
{editUser ? (

Edit User

{editUser.createdAt}
{editUser.id}
setShowEmailTooltip(true)} onMouseLeave={() => setShowEmailTooltip(false)} /> {/* Custom tooltip */} {showEmailTooltip && (
This field cannot be changed.
To change the email, delete and re-add the user.
)}
) : (
Select a user...
)}
); }