diff --git a/src/components/Header/UserInfo.tsx b/src/components/Header/UserInfo.tsx index 8af61f6..c166c63 100644 --- a/src/components/Header/UserInfo.tsx +++ b/src/components/Header/UserInfo.tsx @@ -18,6 +18,10 @@ import { observer } from 'mobx-react'; import { useRootStore } from '@educt/hooks/useRootStore'; import { Link } from 'react-router-dom'; import UserBadge from '@educt/components/UserBadge'; + +/** + * Hooks + */ import useLogoutQuery from '@educt/hooks/useLogoutQuery'; const UserInfo: React.FC = () => { diff --git a/src/hooks/useAsync.ts b/src/hooks/useAsync.ts index 6fdc0da..20e40ea 100644 --- a/src/hooks/useAsync.ts +++ b/src/hooks/useAsync.ts @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useState } from 'react'; +import { useCallback, useState } from 'react'; import useIsMountedRef from './useIsMountedRef'; type StateType = { diff --git a/src/hooks/useFetchCourseQuery.ts b/src/hooks/useFetchCourseQuery.ts index 452b574..aaa215b 100644 --- a/src/hooks/useFetchCourseQuery.ts +++ b/src/hooks/useFetchCourseQuery.ts @@ -2,56 +2,38 @@ * Types */ import { ICourse } from '@educt/interfaces'; +import { useEffect } from 'react'; /** * Hooks */ -import { useEffect, useState } from 'react'; import { useErrorHandler } from 'react-error-boundary'; -import useIsMountedRef from './useIsMountedRef'; +import useAsync from './useAsync'; import { useRootStore } from './useRootStore'; -type CourseStateType = { - data: Omit | null; - error: any; - loading: boolean; - fetched: boolean; -}; +type QueryResponseDataType = Omit | undefined; const useFetchCourseQuery = (id: string) => { const { courseStore: { courseService }, } = useRootStore(); - const [state, setState] = useState({ data: null, error: null, loading: false, fetched: false }); - const isMountedRef = useIsMountedRef(); const handleError = useErrorHandler(); - /** - * Fetch course handler - */ + const fetch = async (id: string) => { + try { + const result = await courseService.fetchById(id); + return result.data; + } catch (error: any) { + if (!error.response) { + handleError(error); + } + } + }; + + const { execute: fetchCourseById, ...state } = useAsync>(fetch); + useEffect(() => { - setState(s => ({ ...s, loading: true })); - courseService - .fetchById(id) - .then(data => { - if (isMountedRef.current) { - setState(s => ({ ...s, data: data.data })); - } - }) - .catch(error => { - if (error.response) { - if (isMountedRef.current) { - setState(s => ({ ...s, error })); - } - } else { - handleError(error); - } - }) - .finally(() => { - if (isMountedRef.current) { - setState(s => ({ ...s, loading: false, fetched: true })); - } - }); + fetchCourseById(id); }, [id]); return { ...state }; diff --git a/src/hooks/useLoginQuery.ts b/src/hooks/useLoginQuery.ts index 249f7dc..f1bf2e1 100644 --- a/src/hooks/useLoginQuery.ts +++ b/src/hooks/useLoginQuery.ts @@ -18,7 +18,7 @@ const useLoginQuery = () => { isClosable: true, status: 'success', }); - return result; + return result.data; } catch (error: any) { if (error.response) { /** @@ -41,7 +41,7 @@ const useLoginQuery = () => { } }; - const { execute, ...state } = useAsync | undefined, Parameters>(login); + const { execute, ...state } = useAsync>(login); return { login: execute, ...state }; }; diff --git a/src/hooks/useLogoutQuery.ts b/src/hooks/useLogoutQuery.ts index be20d97..67eed7f 100644 --- a/src/hooks/useLogoutQuery.ts +++ b/src/hooks/useLogoutQuery.ts @@ -1,49 +1,28 @@ -import { useState } from 'react'; import { useToast } from '@chakra-ui/react'; import { useHistory } from 'react-router-dom'; import { useRootStore } from './useRootStore'; -import { IApiRespose } from '@educt/interfaces'; import { useErrorHandler } from 'react-error-boundary'; -import useIsMountedRef from './useIsMountedRef'; - -type LogoutStateType = { - result: IApiRespose<{}> | null; - error: any; - loading: boolean; - fetched: boolean; -}; +import useAsync from './useAsync'; const useLogoutQuery = () => { const { authStore } = useRootStore(); - const [state, setState] = useState({ result: null, error: null, loading: false, fetched: false }); - const isMountedRef = useIsMountedRef(); const history = useHistory(); const toast = useToast(); const handleError = useErrorHandler(); const logout = async () => { - setState(s => ({ ...s, loading: true })); try { - const data = await authStore.logout(); + await authStore.logout(); history.push('/auth'); - toast({ title: 'You are logged out.', isClosable: true, status: 'info' }); - if (isMountedRef.current) { - setState(s => ({ ...s, result: data })); - } } catch (error) { - if (isMountedRef.current) { - setState(s => ({ ...s, error })); - } handleError(error); - } finally { - if (isMountedRef.current) { - setState(s => ({ ...s, loading: false, fetched: true })); - } } }; - return { ...state, logout }; + const { execute, ...state } = useAsync>(logout); + + return { logout: execute, ...state }; }; export default useLogoutQuery; diff --git a/src/pages/courses/edit/edit.tsx b/src/pages/courses/edit/edit.tsx index 4df1bdb..0e0e765 100644 --- a/src/pages/courses/edit/edit.tsx +++ b/src/pages/courses/edit/edit.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import Helmet from 'react-helmet'; import { Redirect } from 'react-router-dom'; import { Box, Heading, Text, Tab, TabList, Flex, Tabs, TabPanels, TabPanel } from '@chakra-ui/react'; @@ -27,7 +27,7 @@ import useFetchCourseQuery from '@educt/hooks/useFetchCourseQuery'; */ const EditCoursePage: React.FC = () => { const params = useParams<{ id: string }>(); - const { data: course, loading, error } = useFetchCourseQuery(params.id); + const { data: course, error, isLoading } = useFetchCourseQuery(params.id); /** * Not Found @@ -37,7 +37,7 @@ const EditCoursePage: React.FC = () => { /** * Loading */ - if (loading || course === null) return ; + if (isLoading || !course) return ; return ( <> diff --git a/src/pages/main/main.tsx b/src/pages/main/main.tsx index af8870e..ff9b74b 100644 --- a/src/pages/main/main.tsx +++ b/src/pages/main/main.tsx @@ -1,8 +1,7 @@ import React from 'react'; -import { Box, Heading, Breadcrumb, BreadcrumbItem, BreadcrumbLink, Grid } from '@chakra-ui/react'; +import { Box, Heading } from '@chakra-ui/react'; import { IPageProps } from '@educt/interfaces'; -import { observer } from 'mobx-react'; /** * Main page