From 0d9e3bc29ff0d49f26557c96dfb08a90f1d03ff5 Mon Sep 17 00:00:00 2001 From: Ifycode Date: Thu, 7 Apr 2022 21:59:23 +0100 Subject: [PATCH 01/12] Add comment to begin fixing --- src/hooks/useAuth.tsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/hooks/useAuth.tsx b/src/hooks/useAuth.tsx index 14f199d..c811c3d 100644 --- a/src/hooks/useAuth.tsx +++ b/src/hooks/useAuth.tsx @@ -1,4 +1,4 @@ -import { ChangeEvent, useState } from "react"; +import { ChangeEvent, useEffect, useState } from "react"; import { Location, NavigateFunction, useLocation, useNavigate } from "react-router-dom"; import { createContainer } from "unstated-next"; import { AuthForm, AuthFormContent, User } from "../interfaces/auth"; @@ -36,6 +36,21 @@ export const useAuth = () => { const [user, setUser] = useState(initialUser); const [form, setForm] = useState(initialForm); + // useEffect(() => { // Suggestions from Silas + // // Set isloading to true + + // // read token from local storage + // // if token exists, + // // read user data from local storage + // // set the user variable + // // set isAuthenticated to true + + // // if token doesn't exist, + // // set isAuthenticated to false + + // // set isLoading to false + // }, []); + const authenticateUser = async (e: any, apiEndpoint: string, destinationPage: string) => { e.preventDefault(); const response = await fetch(`${process.env.REACT_APP_BASE_URL}/${apiEndpoint}`, { From 50d9a08bd99593b7b35d7082612a10d89b458c8f Mon Sep 17 00:00:00 2001 From: Ifycode Date: Thu, 7 Apr 2022 22:02:38 +0100 Subject: [PATCH 02/12] Change localstorage items name for easy debugging --- src/hooks/useAuth.tsx | 12 ++++++------ src/pages/Books.tsx | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hooks/useAuth.tsx b/src/hooks/useAuth.tsx index c811c3d..4c19047 100644 --- a/src/hooks/useAuth.tsx +++ b/src/hooks/useAuth.tsx @@ -63,9 +63,9 @@ export const useAuth = () => { const data = await response.json(); if (data.user) { if (pageRoute === '/login') { - localStorage.setItem('accessToken', data.accessToken); - localStorage.setItem('_user', JSON.stringify(data.user)); - setUser(JSON.parse(localStorage.getItem('_user') as string)); + localStorage.setItem('buuks_accessToken', data.accessToken); + localStorage.setItem('buuks_user', JSON.stringify(data.user)); + setUser(JSON.parse(localStorage.getItem('buuks_user') as string)); setIsAuthenticated(true); } navigate(destinationPage); @@ -92,15 +92,15 @@ export const useAuth = () => { const handleLogIn = () => { setIsAuthenticated(true); - localStorage.getItem('accessToken'); + localStorage.getItem('buuks_accessToken'); } const handleLogout = () => { setIsAuthenticated(false); setUnAuthorizedError(false); navigate('/login'); - localStorage.removeItem('accessToken'); - localStorage.removeItem('_user'); + localStorage.removeItem('buuks_accessToken'); + localStorage.removeItem('buuks_user'); setUser(initialUser); } diff --git a/src/pages/Books.tsx b/src/pages/Books.tsx index cd102ae..a9f7fac 100644 --- a/src/pages/Books.tsx +++ b/src/pages/Books.tsx @@ -12,7 +12,7 @@ const Books = (): ReactElement => { const hook = useBooks(); useEffect(() => { let abortController = new AbortController(); - const user = JSON.parse(localStorage.getItem('_user') as string); + const user = JSON.parse(localStorage.getItem('buuks_user') as string); auth.setUser(user); hook.fetchBookData(null, 'GET', `books/user/${user._id}`, null); auth.handleLogIn(); From 4b7b93a85d8f21d7cb2b39ca392cafe616215bfb Mon Sep 17 00:00:00 2001 From: Ifycode Date: Fri, 8 Apr 2022 17:45:05 +0100 Subject: [PATCH 03/12] Work in progress - Fix for error on /books reload --- src/hooks/useAuth.tsx | 25 +++- src/hooks/useBooks.tsx | 252 ++++++++++++++++++++++++++++++++++++----- src/lib/books.tsx | 4 +- src/pages/Books.tsx | 20 +--- 4 files changed, 252 insertions(+), 49 deletions(-) diff --git a/src/hooks/useAuth.tsx b/src/hooks/useAuth.tsx index 4c19047..243398f 100644 --- a/src/hooks/useAuth.tsx +++ b/src/hooks/useAuth.tsx @@ -3,6 +3,7 @@ import { Location, NavigateFunction, useLocation, useNavigate } from "react-rout import { createContainer } from "unstated-next"; import { AuthForm, AuthFormContent, User } from "../interfaces/auth"; import { formBody } from "../lib/auth"; +import { useBooks } from "./useBooks"; export const useAuth = () => { const navigate: NavigateFunction = useNavigate(); @@ -35,6 +36,7 @@ export const useAuth = () => { const [authFormContent, setAuthFormContent] = useState(initialAuthFormContent); const [user, setUser] = useState(initialUser); const [form, setForm] = useState(initialForm); + const usebooksHook = useBooks({ user, isAuthenticated }); // useEffect(() => { // Suggestions from Silas // // Set isloading to true @@ -51,6 +53,17 @@ export const useAuth = () => { // // set isLoading to false // }, []); + useEffect(() => { + setIsLoading(true); + const token = localStorage.getItem('buuks_accessToken'); + if (token) { + handleLogIn(); + } else { + handleLogout(); + } + setIsLoading(false); + }, []); + const authenticateUser = async (e: any, apiEndpoint: string, destinationPage: string) => { e.preventDefault(); const response = await fetch(`${process.env.REACT_APP_BASE_URL}/${apiEndpoint}`, { @@ -65,8 +78,8 @@ export const useAuth = () => { if (pageRoute === '/login') { localStorage.setItem('buuks_accessToken', data.accessToken); localStorage.setItem('buuks_user', JSON.stringify(data.user)); - setUser(JSON.parse(localStorage.getItem('buuks_user') as string)); - setIsAuthenticated(true); + handleLogIn(); + usebooksHook.getBooks(); } navigate(destinationPage); resetForm(initialForm); @@ -91,9 +104,13 @@ export const useAuth = () => { } const handleLogIn = () => { + const userLocal = localStorage.getItem('buuks_user'); + setUser(JSON.parse(userLocal as string)); setIsAuthenticated(true); - localStorage.getItem('buuks_accessToken'); - } + console.log(user); + // console.log(isAuthenticated); + usebooksHook.fetchBookData(null, 'GET', `books/user/${user._id}`, null); + } // don't forget to cahange the hard coded user._id const handleLogout = () => { setIsAuthenticated(false); diff --git a/src/hooks/useBooks.tsx b/src/hooks/useBooks.tsx index cd00b8e..8001cc9 100644 --- a/src/hooks/useBooks.tsx +++ b/src/hooks/useBooks.tsx @@ -1,10 +1,10 @@ -import { ChangeEvent, useState } from "react"; +import { ChangeEvent, useEffect, useState } from "react"; import { fetchOptions } from "../lib/books"; import { BooksObject, ModalForm, PostForm } from "../interfaces/books"; -import { AuthContainer } from "./useAuth"; +// import { AuthContainer } from "./useAuth"; -export const useBooks = (): Record => { - const auth = AuthContainer.useContainer(); +export const useBooks = ({ user, isAuthenticated }: { user: any, isAuthenticated: boolean }): Record => { + // const auth = AuthContainer.useContainer(); let [books, setBooks] = useState([]); const [modal, setModal] = useState(false); const [success, setSuccess] = useState(false); @@ -34,16 +34,23 @@ export const useBooks = (): Record => { const [form, setForm] = useState(initialForm); const [modalForm, setModalForm] = useState(initialModalform); + useEffect(() => { + if (isAuthenticated) getBooks(); + }, [isAuthenticated]); + + const getBooks = () => fetchBookData(null, 'GET', `books/user/${user._id}`, null); + const fetchBookData = async (e: any, method: string, apiEndpoint: string, bookId: string | null) => { if (method === 'POST' || method === 'PUT') e.preventDefault(); - if (method === 'GET' && !auth.isLoading) setBooksLoading(false); - if (method !== 'GET' && !auth.isLoading) setBooksLoading(null); - trackProgress(true, false, ''); + // if (method === 'GET' && !auth.isLoading) setBooksLoading(false); + // if (method !== 'GET' && !auth.isLoading) setBooksLoading(null); + // trackProgress(true, false, ''); let response: Response; response = await fetch(`${process.env.REACT_APP_BASE_URL}/${apiEndpoint}`, fetchOptions(method, form)); const data = await response.json(); + console.log(apiEndpoint); if (response.ok) { - trackProgress(false, false, ''); + // trackProgress(false, false, ''); if (method === 'GET') setBooks(data.books); if (method === 'DELETE') setBooks(books.filter(book => book._id !== bookId)); if (method === 'POST') { @@ -69,22 +76,22 @@ export const useBooks = (): Record => { resetForm(); } if (response.status === 400) { - if (method === 'POST') trackProgress(false, true, 'All fields are required. Also, only PDF files are allowed.'); - if (method === 'PUT') trackProgress(false, true, 'Only PDF files are allowed.'); - if (method === 'POST' && data[0].code === 'too_small') trackProgress(false, true, `${data[0].message}. All fields are required. Also, only PDF files are allowed.`); + // if (method === 'POST') trackProgress(false, true, 'All fields are required. Also, only PDF files are allowed.'); + // if (method === 'PUT') trackProgress(false, true, 'Only PDF files are allowed.'); + // if (method === 'POST' && data[0].code === 'too_small') trackProgress(false, true, `${data[0].message}. All fields are required. Also, only PDF files are allowed.`); } if (response.status === 401) { - trackProgress(false, true, 'Your session has expired, please login again'); - auth.setUnAuthorizedError(true); - const removeError = () => auth.setUnAuthorizedError(false); - const interval = setInterval(removeError, 200); - const removeInterval = () => { - auth.handleLogout(); - clearInterval(interval); - } - setTimeout(removeInterval, 200); + // trackProgress(false, true, 'Your session has expired, please login again'); + // auth.setUnAuthorizedError(true); + // const removeError = () => auth.setUnAuthorizedError(false); + // const interval = setInterval(removeError, 200); + // const removeInterval = () => { + // auth.handleLogout(); + // clearInterval(interval); + // } + // setTimeout(removeInterval, 200); } - // console.log('data: ', data); + console.log('data: ', data); } const handleInputChange = (e: ChangeEvent, checkboxString: string) => { // checkboxString: string | null @@ -98,19 +105,19 @@ export const useBooks = (): Record => { setModalForm({ ...modalForm, [checkboxString]: false }); } } - trackProgress(false, false, ''); + // trackProgress(false, false, ''); } - const trackProgress = (loading: boolean, errBool: boolean, errString: string) => { - auth.setIsLoading(loading); - auth.handleError(errBool, errString); - } + // const trackProgress = (loading: boolean, errBool: boolean, errString: string) => { + // auth.setIsLoading(loading); + // auth.handleError(errBool, errString); + // } const handleModal = (boolean: boolean) => { setModal(boolean); if (!boolean) { setModalForm(initialModalform); - auth.handleError(false, ''); + // auth.handleError(false, ''); resetForm(); } } @@ -171,6 +178,7 @@ export const useBooks = (): Record => { form, handleModal, fetchBookData, + getBooks, handleInputChange, handlePostRequestForm, modalForm, @@ -178,4 +186,192 @@ export const useBooks = (): Record => { success, successMessage } -} \ No newline at end of file +} + + + + + + + +// import { ChangeEvent, useState } from "react"; +// import { fetchOptions } from "../lib/books"; +// import { BooksObject, ModalForm, PostForm } from "../interfaces/books"; +// import { AuthContainer } from "./useAuth"; + +// export const useBooks = (): Record => { +// const auth = AuthContainer.useContainer(); +// let [books, setBooks] = useState([]); +// const [modal, setModal] = useState(false); +// const [success, setSuccess] = useState(false); +// const [successMessage, setSuccessMessage] = useState(''); +// const [booksLoading, setBooksLoading] = useState(null); +// const initialForm = { +// title: '', +// description: '', +// pdf: '' +// }; +// const initialModalform = { +// persistInstruction: false, +// persistFormBody: false, +// persistTitle: false, +// persistDescription: false, +// persistFile: false, +// title: '', +// buttonText: '', +// placeholderText: { +// title: '', +// description: '' +// }, +// method: '', +// apiEndpoint: '', +// bookId: '' +// } +// const [form, setForm] = useState(initialForm); +// const [modalForm, setModalForm] = useState(initialModalform); + +// const fetchBookData = async (e: any, method: string, apiEndpoint: string, bookId: string | null) => { +// if (method === 'POST' || method === 'PUT') e.preventDefault(); +// if (method === 'GET' && !auth.isLoading) setBooksLoading(false); +// if (method !== 'GET' && !auth.isLoading) setBooksLoading(null); +// trackProgress(true, false, ''); +// let response: Response; +// response = await fetch(`${process.env.REACT_APP_BASE_URL}/${apiEndpoint}`, fetchOptions(method, form)); +// const data = await response.json(); +// if (response.ok) { +// trackProgress(false, false, ''); +// if (method === 'GET') setBooks(data.books); +// if (method === 'DELETE') setBooks(books.filter(book => book._id !== bookId)); +// if (method === 'POST') { +// books.unshift(data.book); +// handleModal(false); +// } +// if (method === 'PUT') { +// const updated = books.map((book) => { +// if (book._id === bookId) return { ...book, ...data.book }; +// return book; +// }); +// setBooks(updated); +// handleModal(false); +// } +// if (method !== 'GET') { +// setSuccessMessage(data.message) +// setSuccess(true); +// const removeSuccessMsg = () => setSuccess(false); +// const interval = setInterval(removeSuccessMsg, 2000); +// const removeInterval = () => clearInterval(interval); +// setTimeout(removeInterval, 2000); +// } +// resetForm(); +// } +// if (response.status === 400) { +// if (method === 'POST') trackProgress(false, true, 'All fields are required. Also, only PDF files are allowed.'); +// if (method === 'PUT') trackProgress(false, true, 'Only PDF files are allowed.'); +// if (method === 'POST' && data[0].code === 'too_small') trackProgress(false, true, `${data[0].message}. All fields are required. Also, only PDF files are allowed.`); +// } +// if (response.status === 401) { +// trackProgress(false, true, 'Your session has expired, please login again'); +// auth.setUnAuthorizedError(true); +// const removeError = () => auth.setUnAuthorizedError(false); +// const interval = setInterval(removeError, 200); +// const removeInterval = () => { +// auth.handleLogout(); +// clearInterval(interval); +// } +// setTimeout(removeInterval, 200); +// } +// // console.log('data: ', data); +// } + +// const handleInputChange = (e: ChangeEvent, checkboxString: string) => { // checkboxString: string | null +// const { name, value, files, checked } = e.target; +// if (name === 'title' || name === 'description') setForm({ ...form, [name]: value } as Pick); +// if (name === 'pdf') setForm({ ...form, [name]: files![0] } as Pick); +// if (name === 'checkbox') { +// if (checked) { +// setModalForm({ ...modalForm, [checkboxString]: true }); +// } else { +// setModalForm({ ...modalForm, [checkboxString]: false }); +// } +// } +// trackProgress(false, false, ''); +// } + +// const trackProgress = (loading: boolean, errBool: boolean, errString: string) => { +// auth.setIsLoading(loading); +// auth.handleError(errBool, errString); +// } + +// const handleModal = (boolean: boolean) => { +// setModal(boolean); +// if (!boolean) { +// setModalForm(initialModalform); +// auth.handleError(false, ''); +// resetForm(); +// } +// } + +// const handlePostRequestForm = (boolean: boolean, operation: string, bookId: string | null) => { +// handleModal(boolean); +// if (operation === 'add') { +// setModalForm({ +// persistInstruction: false, +// persistFormBody: true, +// persistTitle: true, +// persistDescription: true, +// persistFile: true, +// title: 'New Book - Form', +// buttonText: 'Submit new book', +// placeholderText: { +// title: 'New book title', +// description: 'New book description' +// }, +// method: 'POST', +// apiEndpoint: 'books', +// bookId: bookId +// }); +// } +// if (operation === 'update') { +// setModalForm({ +// persistInstruction: true, +// persistFormBody: true, +// persistTitle: false, +// persistDescription: false, +// persistFile: false, +// title: 'Update Book - Form', +// buttonText: 'Update book', +// placeholderText: { +// title: 'Update book title', +// description: 'Update book description' +// }, +// method: 'PUT', +// apiEndpoint: `books/${bookId}`, +// bookId: bookId +// }); +// const cardInfo = books.filter((book) => book._id === bookId)[0]; +// setForm({ +// title: cardInfo.title, +// description: cardInfo.description, +// pdf: '' +// }) +// } +// } + +// const resetForm = () => { +// setForm(initialForm); +// } + +// return { +// books, +// modal, +// form, +// handleModal, +// fetchBookData, +// handleInputChange, +// handlePostRequestForm, +// modalForm, +// booksLoading, +// success, +// successMessage +// } +// } \ No newline at end of file diff --git a/src/lib/books.tsx b/src/lib/books.tsx index 7333c55..950bc63 100644 --- a/src/lib/books.tsx +++ b/src/lib/books.tsx @@ -5,8 +5,8 @@ export const fetchOptions = (method: string, form: PostForm) => { options = { method: method, headers: { - 'Authorization': `Bearer ${localStorage.accessToken}`, - 'x-access-token': `${localStorage.accessToken}` + 'Authorization': `Bearer ${localStorage.buuks_accessToken}`, + 'x-access-token': `${localStorage.buuks_accessToken}` } } if (method === 'POST') { diff --git a/src/pages/Books.tsx b/src/pages/Books.tsx index a9f7fac..aa1bedc 100644 --- a/src/pages/Books.tsx +++ b/src/pages/Books.tsx @@ -1,4 +1,4 @@ -import { ReactElement, useEffect } from "react"; +import { ReactElement } from "react"; import Modal from "../components/Modal"; import { useBooks } from "../hooks/useBooks"; import { AuthContainer } from "../hooks/useAuth"; @@ -8,26 +8,16 @@ import BooksBody from "../components/BooksBody"; import BookForm from "../components/forms/BookForm"; const Books = (): ReactElement => { - const auth = AuthContainer.useContainer(); - const hook = useBooks(); - useEffect(() => { - let abortController = new AbortController(); - const user = JSON.parse(localStorage.getItem('buuks_user') as string); - auth.setUser(user); - hook.fetchBookData(null, 'GET', `books/user/${user._id}`, null); - auth.handleLogIn(); - return () => { - abortController.abort(); - } - }, []); + const { user, isAuthenticated, handleLogout } = AuthContainer.useContainer(); + const hook = useBooks({ user, isAuthenticated }); return (
-

{auth.user.name}

+

{user.name}

)} - + diff --git a/src/components/ui/Skeleton.tsx b/src/components/ui/Skeleton.tsx new file mode 100644 index 0000000..3ec418e --- /dev/null +++ b/src/components/ui/Skeleton.tsx @@ -0,0 +1,30 @@ + +const Skeleton = () => { + return ( +
+ { + [...Array(6)].map(((book: any, index: number) => { + return ( +
+
+

Skeleton title

+

Skeleton description text

+

Preview or download PDF

+
+
+
+ Skeleton +
+
+ Skeleton +
+
+
+ ) + })) + } +
+ ) +} + +export default Skeleton; \ No newline at end of file diff --git a/src/components/ui/SvgAnimatedLoader.tsx b/src/components/ui/SvgAnimatedLoader.tsx new file mode 100644 index 0000000..f3f4d2c --- /dev/null +++ b/src/components/ui/SvgAnimatedLoader.tsx @@ -0,0 +1,62 @@ +import { ReactElement } from "react"; + +const SvgAnimatedLoader = (): ReactElement => { + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {/* */} + +
+ ); +} + +export default SvgAnimatedLoader; \ No newline at end of file diff --git a/src/hooks/useAuth.tsx b/src/hooks/useAuth.tsx index dde94de..31a0ac8 100644 --- a/src/hooks/useAuth.tsx +++ b/src/hooks/useAuth.tsx @@ -9,7 +9,7 @@ export const useAuth = () => { const location: Location = useLocation(); const pageRoute: string = location.pathname; const [isAuthenticated, setIsAuthenticated] = useState(false); - const [isLoading, setIsLoading] = useState(false); + const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(false); const [errorMessage, setErrorMessage] = useState(''); const [unAuthorizedError, setUnAuthorizedError] = useState(false); @@ -52,14 +52,14 @@ export const useAuth = () => { // }, []); useEffect(() => { - setIsLoading(true); + // setIsLoading(true); const token = localStorage.getItem('buuks_accessToken'); if (token) { handleLogIn(); } else { handleLogout(); } - setIsLoading(false); + // setIsLoading(false); }, []); const authenticateUser = async (e: any, apiEndpoint: string, destinationPage: string) => { diff --git a/src/hooks/useBooks.tsx b/src/hooks/useBooks.tsx index f2339be..4c7f389 100644 --- a/src/hooks/useBooks.tsx +++ b/src/hooks/useBooks.tsx @@ -1,14 +1,15 @@ -import { ChangeEvent, useEffect, useState } from "react"; +import { ChangeEvent, Dispatch, SetStateAction, useEffect, useState } from "react"; import { fetchOptions } from "../lib/books"; import { BooksObject, ModalForm, PostForm } from "../interfaces/books"; // import { AuthContainer } from "./useAuth"; export const useBooks = ( - { user, isAuthenticated, handleLogout }: + { user, isAuthenticated, handleLogout, setIsLoading }: { user: any, isAuthenticated: boolean, - handleLogout: () => void + handleLogout: () => void, + setIsLoading: Dispatch> }) => { // const auth = AuthContainer.useContainer(); let [books, setBooks] = useState([]); @@ -41,8 +42,10 @@ export const useBooks = ( const [modalForm, setModalForm] = useState(initialModalform); useEffect(() => { + // setIsLoading(true); if (isAuthenticated) getBooks(); - }, [isAuthenticated]); + // setIsLoading(false); + }, [isAuthenticated, setIsLoading]); const getBooks = () => fetchBookData(null, 'GET', `books/user/${user._id}`, null); diff --git a/src/hooks/useLoader.tsx b/src/hooks/useLoader.tsx new file mode 100644 index 0000000..053a555 --- /dev/null +++ b/src/hooks/useLoader.tsx @@ -0,0 +1,25 @@ +import { useEffect, useState } from "react" + +export const useLoader = ({ fixed }: { fixed: boolean }) => { + const [loader, setLoader] = useState({ + text: '', + style: '' + }); + useEffect(() => { + if (fixed) { + setLoader({ + text: 'Loading...', + style: 'fixed bottom-6 right-6 py-2 px-3 md:text-lg md:px-4 rounded border border-pink-800' + }); + } else { + setLoader({ + text: 'Fetching all books...', + style: 'mt-4' + }); + } + }, [fixed]); + + return { + loader + } +} \ No newline at end of file diff --git a/src/pages/Books.tsx b/src/pages/Books.tsx index f6ceab5..10c5ec8 100644 --- a/src/pages/Books.tsx +++ b/src/pages/Books.tsx @@ -6,10 +6,11 @@ import Loader from "../components/Loader"; import Toastr from "../components/Toastr"; import BooksBody from "../components/BooksBody"; import BookForm from "../components/forms/BookForm"; +import Skeleton from "../components/ui/Skeleton"; const Books = (): ReactElement => { - const { user, isAuthenticated, handleLogout } = AuthContainer.useContainer(); - const hook = useBooks({ user, isAuthenticated, handleLogout }); + const { user, isAuthenticated, handleLogout, setIsLoading } = AuthContainer.useContainer(); + const hook = useBooks({ user, isAuthenticated, handleLogout, setIsLoading }); return (
@@ -30,7 +31,8 @@ const Books = (): ReactElement => { > - + + Date: Sat, 9 Apr 2022 03:44:20 +0100 Subject: [PATCH 07/12] Add loader to login and signup form --- src/components/Loader.tsx | 2 +- src/components/forms/AuthForm.tsx | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/Loader.tsx b/src/components/Loader.tsx index 72c4720..a75d003 100644 --- a/src/components/Loader.tsx +++ b/src/components/Loader.tsx @@ -8,7 +8,7 @@ const Loader = ({ fixed }: { fixed: boolean }): ReactElement | null => { const { loader } = useLoader({ fixed }); if (!isLoading) return null; return ( -
+
{loader.text}
diff --git a/src/components/forms/AuthForm.tsx b/src/components/forms/AuthForm.tsx index a524702..6c4c6f8 100644 --- a/src/components/forms/AuthForm.tsx +++ b/src/components/forms/AuthForm.tsx @@ -2,6 +2,7 @@ import { Fragment, ReactElement, useEffect } from "react"; import { AuthContainer } from "../../hooks/useAuth"; import AppLink from "../AppLink"; import Error from "../Error"; +import Loader from "../Loader"; const AuthForm = (): ReactElement => { const auth = AuthContainer.useContainer(); @@ -64,6 +65,7 @@ const AuthForm = (): ReactElement => { text={auth.authFormContent.LinkText} />
+ From d9b0b390edf1dc5c2764ea140fb29d13a087db42 Mon Sep 17 00:00:00 2001 From: Ifycode Date: Sat, 9 Apr 2022 04:52:25 +0100 Subject: [PATCH 08/12] Configure isLoading to work depending on isFetching state --- src/hooks/useAuth.tsx | 17 ++++++++--------- src/hooks/useBooks.tsx | 7 +++++-- src/pages/Books.tsx | 4 ++-- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/hooks/useAuth.tsx b/src/hooks/useAuth.tsx index 31a0ac8..f963833 100644 --- a/src/hooks/useAuth.tsx +++ b/src/hooks/useAuth.tsx @@ -9,7 +9,8 @@ export const useAuth = () => { const location: Location = useLocation(); const pageRoute: string = location.pathname; const [isAuthenticated, setIsAuthenticated] = useState(false); - const [isLoading, setIsLoading] = useState(true); + const [isLoading, setIsLoading] = useState(false); + const [isFetching, setIsFetching] = useState(false); const [error, setError] = useState(false); const [errorMessage, setErrorMessage] = useState(''); const [unAuthorizedError, setUnAuthorizedError] = useState(false); @@ -52,18 +53,14 @@ export const useAuth = () => { // }, []); useEffect(() => { - // setIsLoading(true); const token = localStorage.getItem('buuks_accessToken'); - if (token) { - handleLogIn(); - } else { - handleLogout(); - } - // setIsLoading(false); - }, []); + token ? handleLogIn() : handleLogout(); + isFetching ? setIsLoading(true) : setIsLoading(false); + }, [isFetching]); const authenticateUser = async (e: any, apiEndpoint: string, destinationPage: string) => { e.preventDefault(); + setIsFetching(true); const response = await fetch(`${process.env.REACT_APP_BASE_URL}/${apiEndpoint}`, { method: 'POST', headers: { @@ -91,6 +88,7 @@ export const useAuth = () => { if (response.status === 401) { handleError(true, data.error.message); } + setIsFetching(false); // console.log(data) } @@ -172,6 +170,7 @@ export const useAuth = () => { error, errorMessage, setIsLoading, + setIsFetching, handleError, unAuthorizedError, setUnAuthorizedError, diff --git a/src/hooks/useBooks.tsx b/src/hooks/useBooks.tsx index 4c7f389..0c8decc 100644 --- a/src/hooks/useBooks.tsx +++ b/src/hooks/useBooks.tsx @@ -4,12 +4,13 @@ import { BooksObject, ModalForm, PostForm } from "../interfaces/books"; // import { AuthContainer } from "./useAuth"; export const useBooks = ( - { user, isAuthenticated, handleLogout, setIsLoading }: + { user, isAuthenticated, handleLogout, setIsLoading, setIsFetching }: { user: any, isAuthenticated: boolean, handleLogout: () => void, - setIsLoading: Dispatch> + setIsLoading: Dispatch>, + setIsFetching: Dispatch> }) => { // const auth = AuthContainer.useContainer(); let [books, setBooks] = useState([]); @@ -51,6 +52,7 @@ export const useBooks = ( const fetchBookData = async (e: any, method: string, apiEndpoint: string, bookId: string | null) => { if (method === 'POST' || method === 'PUT') e.preventDefault(); + setIsFetching(true); // if (method === 'GET' && !auth.isLoading) setBooksLoading(false); // if (method !== 'GET' && !auth.isLoading) setBooksLoading(null); // trackProgress(true, false, ''); @@ -102,6 +104,7 @@ export const useBooks = ( // } // setTimeout(removeInterval, 200); } + setIsFetching(false); if (isAuthenticated) console.log('data: ', data); } diff --git a/src/pages/Books.tsx b/src/pages/Books.tsx index 10c5ec8..4395663 100644 --- a/src/pages/Books.tsx +++ b/src/pages/Books.tsx @@ -9,8 +9,8 @@ import BookForm from "../components/forms/BookForm"; import Skeleton from "../components/ui/Skeleton"; const Books = (): ReactElement => { - const { user, isAuthenticated, handleLogout, setIsLoading } = AuthContainer.useContainer(); - const hook = useBooks({ user, isAuthenticated, handleLogout, setIsLoading }); + const { user, isAuthenticated, handleLogout, setIsLoading, setIsFetching } = AuthContainer.useContainer(); + const hook = useBooks({ user, isAuthenticated, handleLogout, setIsLoading, setIsFetching }); return (
From 7fd148d0c7a844df7f53fac1b015218faf3c2006 Mon Sep 17 00:00:00 2001 From: Ifycode Date: Sat, 9 Apr 2022 05:02:58 +0100 Subject: [PATCH 09/12] Clean up - Remove unused --- src/hooks/useBooks.tsx | 7 ++----- src/pages/Books.tsx | 4 ++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/hooks/useBooks.tsx b/src/hooks/useBooks.tsx index 0c8decc..95a884c 100644 --- a/src/hooks/useBooks.tsx +++ b/src/hooks/useBooks.tsx @@ -4,12 +4,11 @@ import { BooksObject, ModalForm, PostForm } from "../interfaces/books"; // import { AuthContainer } from "./useAuth"; export const useBooks = ( - { user, isAuthenticated, handleLogout, setIsLoading, setIsFetching }: + { user, isAuthenticated, handleLogout, setIsFetching }: { user: any, isAuthenticated: boolean, handleLogout: () => void, - setIsLoading: Dispatch>, setIsFetching: Dispatch> }) => { // const auth = AuthContainer.useContainer(); @@ -43,10 +42,8 @@ export const useBooks = ( const [modalForm, setModalForm] = useState(initialModalform); useEffect(() => { - // setIsLoading(true); if (isAuthenticated) getBooks(); - // setIsLoading(false); - }, [isAuthenticated, setIsLoading]); + }, [isAuthenticated]); const getBooks = () => fetchBookData(null, 'GET', `books/user/${user._id}`, null); diff --git a/src/pages/Books.tsx b/src/pages/Books.tsx index 4395663..d0b138d 100644 --- a/src/pages/Books.tsx +++ b/src/pages/Books.tsx @@ -9,8 +9,8 @@ import BookForm from "../components/forms/BookForm"; import Skeleton from "../components/ui/Skeleton"; const Books = (): ReactElement => { - const { user, isAuthenticated, handleLogout, setIsLoading, setIsFetching } = AuthContainer.useContainer(); - const hook = useBooks({ user, isAuthenticated, handleLogout, setIsLoading, setIsFetching }); + const { user, isAuthenticated, handleLogout, setIsFetching } = AuthContainer.useContainer(); + const hook = useBooks({ user, isAuthenticated, handleLogout, setIsFetching }); return (
From 99410ded39a0b34d150738be2b75c62fecae5484 Mon Sep 17 00:00:00 2001 From: Ifycode Date: Sat, 9 Apr 2022 18:49:28 +0100 Subject: [PATCH 10/12] Make skeleton show up onlyy for get request only, fix loader experience --- src/components/BooksBody.tsx | 8 +----- src/components/ui/Skeleton.tsx | 52 +++++++++++++++++++--------------- src/hooks/useBooks.tsx | 6 ++-- src/hooks/useLoader.tsx | 2 +- src/pages/Books.tsx | 5 ++-- 5 files changed, 38 insertions(+), 35 deletions(-) diff --git a/src/components/BooksBody.tsx b/src/components/BooksBody.tsx index 5bff3b3..688a6a8 100644 --- a/src/components/BooksBody.tsx +++ b/src/components/BooksBody.tsx @@ -3,13 +3,7 @@ import { AuthContainer } from '../hooks/useAuth'; const BooksBody = ({ hook }: { hook: Record }): ReactElement | null => { const { isLoading } = AuthContainer.useContainer(); - // if (!hook.books.length && !auth.isLoading) { - // return ( - //
You have not added any book yet. Click on the add button to begin.
- // ); - // } - if (isLoading) return null; - // if (hook.booksLoading) return null; + if (isLoading && hook.getRequest) return null; return (
{ diff --git a/src/components/ui/Skeleton.tsx b/src/components/ui/Skeleton.tsx index 3ec418e..b06076e 100644 --- a/src/components/ui/Skeleton.tsx +++ b/src/components/ui/Skeleton.tsx @@ -1,30 +1,36 @@ +import { ReactElement } from "react"; +import { AuthContainer } from "../../hooks/useAuth"; -const Skeleton = () => { - return ( -
- { - [...Array(6)].map(((book: any, index: number) => { - return ( -
-
-

Skeleton title

-

Skeleton description text

-

Preview or download PDF

-
-
-
- Skeleton +const Skeleton = ({hook}: {hook: any}): ReactElement | null => { + const { isLoading } = AuthContainer.useContainer(); + if (isLoading && hook.getRequest) { + return ( +
+ { + [...Array(6)].map(((book: any, index: number) => { + return ( +
+
+

Skeleton title

+

Skeleton description text

+

Preview or download PDF

-
- Skeleton +
+
+ Skeleton +
+
+ Skeleton +
-
- ) - })) - } -
- ) + ) + })) + } +
+ ) + } + return null; } export default Skeleton; \ No newline at end of file diff --git a/src/hooks/useBooks.tsx b/src/hooks/useBooks.tsx index 95a884c..584f2c0 100644 --- a/src/hooks/useBooks.tsx +++ b/src/hooks/useBooks.tsx @@ -16,7 +16,7 @@ export const useBooks = ( const [modal, setModal] = useState(false); const [success, setSuccess] = useState(false); const [successMessage, setSuccessMessage] = useState(''); - const [booksLoading, setBooksLoading] = useState(null); + const [getRequest, setGetRequest] = useState(false); const initialForm = { title: '', description: '', @@ -50,6 +50,7 @@ export const useBooks = ( const fetchBookData = async (e: any, method: string, apiEndpoint: string, bookId: string | null) => { if (method === 'POST' || method === 'PUT') e.preventDefault(); setIsFetching(true); + if (method === 'GET') setGetRequest(true); // if (method === 'GET' && !auth.isLoading) setBooksLoading(false); // if (method !== 'GET' && !auth.isLoading) setBooksLoading(null); // trackProgress(true, false, ''); @@ -102,6 +103,7 @@ export const useBooks = ( // setTimeout(removeInterval, 200); } setIsFetching(false); + setGetRequest(false); if (isAuthenticated) console.log('data: ', data); } @@ -192,8 +194,8 @@ export const useBooks = ( getBooks, handleInputChange, handlePostRequestForm, + getRequest, modalForm, - booksLoading, success, successMessage } diff --git a/src/hooks/useLoader.tsx b/src/hooks/useLoader.tsx index 053a555..4f81540 100644 --- a/src/hooks/useLoader.tsx +++ b/src/hooks/useLoader.tsx @@ -13,7 +13,7 @@ export const useLoader = ({ fixed }: { fixed: boolean }) => { }); } else { setLoader({ - text: 'Fetching all books...', + text: 'Updating books count...', style: 'mt-4' }); } diff --git a/src/pages/Books.tsx b/src/pages/Books.tsx index d0b138d..7eca1c1 100644 --- a/src/pages/Books.tsx +++ b/src/pages/Books.tsx @@ -9,7 +9,7 @@ import BookForm from "../components/forms/BookForm"; import Skeleton from "../components/ui/Skeleton"; const Books = (): ReactElement => { - const { user, isAuthenticated, handleLogout, setIsFetching } = AuthContainer.useContainer(); + const { user, isAuthenticated, isLoading, handleLogout, setIsFetching } = AuthContainer.useContainer(); const hook = useBooks({ user, isAuthenticated, handleLogout, setIsFetching }); return ( @@ -32,7 +32,8 @@ const Books = (): ReactElement => { - + {!isLoading ?
Total number of books: {hook.books.length}
: null} + Date: Sat, 9 Apr 2022 23:23:33 +0100 Subject: [PATCH 11/12] make skeleton show up after login, refactor getRequest state --- src/components/BooksBody.tsx | 4 ++-- src/components/ui/Skeleton.tsx | 6 +++--- src/hooks/useAuth.tsx | 6 +++++- src/hooks/useBooks.tsx | 7 +++---- src/pages/Books.tsx | 6 +++--- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/components/BooksBody.tsx b/src/components/BooksBody.tsx index 688a6a8..ba95602 100644 --- a/src/components/BooksBody.tsx +++ b/src/components/BooksBody.tsx @@ -2,8 +2,8 @@ import { ReactElement } from 'react' import { AuthContainer } from '../hooks/useAuth'; const BooksBody = ({ hook }: { hook: Record }): ReactElement | null => { - const { isLoading } = AuthContainer.useContainer(); - if (isLoading && hook.getRequest) return null; + const { isLoading, getRequest } = AuthContainer.useContainer(); + if (isLoading && getRequest) return null; return (
{ diff --git a/src/components/ui/Skeleton.tsx b/src/components/ui/Skeleton.tsx index b06076e..4cd8557 100644 --- a/src/components/ui/Skeleton.tsx +++ b/src/components/ui/Skeleton.tsx @@ -1,9 +1,9 @@ import { ReactElement } from "react"; import { AuthContainer } from "../../hooks/useAuth"; -const Skeleton = ({hook}: {hook: any}): ReactElement | null => { - const { isLoading } = AuthContainer.useContainer(); - if (isLoading && hook.getRequest) { +const Skeleton = (): ReactElement | null => { + const { isLoading, getRequest } = AuthContainer.useContainer(); + if (isLoading && getRequest) { return (
{ diff --git a/src/hooks/useAuth.tsx b/src/hooks/useAuth.tsx index f963833..90c28a9 100644 --- a/src/hooks/useAuth.tsx +++ b/src/hooks/useAuth.tsx @@ -11,6 +11,7 @@ export const useAuth = () => { const [isAuthenticated, setIsAuthenticated] = useState(false); const [isLoading, setIsLoading] = useState(false); const [isFetching, setIsFetching] = useState(false); + const [getRequest, setGetRequest] = useState(false); const [error, setError] = useState(false); const [errorMessage, setErrorMessage] = useState(''); const [unAuthorizedError, setUnAuthorizedError] = useState(false); @@ -56,7 +57,8 @@ export const useAuth = () => { const token = localStorage.getItem('buuks_accessToken'); token ? handleLogIn() : handleLogout(); isFetching ? setIsLoading(true) : setIsLoading(false); - }, [isFetching]); + if (getRequest) setIsLoading(true); + }, [isFetching, getRequest]); const authenticateUser = async (e: any, apiEndpoint: string, destinationPage: string) => { e.preventDefault(); @@ -167,10 +169,12 @@ export const useAuth = () => { user, setUser, isLoading, + getRequest, error, errorMessage, setIsLoading, setIsFetching, + setGetRequest, handleError, unAuthorizedError, setUnAuthorizedError, diff --git a/src/hooks/useBooks.tsx b/src/hooks/useBooks.tsx index 584f2c0..5cd0a51 100644 --- a/src/hooks/useBooks.tsx +++ b/src/hooks/useBooks.tsx @@ -4,19 +4,19 @@ import { BooksObject, ModalForm, PostForm } from "../interfaces/books"; // import { AuthContainer } from "./useAuth"; export const useBooks = ( - { user, isAuthenticated, handleLogout, setIsFetching }: + { user, isAuthenticated, handleLogout, setIsFetching, setGetRequest }: { user: any, isAuthenticated: boolean, handleLogout: () => void, - setIsFetching: Dispatch> + setIsFetching: Dispatch>, + setGetRequest: Dispatch> }) => { // const auth = AuthContainer.useContainer(); let [books, setBooks] = useState([]); const [modal, setModal] = useState(false); const [success, setSuccess] = useState(false); const [successMessage, setSuccessMessage] = useState(''); - const [getRequest, setGetRequest] = useState(false); const initialForm = { title: '', description: '', @@ -194,7 +194,6 @@ export const useBooks = ( getBooks, handleInputChange, handlePostRequestForm, - getRequest, modalForm, success, successMessage diff --git a/src/pages/Books.tsx b/src/pages/Books.tsx index 7eca1c1..6823432 100644 --- a/src/pages/Books.tsx +++ b/src/pages/Books.tsx @@ -9,8 +9,8 @@ import BookForm from "../components/forms/BookForm"; import Skeleton from "../components/ui/Skeleton"; const Books = (): ReactElement => { - const { user, isAuthenticated, isLoading, handleLogout, setIsFetching } = AuthContainer.useContainer(); - const hook = useBooks({ user, isAuthenticated, handleLogout, setIsFetching }); + const { user, isAuthenticated, isLoading, handleLogout, setIsFetching, setGetRequest } = AuthContainer.useContainer(); + const hook = useBooks({ user, isAuthenticated, handleLogout, setIsFetching, setGetRequest }); return (
@@ -33,7 +33,7 @@ const Books = (): ReactElement => { {!isLoading ?
Total number of books: {hook.books.length}
: null} - + Date: Sun, 10 Apr 2022 00:28:41 +0100 Subject: [PATCH 12/12] Cleanup code and fix code consistency --- src/hooks/useAuth.tsx | 15 --- src/hooks/useBooks.tsx | 197 +--------------------------------------- src/hooks/useLoader.tsx | 4 +- src/setupTests.ts | 5 - 4 files changed, 5 insertions(+), 216 deletions(-) delete mode 100644 src/setupTests.ts diff --git a/src/hooks/useAuth.tsx b/src/hooks/useAuth.tsx index 90c28a9..08c8fa8 100644 --- a/src/hooks/useAuth.tsx +++ b/src/hooks/useAuth.tsx @@ -38,21 +38,6 @@ export const useAuth = () => { const [user, setUser] = useState(initialUser); const [form, setForm] = useState(initialForm); - // useEffect(() => { // Suggestions from Silas - // // Set isloading to true - - // // read token from local storage - // // if token exists, - // // read user data from local storage - // // set the user variable - // // set isAuthenticated to true - - // // if token doesn't exist, - // // set isAuthenticated to false - - // // set isLoading to false - // }, []); - useEffect(() => { const token = localStorage.getItem('buuks_accessToken'); token ? handleLogIn() : handleLogout(); diff --git a/src/hooks/useBooks.tsx b/src/hooks/useBooks.tsx index 5cd0a51..9b6345a 100644 --- a/src/hooks/useBooks.tsx +++ b/src/hooks/useBooks.tsx @@ -1,20 +1,19 @@ import { ChangeEvent, Dispatch, SetStateAction, useEffect, useState } from "react"; import { fetchOptions } from "../lib/books"; import { BooksObject, ModalForm, PostForm } from "../interfaces/books"; -// import { AuthContainer } from "./useAuth"; +import { User } from "../interfaces/auth"; export const useBooks = ( { user, isAuthenticated, handleLogout, setIsFetching, setGetRequest }: { - user: any, + user: User, isAuthenticated: boolean, handleLogout: () => void, setIsFetching: Dispatch>, setGetRequest: Dispatch> }) => { - // const auth = AuthContainer.useContainer(); let [books, setBooks] = useState([]); - const [modal, setModal] = useState(false); + const [modal, setModal] = useState(false); const [success, setSuccess] = useState(false); const [successMessage, setSuccessMessage] = useState(''); const initialForm = { @@ -51,8 +50,6 @@ export const useBooks = ( if (method === 'POST' || method === 'PUT') e.preventDefault(); setIsFetching(true); if (method === 'GET') setGetRequest(true); - // if (method === 'GET' && !auth.isLoading) setBooksLoading(false); - // if (method !== 'GET' && !auth.isLoading) setBooksLoading(null); // trackProgress(true, false, ''); let response: Response; response = await fetch(`${process.env.REACT_APP_BASE_URL}/${apiEndpoint}`, fetchOptions(method, form)); @@ -199,191 +196,3 @@ export const useBooks = ( successMessage } } - - - - - - - -// import { ChangeEvent, useState } from "react"; -// import { fetchOptions } from "../lib/books"; -// import { BooksObject, ModalForm, PostForm } from "../interfaces/books"; -// import { AuthContainer } from "./useAuth"; - -// export const useBooks = (): Record => { -// const auth = AuthContainer.useContainer(); -// let [books, setBooks] = useState([]); -// const [modal, setModal] = useState(false); -// const [success, setSuccess] = useState(false); -// const [successMessage, setSuccessMessage] = useState(''); -// const [booksLoading, setBooksLoading] = useState(null); -// const initialForm = { -// title: '', -// description: '', -// pdf: '' -// }; -// const initialModalform = { -// persistInstruction: false, -// persistFormBody: false, -// persistTitle: false, -// persistDescription: false, -// persistFile: false, -// title: '', -// buttonText: '', -// placeholderText: { -// title: '', -// description: '' -// }, -// method: '', -// apiEndpoint: '', -// bookId: '' -// } -// const [form, setForm] = useState(initialForm); -// const [modalForm, setModalForm] = useState(initialModalform); - -// const fetchBookData = async (e: any, method: string, apiEndpoint: string, bookId: string | null) => { -// if (method === 'POST' || method === 'PUT') e.preventDefault(); -// if (method === 'GET' && !auth.isLoading) setBooksLoading(false); -// if (method !== 'GET' && !auth.isLoading) setBooksLoading(null); -// trackProgress(true, false, ''); -// let response: Response; -// response = await fetch(`${process.env.REACT_APP_BASE_URL}/${apiEndpoint}`, fetchOptions(method, form)); -// const data = await response.json(); -// if (response.ok) { -// trackProgress(false, false, ''); -// if (method === 'GET') setBooks(data.books); -// if (method === 'DELETE') setBooks(books.filter(book => book._id !== bookId)); -// if (method === 'POST') { -// books.unshift(data.book); -// handleModal(false); -// } -// if (method === 'PUT') { -// const updated = books.map((book) => { -// if (book._id === bookId) return { ...book, ...data.book }; -// return book; -// }); -// setBooks(updated); -// handleModal(false); -// } -// if (method !== 'GET') { -// setSuccessMessage(data.message) -// setSuccess(true); -// const removeSuccessMsg = () => setSuccess(false); -// const interval = setInterval(removeSuccessMsg, 2000); -// const removeInterval = () => clearInterval(interval); -// setTimeout(removeInterval, 2000); -// } -// resetForm(); -// } -// if (response.status === 400) { -// if (method === 'POST') trackProgress(false, true, 'All fields are required. Also, only PDF files are allowed.'); -// if (method === 'PUT') trackProgress(false, true, 'Only PDF files are allowed.'); -// if (method === 'POST' && data[0].code === 'too_small') trackProgress(false, true, `${data[0].message}. All fields are required. Also, only PDF files are allowed.`); -// } -// if (response.status === 401) { -// trackProgress(false, true, 'Your session has expired, please login again'); -// auth.setUnAuthorizedError(true); -// const removeError = () => auth.setUnAuthorizedError(false); -// const interval = setInterval(removeError, 200); -// const removeInterval = () => { -// auth.handleLogout(); -// clearInterval(interval); -// } -// setTimeout(removeInterval, 200); -// } -// // console.log('data: ', data); -// } - -// const handleInputChange = (e: ChangeEvent, checkboxString: string) => { // checkboxString: string | null -// const { name, value, files, checked } = e.target; -// if (name === 'title' || name === 'description') setForm({ ...form, [name]: value } as Pick); -// if (name === 'pdf') setForm({ ...form, [name]: files![0] } as Pick); -// if (name === 'checkbox') { -// if (checked) { -// setModalForm({ ...modalForm, [checkboxString]: true }); -// } else { -// setModalForm({ ...modalForm, [checkboxString]: false }); -// } -// } -// trackProgress(false, false, ''); -// } - -// const trackProgress = (loading: boolean, errBool: boolean, errString: string) => { -// auth.setIsLoading(loading); -// auth.handleError(errBool, errString); -// } - -// const handleModal = (boolean: boolean) => { -// setModal(boolean); -// if (!boolean) { -// setModalForm(initialModalform); -// auth.handleError(false, ''); -// resetForm(); -// } -// } - -// const handlePostRequestForm = (boolean: boolean, operation: string, bookId: string | null) => { -// handleModal(boolean); -// if (operation === 'add') { -// setModalForm({ -// persistInstruction: false, -// persistFormBody: true, -// persistTitle: true, -// persistDescription: true, -// persistFile: true, -// title: 'New Book - Form', -// buttonText: 'Submit new book', -// placeholderText: { -// title: 'New book title', -// description: 'New book description' -// }, -// method: 'POST', -// apiEndpoint: 'books', -// bookId: bookId -// }); -// } -// if (operation === 'update') { -// setModalForm({ -// persistInstruction: true, -// persistFormBody: true, -// persistTitle: false, -// persistDescription: false, -// persistFile: false, -// title: 'Update Book - Form', -// buttonText: 'Update book', -// placeholderText: { -// title: 'Update book title', -// description: 'Update book description' -// }, -// method: 'PUT', -// apiEndpoint: `books/${bookId}`, -// bookId: bookId -// }); -// const cardInfo = books.filter((book) => book._id === bookId)[0]; -// setForm({ -// title: cardInfo.title, -// description: cardInfo.description, -// pdf: '' -// }) -// } -// } - -// const resetForm = () => { -// setForm(initialForm); -// } - -// return { -// books, -// modal, -// form, -// handleModal, -// fetchBookData, -// handleInputChange, -// handlePostRequestForm, -// modalForm, -// booksLoading, -// success, -// successMessage -// } -// } \ No newline at end of file diff --git a/src/hooks/useLoader.tsx b/src/hooks/useLoader.tsx index 4f81540..d114299 100644 --- a/src/hooks/useLoader.tsx +++ b/src/hooks/useLoader.tsx @@ -1,7 +1,7 @@ -import { useEffect, useState } from "react" +import { useEffect, useState } from 'react'; export const useLoader = ({ fixed }: { fixed: boolean }) => { - const [loader, setLoader] = useState({ + const [loader, setLoader] = useState<{ text: string; style: string;}>({ text: '', style: '' }); diff --git a/src/setupTests.ts b/src/setupTests.ts deleted file mode 100644 index 8f2609b..0000000 --- a/src/setupTests.ts +++ /dev/null @@ -1,5 +0,0 @@ -// jest-dom adds custom jest matchers for asserting on DOM nodes. -// allows you to do things like: -// expect(element).toHaveTextContent(/react/i) -// learn more: https://github.com/testing-library/jest-dom -import '@testing-library/jest-dom';