import styles from './UsersPage.module.scss'; import { useEffect, useRef, useState } from 'react'; import useSWR from 'swr'; import useUser from '../../lib/hooks/useUser'; import { PaginatedResponse } from '../../lib/types/paginated-response.interface'; import { UserListItem } from '../../lib/types/users.interfaces'; import { Container } from '../common/Container/Container'; import { Header } from '../common/Header/Header'; import avatar from '../../public/avatar.png'; import Image from 'next/image'; import { UPLOADS_URL } from '../../lib/constants'; import { Paginator } from '../common/Paginator/Paginator'; import { Dropdown } from '../common/Dropdown/Dropdown'; import toast from 'react-hot-toast'; import { publishJSON } from '../../lib/utils/fetch'; import { useForm } from '../../lib/hooks/useForm'; import { ModalProps } from '../../lib/types/modal.interface'; import { Button } from '../common/Button/Button'; import { FormControl } from '../common/Form/FormControl/FormControl'; import { FormWrapper } from '../common/Form/FormWrapper/FormWrapper'; import Modal from '../common/Modal/Modal/Modal'; import ModalBody from '../common/Modal/ModalBody/ModalBody'; import ModalFooter from '../common/Modal/ModalFooter/ModalFooter'; import ModalHeader from '../common/Modal/ModalHeader/ModalHeader'; import ModalService from '../common/Modal/services/ModalService'; import { Privilege } from '../../lib/types/privilege.interface'; import useHasPrivileges from '../../lib/hooks/useHasPrivileges'; function getSelectValues(selectElement: HTMLSelectElement) { const result = []; const options = selectElement && selectElement.options; for (let i = 0, iLen = options.length; i < iLen; i++) { const opt = options[i]; if (opt.selected) { result.push(opt.value || opt.text); } } return result; } const PrivilegeEditor = ({ user, onChange, }: { user: UserListItem; onChange: (privvy: Privilege[]) => void; }) => { const [userPrivvy, setUserPrivvy] = useState(user.privileges || []); const [selectionAvailable, setSelectionAvailable] = useState([]); const [selectionExisting, setSelectionExisting] = useState([]); const [availablePrivileges, setAvailablePrivileges] = useState( [] ); const { data } = useSWR('/api/admin/privileges'); useEffect(() => { setAvailablePrivileges( (data || []).filter( ({ id }) => !(userPrivvy || []).some((privvy) => privvy.id === id) ) ); }, [user, data, userPrivvy]); return ( <>

Privileges

Available

Current

); }; const EditUserModal = ({ close, modalRef, privPriv, user, update, }: ModalProps<{ user: UserListItem; update: () => void; privPriv: boolean; }>) => { const formRef = useRef(null); const { formData, handleInputChange, handleSubmit } = useForm< Partial >(user, async () => { // Save privileges if (privPriv) { await toast.promise( publishJSON(`/api/admin/users/${user.id}/privileges`, 'PUT', { privileges: (user.privileges || []).map(({ id }) => id), }), { loading: 'Saving privileges...', success: 'Privileges saved!', error: 'Failed to save privileges.', } ); } // Save user data toast .promise(publishJSON(`/api/admin/users/${user.id}`, 'PATCH', formData), { loading: 'Saving user...', success: 'User saved!', error: (err) => `Saving the user failed: ${err.message}`, }) .then((data) => { if (data) { close(true); update(); } }); return false; }); return (

Edit user details

{privPriv && ( (formData.privileges = privileges) } > )}
); }; const UserCard = ({ user, update, privPriv, }: { user: UserListItem; update: () => void; privPriv: boolean; }) => (
{user.picture ? ( ) : ( )}

{user.display_name}{' '} @{user.username}

{!user.activated && ( )} {user.activated && ( )} {user.picture && ( )}
UUID
{user.uuid}
Email
{user.email}
{user.privileges && user.privileges.length > 0 && ( <>
Privileges
{user.privileges.map((privilege) => privilege.name).join(', ')}
)}
Activated
{user.activated ? 'Yes' : NOT ACTIVATED}
Registered
{new Date(user.created_at).toDateString()}
); const UserList = ({ pageIndex, searchTerm, privPriv, setPage, }: { pageIndex: number; searchTerm: string; privPriv: boolean; setPage: (page: number) => void; }) => { const { data, mutate } = useSWR>( `/api/admin/users?page=${pageIndex}${searchTerm ? `&q=${searchTerm}` : ''}` ); return data ? ( <> {data?.list?.length && (
{data.list.map((user) => ( ))}
)} ) : ( Nothing found ); }; export const UsersPage = () => { const { user } = useUser({ redirectTo: '/login' }); const [pageIndex, setPageIndex] = useState(1); const [searchTerm, setSearchTerm] = useState(''); const privPriv = useHasPrivileges(user, 'admin:user:privilege'); return ( <>

Users

setSearchTerm(e.target.value)} placeholder="Search usernames, display names, emails, UUIDs.." />
); };