ui(admin): fix users list

This commit is contained in:
Matthew Penner 2023-01-25 11:14:39 -07:00
parent 5063db7d95
commit 4b82ca1042
No known key found for this signature in database
5 changed files with 126 additions and 92 deletions

View file

@ -4,7 +4,7 @@ import { useState } from 'react';
import Checkbox from '@/components/elements/inputs/Checkbox';
import { Dropdown } from '@/components/elements/dropdown';
import { Dialog } from '@/components/elements/dialog';
import { User } from '@definitions/admin';
import type { User } from '@definitions/admin';
interface Props {
user: User;
@ -12,7 +12,7 @@ interface Props {
onRowChange: (user: User, selected: boolean) => void;
}
const UserTableRow = ({ user, selected, onRowChange }: Props) => {
function UserTableRow({ user, selected, onRowChange }: Props) {
const [visible, setVisible] = useState(false);
return (
@ -56,12 +56,14 @@ const UserTableRow = ({ user, selected, onRowChange }: Props) => {
</span>
)}
</td>
<td className={'whitespace-nowrap px-6 py-4'}>
<td className="whitespace-nowrap px-6 py-4">
<Dropdown>
<Dropdown.Button className={'px-2'}>
<Dropdown.Button className="px-2">
<DotsVerticalIcon />
</Dropdown.Button>
<Dropdown.Item icon={<PencilIcon />}>Edit</Dropdown.Item>
<Dropdown.Item to={`/admin/users/${user.id}`} icon={<PencilIcon />}>
Edit
</Dropdown.Item>
<Dropdown.Item icon={<SupportIcon />}>Reset Password</Dropdown.Item>
<Dropdown.Item icon={<LockOpenIcon />} disabled={!user.isUsingTwoFactor}>
Disable 2-FA
@ -76,6 +78,6 @@ const UserTableRow = ({ user, selected, onRowChange }: Props) => {
</tr>
</>
);
};
}
export default UserTableRow;

View file

@ -1,5 +1,6 @@
import { LockOpenIcon, PlusIcon, SupportIcon, TrashIcon } from '@heroicons/react/solid';
import { Fragment, useEffect, useState } from 'react';
import { NavLink } from 'react-router-dom';
import { useGetUsers } from '@/api/admin/users';
import type { UUID } from '@/api/definitions';
@ -16,7 +17,7 @@ import { Shape } from '@/components/elements/button/types';
const filters = ['id', 'uuid', 'external_id', 'username', 'email'] as const;
const UsersContainer = () => {
function UsersContainer() {
const [search, setSearch] = useDebouncedState('', 500);
const [selected, setSelected] = useState<UUID[]>([]);
const { data: users } = useGetUsers(
@ -42,13 +43,16 @@ const UsersContainer = () => {
return (
<div>
<div className={'mb-4 flex justify-end'}>
<Button className={'shadow focus:ring-offset-2 focus:ring-offset-neutral-800'}>
Add User <PlusIcon className={'ml-2 h-5 w-5'} />
</Button>
<div className="mb-4 flex justify-end">
<NavLink to="/admin/users/new">
<Button className="shadow focus:ring-offset-2 focus:ring-offset-neutral-800">
Add User <PlusIcon className="ml-2 h-5 w-5" />
</Button>
</NavLink>
</div>
<div className={'relative flex items-center rounded-t bg-neutral-700 px-4 py-2'}>
<div className={'mr-6'}>
<div className="relative flex items-center rounded-t bg-neutral-700 px-4 py-2">
<div className="mr-6">
<Checkbox
checked={selectAllChecked}
disabled={!users?.items.length}
@ -56,22 +60,18 @@ const UsersContainer = () => {
onChange={onSelectAll}
/>
</div>
<div className={'flex-1'}>
<div className="flex-1">
<InputField
type={'text'}
name={'filter'}
placeholder={'Begin typing to filter...'}
className={'w-56 focus:w-96'}
type="text"
name="filter"
placeholder="Begin typing to filter..."
className="w-56 focus:w-96"
onChange={e => setSearch(e.currentTarget.value)}
/>
</div>
<Transition.Fade as={Fragment} show={selected.length > 0} duration={'duration-75'}>
<div
className={
'absolute top-0 left-0 flex h-full w-full items-center justify-end space-x-4 rounded-t bg-neutral-700 px-4'
}
>
<div className={'flex-1'}>
<Transition.Fade as={Fragment} show={selected.length > 0} duration="duration-75">
<div className="absolute top-0 left-0 flex h-full w-full items-center justify-end space-x-4 rounded-t bg-neutral-700 px-4">
<div className="flex-1">
<Checkbox
checked={selectAllChecked}
indeterminate={selected.length !== users?.items.length}
@ -79,26 +79,26 @@ const UsersContainer = () => {
/>
</div>
<Button.Text shape={Shape.IconSquare}>
<SupportIcon className={'h-4 w-4'} />
<SupportIcon className="h-4 w-4" />
</Button.Text>
<Button.Text shape={Shape.IconSquare}>
<LockOpenIcon className={'h-4 w-4'} />
<LockOpenIcon className="h-4 w-4" />
</Button.Text>
<Button.Text shape={Shape.IconSquare}>
<TrashIcon className={'h-4 w-4'} />
<TrashIcon className="h-4 w-4" />
</Button.Text>
</div>
</Transition.Fade>
</div>
<table className={'min-w-full rounded bg-neutral-700'}>
<thead className={'bg-neutral-900'}>
<table className="min-w-full rounded bg-neutral-700">
<thead className="bg-neutral-900">
<tr>
<th scope={'col'} className={'w-8'} />
<th scope={'col'} className={'w-full px-6 py-2 text-left'}>
<th scope="col" className="w-8" />
<th scope="col" className="w-full px-6 py-2 text-left">
Email
</th>
<th scope={'col'} />
<th scope={'col'} />
<th scope="col" />
<th scope="col" />
</tr>
</thead>
<tbody>
@ -111,10 +111,10 @@ const UsersContainer = () => {
/>
))}
</tbody>
{users && <TFootPaginated span={4} pagination={users.pagination} />}
{users ? <TFootPaginated span={4} pagination={users.pagination} /> : null}
</table>
</div>
);
};
}
export default UsersContainer;