/* eslint-disable react-hooks/exhaustive-deps */ import React, { useState, useCallback, useEffect, useMemo } from 'react'; import { RouteComponentProps, Link } from '@reach/router'; import { ChevronRightIcon, SearchIcon, PlusIcon } from '@heroicons/react/solid'; import { CogIcon, TrashIcon } from '@heroicons/react/outline'; import { useUsers } from 'src/services/users'; import { Table } from 'src/components'; import { ConfirmationModal } from 'src/components/Modal'; import { UserModal } from './components/UserModal'; const pages = [{ name: 'Users', href: '#', current: true }]; export const Users: React.FC<RouteComponentProps> = () => { const [selectedRowsIds, setSelectedRowsIds] = useState({}); const [deleteModal, setDeleteModal] = useState(false); const [configureModal, setConfigureModal] = useState(false); const [search, setSearch] = useState(''); const { loadUsers, users } = useUsers(); const handleSearch = useCallback((event: any) => { setSearch(event.target.value); }, []); // TODO: Check why it needs any const allUsers: any = users.items; useEffect(() => { const asyncFc = async () => { try { await loadUsers(); } catch { // continue } }; asyncFc(); /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, []); const filterSearch = useMemo(() => { return allUsers.filter((item: any) => item.name?.toLowerCase().includes(search.toLowerCase())); }, [search, allUsers]); const deleteModalOpen = () => setDeleteModal(true); const deleteModalClose = () => setDeleteModal(false); const configureModalOpen = () => setConfigureModal(true); const configureModalClose = () => setConfigureModal(false); const columns: any = React.useMemo( () => [ { Header: 'Name', accessor: 'name', width: 'auto', }, { Header: 'Email', accessor: 'email', width: 'auto', }, { Header: 'Status', accessor: 'status', width: 'auto', }, { Header: 'Last Sign-In', accessor: 'last_login', width: 'auto', }, { Header: ' ', Cell: () => { return ( <div className="text-right opacity-0 group-hover:opacity-100 transition-opacity"> <button onClick={configureModalOpen} type="button" className="inline-flex items-center px-4 py-2 border border-gray-200 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500" > <CogIcon className="-ml-0.5 mr-2 h-4 w-4" aria-hidden="true" /> Configure </button> </div> ); }, width: 'auto', }, ], [], ); const selectedRows = useCallback((rows: Record<string, boolean>) => { setSelectedRowsIds(rows); }, []); return ( <div className="max-w-7xl mx-auto py-4 sm:px-6 lg:px-8 h-full flex-grow"> <nav className="flex mb-8" aria-label="Breadcrumb"> <ol className="flex items-center space-x-4"> <li> <div className="flex items-center"> <Link to="/dashboard" className="text-sm font-medium text-gray-500 hover:text-gray-700"> <span>Dashboard</span> </Link> </div> </li> {pages.map((page) => ( <li key={page.name}> <div className="flex items-center"> <ChevronRightIcon className="flex-shrink-0 h-5 w-5 text-gray-400" aria-hidden="true" /> <a href={page.href} className="ml-4 text-sm font-medium text-gray-500 hover:text-gray-700" aria-current={page.current ? 'page' : undefined} > {page.name} </a> </div> </li> ))} </ol> </nav> <div className="pb-5 border-b border-gray-200 sm:flex sm:items-center sm:justify-between"> <h1 className="text-3xl leading-6 font-bold text-gray-900">Users</h1> <div className="mt-3 sm:mt-0 sm:ml-4"> <button onClick={configureModalOpen} type="button" className="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-primary-700 hover:bg-primary-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-800" > <PlusIcon className="-ml-0.5 mr-2 h-4 w-4" aria-hidden="true" /> Add new user </button> </div> </div> <div className="flex justify-between w-100 my-3 items-center mb-5 "> <div className="flex items-center"> {/* <div className="mr-3 inline-block shadow-sm"> <label htmlFor="location" className="block text-sm font-medium text-gray-700 sr-only"> Location </label> <select id="location" name="location" className="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-200 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm rounded-md" defaultValue="All users" > <option>All users</option> <option>Owner</option> <option>Admins</option> <option>Members</option> </select> </div> */} <div className="inline-block"> <label htmlFor="email" className="block text-sm font-medium text-gray-700 sr-only"> Search candidates </label> <div className="mt-1 flex rounded-md shadow-sm"> <div className="relative flex items-stretch flex-grow focus-within:z-10"> <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none"> <SearchIcon className="h-5 w-5 text-gray-400" aria-hidden="true" /> </div> <input type="text" name="email" id="email" className="focus:ring-primary-500 focus:border-primary-500 block w-full rounded-md pl-10 sm:text-sm border-gray-200" placeholder="Search Users" onChange={handleSearch} /> </div> </div> </div> </div> {selectedRowsIds && Object.keys(selectedRowsIds).length !== 0 && ( <div className="flex items-center"> <button onClick={deleteModalOpen} type="button" className="inline-flex items-center px-4 py-2 text-sm font-medium rounded-md text-red-700 bg-red-50 hover:bg-red-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500" > <TrashIcon className="-ml-0.5 mr-2 h-4 w-4" aria-hidden="true" /> Delete </button> </div> )} </div> <div className="flex flex-col"> <div className="-my-2 sm:-mx-6 lg:-mx-8"> <div className="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8"> <div className="shadow border-b border-gray-200 sm:rounded-lg"> <Table data={filterSearch} columns={columns} getSelectedRowIds={selectedRows} selectable /> </div> </div> </div> </div> <ConfirmationModal open={deleteModal} onClose={deleteModalClose} title="Delete user" body="Are you sure you want to delete this user? All of your data will be permanently removed. This action cannot be undone." /> <UserModal open={configureModal} onClose={configureModalClose} onSave={configureModalClose} /> </div> ); };