2022-02-21 00:10:58 +00:00
|
|
|
import React, { useEffect, useState } from 'react';
|
|
|
|
import http from '@/api/http';
|
|
|
|
import { User } from '@/api/admin/user';
|
|
|
|
import { AdminTransformers } from '@/api/admin/transformers';
|
2022-02-26 20:13:13 +00:00
|
|
|
import { Dropdown } from '@/components/elements/dropdown';
|
2022-02-26 22:05:30 +00:00
|
|
|
import {
|
2022-02-27 02:26:53 +00:00
|
|
|
BanIcon,
|
2022-02-26 22:05:30 +00:00
|
|
|
DotsVerticalIcon,
|
2022-02-27 02:26:53 +00:00
|
|
|
LockOpenIcon,
|
2022-02-26 22:05:30 +00:00
|
|
|
PencilIcon,
|
|
|
|
PlusIcon,
|
2022-02-27 02:26:53 +00:00
|
|
|
SupportIcon,
|
2022-02-26 22:05:30 +00:00
|
|
|
TrashIcon,
|
|
|
|
} from '@heroicons/react/solid';
|
|
|
|
import { Button } from '@/components/elements/button/index';
|
|
|
|
import { Dialog } from '@/components/elements/dialog';
|
2022-02-27 02:51:40 +00:00
|
|
|
import { Checkbox, InputField } from '@/components/elements/inputs';
|
2022-02-21 00:10:58 +00:00
|
|
|
|
|
|
|
const UsersContainerV2 = () => {
|
|
|
|
const [ users, setUsers ] = useState<User[]>([]);
|
|
|
|
useEffect(() => {
|
|
|
|
document.title = 'Admin | Users';
|
|
|
|
}, []);
|
|
|
|
|
2022-02-26 22:05:30 +00:00
|
|
|
const [ visible, setVisible ] = useState(false);
|
|
|
|
|
2022-02-21 00:10:58 +00:00
|
|
|
useEffect(() => {
|
|
|
|
http.get('/api/application/users')
|
|
|
|
.then(({ data }) => {
|
|
|
|
setUsers(data.data.map(AdminTransformers.toUser));
|
|
|
|
})
|
|
|
|
.catch(console.error);
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
return (
|
2022-02-26 22:05:30 +00:00
|
|
|
<div>
|
|
|
|
<div className={'flex justify-end mb-4'}>
|
|
|
|
<Button className={'shadow focus:ring-offset-2 focus:ring-offset-neutral-800'}>
|
|
|
|
Add User <PlusIcon className={'ml-2 w-5 h-5'}/>
|
|
|
|
</Button>
|
|
|
|
</div>
|
|
|
|
<Dialog title={'Delete account'} visible={visible} onDismissed={() => setVisible(false)}>
|
|
|
|
<Dialog.Icon type={'danger'}/>
|
|
|
|
This account will be permanently deleted.
|
|
|
|
<Dialog.Buttons>
|
2022-02-27 02:26:53 +00:00
|
|
|
<Button.Text
|
|
|
|
onClick={() => setVisible(false)}
|
2022-02-27 02:51:40 +00:00
|
|
|
>
|
|
|
|
Cancel
|
2022-02-27 02:26:53 +00:00
|
|
|
</Button.Text>
|
2022-02-27 02:51:40 +00:00
|
|
|
<Button.Danger>Delete</Button.Danger>
|
2022-02-26 22:05:30 +00:00
|
|
|
</Dialog.Buttons>
|
|
|
|
</Dialog>
|
2022-02-27 02:51:40 +00:00
|
|
|
<div className={'flex items-center rounded-t bg-neutral-700 px-4 py-2'}>
|
|
|
|
<div className={'mr-6'}>
|
|
|
|
<Checkbox />
|
|
|
|
</div>
|
|
|
|
<div className={'flex-1'}>
|
|
|
|
<InputField type={'text'} name={'filter'} placeholder={'Begin typing to filter...'} className={'w-56 focus:w-96'} />
|
|
|
|
</div>
|
|
|
|
</div>
|
2022-02-26 22:05:30 +00:00
|
|
|
<table className={'min-w-full rounded bg-neutral-700'}>
|
2022-02-21 00:10:58 +00:00
|
|
|
<thead className={'bg-neutral-900'}>
|
|
|
|
<tr>
|
|
|
|
<th scope={'col'} className={'w-8'}/>
|
|
|
|
<th scope={'col'} className={'text-left px-6 py-2 w-full'}>Email</th>
|
|
|
|
<th scope={'col'}/>
|
2022-02-27 02:26:53 +00:00
|
|
|
<th scope={'col'}/>
|
2022-02-21 00:10:58 +00:00
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
{users.map(user => (
|
|
|
|
<tr key={user.uuid}>
|
|
|
|
<td className={'whitespace-nowrap'}>
|
|
|
|
<div className={'flex justify-end items-center w-8'}>
|
2022-02-27 02:26:53 +00:00
|
|
|
<Checkbox/>
|
2022-02-21 00:10:58 +00:00
|
|
|
</div>
|
|
|
|
</td>
|
|
|
|
<td className={'pl-6 py-4 whitespace-nowrap'}>
|
|
|
|
<div className={'flex items-center'}>
|
|
|
|
<div className={'w-10 h-10'}>
|
|
|
|
<img
|
|
|
|
src={user.avatarUrl}
|
|
|
|
className={'w-10 h-10 rounded-full'}
|
|
|
|
alt={'User avatar'}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
<div className={'ml-4'}>
|
|
|
|
<p className={'font-medium'}>
|
|
|
|
{user.email}
|
|
|
|
</p>
|
|
|
|
<p className={'text-sm text-neutral-400'}>
|
|
|
|
{user.uuid}
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</td>
|
2022-02-27 02:26:53 +00:00
|
|
|
<td className={'pl-2 py-4 whitespace-nowrap'}>
|
|
|
|
{user.isUsingTwoFactor &&
|
|
|
|
<span className={'bg-green-100 uppercase text-green-600 font-semibold text-xs px-2 py-0.5 rounded'}>
|
|
|
|
2-FA Enabled
|
|
|
|
</span>
|
|
|
|
}
|
|
|
|
</td>
|
2022-02-21 00:10:58 +00:00
|
|
|
<td className={'px-6 py-4 whitespace-nowrap'}>
|
2022-02-26 20:13:13 +00:00
|
|
|
<Dropdown>
|
|
|
|
<Dropdown.Button className={'px-2'}>
|
2022-02-26 22:05:30 +00:00
|
|
|
<DotsVerticalIcon/>
|
2022-02-26 20:13:13 +00:00
|
|
|
</Dropdown.Button>
|
2022-02-26 22:05:30 +00:00
|
|
|
<Dropdown.Item icon={<PencilIcon/>}>Edit</Dropdown.Item>
|
2022-02-27 02:26:53 +00:00
|
|
|
<Dropdown.Item icon={<SupportIcon/>}>Reset Password</Dropdown.Item>
|
|
|
|
<Dropdown.Item icon={<LockOpenIcon/>} disabled={!user.isUsingTwoFactor}>
|
|
|
|
Disable 2-FA
|
|
|
|
</Dropdown.Item>
|
|
|
|
<Dropdown.Item icon={<BanIcon/>}>Suspend</Dropdown.Item>
|
2022-02-26 22:05:30 +00:00
|
|
|
<Dropdown.Gap/>
|
2022-02-27 02:26:53 +00:00
|
|
|
<Dropdown.Item icon={<TrashIcon/>} onClick={() => setVisible(true)} danger>Delete
|
|
|
|
Account
|
|
|
|
</Dropdown.Item>
|
2022-02-26 20:13:13 +00:00
|
|
|
</Dropdown>
|
2022-02-21 00:10:58 +00:00
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
))}
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default UsersContainerV2;
|