import React, { useEffect, useState } from 'react'; import _ from 'lodash'; import { TrashIcon } from '@heroicons/react/outline'; import { useFieldArray, useForm } from 'react-hook-form'; import { Modal, ConfirmationModal } from 'src/components'; import { Input, Select } from 'src/components/Form'; import { User, UserRole, useUsers } from 'src/services/users'; import { useAuth } from 'src/services/auth'; import { appAccessList, initialUserForm } from './consts'; import { UserModalProps } from './types'; export const UserModal = ({ open, onClose, userId, setUserId }: UserModalProps) => { const [deleteModal, setDeleteModal] = useState(false); const { user, loadUser, editUserById, createNewUser, userModalLoading, deleteUserById, clearSelectedUser } = useUsers(); const { currentUser, isAdmin } = useAuth(); const { control, reset, handleSubmit } = useForm<User>({ defaultValues: initialUserForm, }); const { fields } = useFieldArray({ control, name: 'app_roles', }); useEffect(() => { if (userId) { loadUser(userId); } reset(initialUserForm); // eslint-disable-next-line react-hooks/exhaustive-deps }, [userId, open]); useEffect(() => { if (!_.isEmpty(user)) { reset(user); } return () => { reset(initialUserForm); }; }, [user, reset, open]); const handleSave = async () => { try { if (userId) { await handleSubmit((data) => editUserById(data))(); } else { await handleSubmit((data) => createNewUser(data))(); } } catch (e: any) { // Continue } onClose(); clearSelectedUser(); setUserId(null); }; const handleKeyPress = (e: any) => { if (e.key === 'Enter' || e.key === 'NumpadEnter') { handleSave(); } }; const handleClose = () => { onClose(); clearSelectedUser(); setUserId(null); }; const deleteModalOpen = () => setDeleteModal(true); const deleteModalClose = () => setDeleteModal(false); const handleDelete = () => { if (userId) { deleteUserById(userId); } clearSelectedUser(); setUserId(null); handleClose(); deleteModalClose(); }; 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">{userId ? 'Edit user' : 'Add new user'}</h3> </div> <div className="mt-6 grid grid-cols-1 gap-y-6 gap-x-4 sm:grid-cols-6"> <div className="sm:col-span-3"> <Input control={control} name="name" label="Name" onKeyPress={handleKeyPress} required={false} /> </div> <div className="sm:col-span-3"> <Input control={control} name="email" label="Email" type="email" onKeyPress={handleKeyPress} required /> </div> {isAdmin && ( <> <div className="sm:col-span-3"> {fields .filter((field) => field.name === 'dashboard') .map((item, index) => ( <Select key={item.name} control={control} name={`app_roles.${index}.role`} label="Role" options={[ { value: UserRole.User, name: 'User' }, { value: UserRole.Admin, name: 'Admin' }, ]} /> ))} </div> <div className="sm:col-span-3 opacity-40 cursor-default pointer-events-none select-none"> <label htmlFor="status" className="block text-sm font-medium text-gray-700"> Status </label> <div className="mt-1"> <select id="status" name="status" className="shadow-sm focus:ring-primary-500 focus:border-primary-500 block w-full sm:text-sm border-gray-300 rounded-md" > <option>Active</option> <option>Inactive</option> <option>Banned</option> </select> </div> </div> </> )} </div> </div> {isAdmin && ( <div> <div className="mt-8"> <h3 className="text-lg leading-6 font-medium text-gray-900">App Access</h3> </div> <div> <div className="flow-root mt-6"> <ul className="-my-5 divide-y divide-gray-200 "> {fields.map((item, index) => { if (item.name === 'dashboard') { return null; } return ( <li className="py-4" key={item.name}> <div className="flex items-center space-x-4"> <div className="flex-shrink-0 flex-1 flex items-center"> <img className="h-10 w-10 rounded-md overflow-hidden" src={_.find(appAccessList, ['name', item.name!])?.image} alt={item.name ?? 'Image'} /> <h3 className="ml-4 text-md leading-6 font-medium text-gray-900"> {_.find(appAccessList, ['name', item.name!])?.label} </h3> </div> <div> <Select key={item.id} control={control} name={`app_roles.${index}.role`} options={[ { value: UserRole.NoAccess, name: 'No Access' }, { value: UserRole.User, name: 'User' }, { value: UserRole.Admin, name: 'Admin' }, ]} /> </div> </div> </li> ); })} </ul> </div> </div> </div> )} </div> </div> </Modal> <ConfirmationModal onDeleteAction={handleDelete} open={deleteModal} onClose={deleteModalClose} title="Delete user" body="Are you sure you want to delete this user? All of the user data will be permanently removed. This action cannot be undone." /> </> ); };