diff --git a/src/modules/users/Users.tsx b/src/modules/users/Users.tsx index c40cc794947c6b87834fb1e42cf2bae6b7993b96..814c4c9719df98498be6bed21a80803929ca653d 100644 --- a/src/modules/users/Users.tsx +++ b/src/modules/users/Users.tsx @@ -4,14 +4,16 @@ import { 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 { debounce } from 'lodash'; +import _, { debounce } from 'lodash'; import { useAuth } from 'src/services/auth'; import { UserModal } from '../../components/UserModal'; +import { MultipleUsersModal } from './components'; export const Users: React.FC = () => { const [selectedRowsIds, setSelectedRowsIds] = useState({}); const [configureModal, setConfigureModal] = useState(false); + const [multipleUsersModal, setMultipleUsersModal] = useState(false); const [userId, setUserId] = useState(null); const [search, setSearch] = useState(''); const { users, loadUsers, userTableLoading } = useUsers(); @@ -106,6 +108,14 @@ export const Users: React.FC = () => { <PlusIcon className="-ml-0.5 mr-2 h-4 w-4" aria-hidden="true" /> Add new user </button> + <button + onClick={() => setMultipleUsersModal(true)} + 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 users + </button> </div> )} </div> @@ -166,6 +176,13 @@ export const Users: React.FC = () => { {configureModal && ( <UserModal open={configureModal} onClose={configureModalClose} userId={userId} setUserId={setUserId} /> )} + {multipleUsersModal && ( + <MultipleUsersModal + open={multipleUsersModal} + onClose={() => setMultipleUsersModal(false)} + onUpload={_.noop} + /> + )} </div> </div> ); diff --git a/src/modules/users/components/MultipleUsersModal/MultipleUsersModal.tsx b/src/modules/users/components/MultipleUsersModal/MultipleUsersModal.tsx new file mode 100644 index 0000000000000000000000000000000000000000..f57e28d938c66a78ce992c787023b75c25d47545 --- /dev/null +++ b/src/modules/users/components/MultipleUsersModal/MultipleUsersModal.tsx @@ -0,0 +1,124 @@ +import React, { ChangeEvent, ChangeEventHandler, useEffect, useState } from 'react'; +import _ from 'lodash'; +// import { TrashIcon } from '@heroicons/react/outline'; +// import { useFieldArray, useForm, useWatch } from 'react-hook-form'; +import { Modal, Tabs } from 'src/components'; +// import { Input, Select } from 'src/components/Form'; +import { useUsers } from 'src/services/users'; +import { useAuth } from 'src/services/auth'; +import { MultipleUsersModalProps } from './types'; +import { csvFileToArray } from './utils'; + +export const MultipleUsersModal = ({ open, onClose, onUpload }: MultipleUsersModalProps) => { + const [file, setFile] = useState<File>(); + const { userModalLoading } = useUsers(); + const { currentUser, isAdmin } = useAuth(); + + const handleOnChange = (e: ChangeEvent<HTMLInputElement>) => { + setFile(_.get(e.target, 'files[0]')); + console.log(_.get(e.target, 'files[0]')); + }; + + const handleSubmit = () => { + // e.preventDefault(); + + if (file) { + const formData = new FormData(); + formData.append('image', file, file.name); + + // console.log('csv to array', csvFileToArray(file)); + console.log('submit', formData); + } else { + console.log('nothing in file?'); + } + }; + + const renderUpload = () => { + return ( + <div> + <div>Please upload CSV file using , as a delimiter</div> + <div> + <input type="file" id="csvFileInput" accept=".csv" onChange={handleOnChange} /> + <button onClick={handleSubmit}>IMPORT CSV</button> + </div> + </div> + ); + }; + + const renderMultilineInput = () => { + return ( + <div> + <textarea + rows={5} + name="description" + className="w-full rounded-md border-gray-700 focus:border-gray-700 shadow-none focus:shadow-slate-800" + > + Enter details here... + </textarea> + </div> + ); + }; + + const handleSave = async () => { + // try { + // if (userId) { + // await handleSubmit((data) => editUserById(data))(); + // } else { + // await handleSubmit((data) => createNewUser(data))(); + // } + // } catch (e: any) { + // // Continue + // } + + onUpload(); + + onClose(); + }; + + const handleClose = () => { + onClose(); + }; + + return ( + <> + <Modal + onClose={handleClose} + open={open} + onSave={handleSave} + isLoading={userModalLoading} + // leftActions={ + // userId && + // user.email !== currentUser?.email && ( + // <button + // onClick={deleteModalOpen} + // type="button" + // className="mb-4 sm:mb-0 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> + // ) + // } + useCancelButton + > + <div className="bg-white px-4"> + <div className="space-y-10 divide-y divide-gray-200"> + <div> + <div> + <h3 className="text-lg leading-6 font-medium text-gray-900">Add new users</h3> + </div> + <div className="sm:p-6"> + <Tabs + tabs={[ + { name: 'Add users', component: renderMultilineInput() }, + { name: 'Import from file', component: renderUpload() }, + ]} + /> + </div> + </div> + </div> + </div> + </Modal> + </> + ); +}; diff --git a/src/modules/users/components/MultipleUsersModal/index.ts b/src/modules/users/components/MultipleUsersModal/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..b8c3b1abdcb63e5dffe1ed477b643f9e595adfe1 --- /dev/null +++ b/src/modules/users/components/MultipleUsersModal/index.ts @@ -0,0 +1 @@ +export { MultipleUsersModal } from './MultipleUsersModal'; diff --git a/src/modules/users/components/MultipleUsersModal/types.ts b/src/modules/users/components/MultipleUsersModal/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..2a3a28076cb437cf7c729f665841c89de6343bd5 --- /dev/null +++ b/src/modules/users/components/MultipleUsersModal/types.ts @@ -0,0 +1,5 @@ +export type MultipleUsersModalProps = { + open: boolean; + onClose: () => void; + onUpload: () => void; +}; diff --git a/src/modules/users/components/MultipleUsersModal/utils.ts b/src/modules/users/components/MultipleUsersModal/utils.ts new file mode 100644 index 0000000000000000000000000000000000000000..7934b5d770dfda94bd12d19a376e90e4c3f342af --- /dev/null +++ b/src/modules/users/components/MultipleUsersModal/utils.ts @@ -0,0 +1,14 @@ +import { User } from 'src/services/users'; + +export const csvFileToArray = (csvData: string) => { + const csvRows = csvData.slice(csvData.indexOf('\n') + 1).split('\n'); + + const array = csvRows.map((i) => { + const values = i.split(','); + const email = values[0]; + const name = values[1]; + return { email, name, app_roles: [], preferredUsername: '', status: '', id: '' } as User; + }); + + return array; +}; diff --git a/src/modules/users/components/index.ts b/src/modules/users/components/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..b8c3b1abdcb63e5dffe1ed477b643f9e595adfe1 --- /dev/null +++ b/src/modules/users/components/index.ts @@ -0,0 +1 @@ +export { MultipleUsersModal } from './MultipleUsersModal';