From f034706bbbb27f4de3997cba3e7b9ab90cfa52b8 Mon Sep 17 00:00:00 2001 From: Valentino Kozinec Date: Fri, 11 Feb 2022 12:45:22 +0100 Subject: [PATCH] Loaders and delete user confirmation --- .../ConfirmationModal/ConfirmationModal.tsx | 5 +- src/components/Table/Table.tsx | 71 ++++-- src/modules/login/LoginCallback.tsx | 38 ++- src/modules/users/Users.tsx | 23 +- .../users/components/UserModal/UserModal.tsx | 219 ++++++++++-------- src/services/users/hooks/use-users.ts | 4 +- src/services/users/redux/actions.ts | 24 +- src/services/users/redux/reducers.ts | 6 + src/services/users/redux/selectors.ts | 1 + src/services/users/redux/types.ts | 1 + 10 files changed, 240 insertions(+), 152 deletions(-) diff --git a/src/components/Modal/ConfirmationModal/ConfirmationModal.tsx b/src/components/Modal/ConfirmationModal/ConfirmationModal.tsx index 7e58650..d6366a4 100644 --- a/src/components/Modal/ConfirmationModal/ConfirmationModal.tsx +++ b/src/components/Modal/ConfirmationModal/ConfirmationModal.tsx @@ -7,9 +7,10 @@ type ConfirmationModalProps = { onClose: () => void; title: string; body: string; + onDeleteAction?: () => void; }; -export const ConfirmationModal = ({ open, onClose, title, body }: ConfirmationModalProps) => { +export const ConfirmationModal = ({ open, onClose, title, body, onDeleteAction }: ConfirmationModalProps) => { const cancelButtonRef = useRef(null); return ( @@ -67,7 +68,7 @@ export const ConfirmationModal = ({ open, onClose, title, body }: ConfirmationMo diff --git a/src/components/Table/Table.tsx b/src/components/Table/Table.tsx index 6057900..09eb629 100644 --- a/src/components/Table/Table.tsx +++ b/src/components/Table/Table.tsx @@ -9,6 +9,7 @@ export interface ReactTableProps> { pagination?: boolean; getSelectedRowIds?(rows: Record, boolean>): void; selectable?: boolean; + loading?: boolean; } const IndeterminateCheckbox = React.forwardRef(({ indeterminate, ...rest }: any, ref) => { @@ -38,6 +39,7 @@ export const Table = >({ onRowClick, getSelectedRowIds, selectable = false, + loading = false, }: ReactTableProps) => { const { getTableProps, @@ -121,29 +123,52 @@ export const Table = >({ ))} - {rows.map((row: any, rowIndex) => { - prepareRow(row); - return ( - onRowClick(row.original as T) : () => {}} - > - {row.cells.map((cell: any) => { - return ( - - {cell.render('Cell')} - - ); - })} - - ); - })} + {!loading ? ( + rows.map((row: any, rowIndex) => { + prepareRow(row); + return ( + onRowClick(row.original as T) : () => {}} + > + {row.cells.map((cell: any) => { + return ( + + {cell.render('Cell')} + + ); + })} + + ); + }) + ) : ( + +
+
+ + + + +
+

Loading users

+
+ + )} diff --git a/src/modules/login/LoginCallback.tsx b/src/modules/login/LoginCallback.tsx index 4722a2e..aa3d992 100644 --- a/src/modules/login/LoginCallback.tsx +++ b/src/modules/login/LoginCallback.tsx @@ -1,4 +1,6 @@ import React, { useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { showToast, ToastType } from 'src/common/util/show-toast'; import { useAuth } from 'src/services/auth'; // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -7,19 +9,49 @@ export function LoginCallback() { const indexOfQuestionMark = currentURL.indexOf('?'); const params = currentURL.slice(indexOfQuestionMark); + const navigate = useNavigate(); + const { logIn } = useAuth(); useEffect(() => { - if (params.length > 2) { - logIn(params); + async function logInUser() { + if (params.length > 2) { + const res = await logIn(params); + + // @ts-ignore + if (!res.ok) { + navigate('/login'); + showToast('Something went wrong, please try logging in again.', ToastType.Error); + } + } } + + logInUser(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [params]); return (
-
Loading . . .
+
+
+ + + + +
+

Logging You in, just a moment.

+
); diff --git a/src/modules/users/Users.tsx b/src/modules/users/Users.tsx index 3b061b2..899065a 100644 --- a/src/modules/users/Users.tsx +++ b/src/modules/users/Users.tsx @@ -4,17 +4,15 @@ 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 { ConfirmationModal } from 'src/components/Modal'; import { debounce } from 'lodash'; import { UserModal } from './components/UserModal'; export const Users: React.FC = () => { const [selectedRowsIds, setSelectedRowsIds] = useState({}); - const [deleteModal, setDeleteModal] = useState(false); const [configureModal, setConfigureModal] = useState(false); const [userId, setUserId] = useState(null); const [search, setSearch] = useState(''); - const { users, loadUsers } = useUsers(); + const { users, loadUsers, userTableLoading } = useUsers(); const handleSearch = (event: any) => { setSearch(event.target.value); @@ -34,9 +32,6 @@ export const Users: React.FC = () => { return users.filter((item: any) => item.email?.toLowerCase().includes(search.toLowerCase())); }, [search, users]); - const deleteModalOpen = () => setDeleteModal(true); - const deleteModalClose = () => setDeleteModal(false); - const configureModalOpen = (id: any) => { setUserId(id); setConfigureModal(true); @@ -132,7 +127,7 @@ export const Users: React.FC = () => { {selectedRowsIds && Object.keys(selectedRowsIds).length !== 0 && (