From 5f7c27b060ff6b98daa091a97eae06e1dbf3a863 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Tue, 2 Nov 2021 23:51:29 +0300 Subject: [PATCH] refactor: render list --- .../PrevPageButton/PrevPageButton.tsx | 24 +++++++++ src/components/PrevPageButton/index.ts | 3 ++ .../components/CategoryList/CategoryItem.tsx | 4 +- .../components/CategoryList/CategoryList.tsx | 25 +++++----- .../components/CourseList/CourseItem.tsx | 2 +- .../components/CourseList/CourseList.tsx | 49 ++++++++++--------- src/pages/courses/courses.tsx | 11 ++--- src/pages/courses/create/create.tsx | 16 ++++-- .../profile/change-email/change-email.tsx | 15 ++---- .../change-password/change-password.tsx | 18 ++----- .../UpdateUserContactsForm.tsx | 4 +- src/pages/profile/profile.tsx | 2 +- .../users/components/UserList/UserItem.tsx | 13 +++-- .../users/components/UserList/UserList.tsx | 4 +- 14 files changed, 108 insertions(+), 82 deletions(-) create mode 100644 src/components/PrevPageButton/PrevPageButton.tsx create mode 100644 src/components/PrevPageButton/index.ts diff --git a/src/components/PrevPageButton/PrevPageButton.tsx b/src/components/PrevPageButton/PrevPageButton.tsx new file mode 100644 index 0000000..31c280c --- /dev/null +++ b/src/components/PrevPageButton/PrevPageButton.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { IconButton } from '@chakra-ui/react'; +import { ChevronLeftIcon } from '@chakra-ui/icons'; +import { useHistory } from 'react-router'; + +type PrevPageButtonProps = { + prevPage: string; +}; + +const PrevPageButton: React.FC = ({ prevPage }) => { + const history = useHistory(); + + return ( + } + onClick={() => history.push(prevPage)} + mr='5' + /> + ); +}; + +export default PrevPageButton; diff --git a/src/components/PrevPageButton/index.ts b/src/components/PrevPageButton/index.ts new file mode 100644 index 0000000..50ea245 --- /dev/null +++ b/src/components/PrevPageButton/index.ts @@ -0,0 +1,3 @@ +import PrevPageButton from './PrevPageButton'; + +export default PrevPageButton; diff --git a/src/pages/courses/components/CategoryList/CategoryItem.tsx b/src/pages/courses/components/CategoryList/CategoryItem.tsx index 34bfcc0..7bd92f5 100644 --- a/src/pages/courses/components/CategoryList/CategoryItem.tsx +++ b/src/pages/courses/components/CategoryList/CategoryItem.tsx @@ -16,11 +16,11 @@ import { CoursesPageContext } from '@educt/contexts'; */ import { useContext } from 'react'; -type CategoryItemProps = { +export type CategoryItemPropsType = { category: ICategory; }; -const CategoryItem: React.FC = ({ category }) => { +const CategoryItem: React.FC = ({ category }) => { const { selectedCategory, setSelectedCategory } = useContext(CoursesPageContext); /** diff --git a/src/pages/courses/components/CategoryList/CategoryList.tsx b/src/pages/courses/components/CategoryList/CategoryList.tsx index e603456..767e034 100644 --- a/src/pages/courses/components/CategoryList/CategoryList.tsx +++ b/src/pages/courses/components/CategoryList/CategoryList.tsx @@ -1,15 +1,15 @@ import React from 'react'; +import { observer } from 'mobx-react'; import { Box, Flex, Tag, TagLabel } from '@chakra-ui/react'; /** * Types */ -import { ICategory } from '@educt/interfaces'; +import { CategoryItemPropsType } from './CategoryItem'; /** * Components */ -import CategoryItem from './CategoryItem'; import CategoryListLoading from './CategoryListLoading'; /** @@ -25,14 +25,14 @@ import { useRootStore } from '@educt/hooks/useRootStore'; import { useErrorHandler } from 'react-error-boundary'; type CategoryListPropsType = { - categories: ICategory[] | null; - isLoading: boolean; + render: React.FC; }; -const CategoryList: React.FC = ({ categories, isLoading }) => { +const CategoryList: React.FC = ({ render: Item }) => { const { categoryStore } = useRootStore(); const { selectedCategory, setSelectedCategory } = useContext(CoursesPageContext); const handleError = useErrorHandler(); + const { categories, isLoading } = categoryStore; /** * Fetch handler @@ -41,9 +41,10 @@ const CategoryList: React.FC = ({ categories, isLoading } categoryStore.loadCategories().catch(error => handleError(error)); }, [categoryStore, handleError]); - if (isLoading || categories === null) { - return ; - } + /** + * Loading + */ + if (categories === null || isLoading) return ; return ( @@ -58,13 +59,13 @@ const CategoryList: React.FC = ({ categories, isLoading } > All categories - {/* Render items */} - {categories.map((category, i) => ( - + + {categories.map(category => ( + ))} ); }; -export default CategoryList; +export default observer(CategoryList); diff --git a/src/pages/courses/components/CourseList/CourseItem.tsx b/src/pages/courses/components/CourseList/CourseItem.tsx index f628b64..74cf85e 100644 --- a/src/pages/courses/components/CourseList/CourseItem.tsx +++ b/src/pages/courses/components/CourseList/CourseItem.tsx @@ -24,7 +24,7 @@ import CourseStatusBadge from '@educt/components/CourseStatusBadge'; import { useColorMode } from '@chakra-ui/color-mode'; import { useRootStore } from '@educt/hooks/useRootStore'; -type CourseItemPropsType = { +export type CourseItemPropsType = { course: Omit; onDelete: (course: Pick) => void; onSetStatus: (id: string, status: CourseStatusEnum) => Promise; diff --git a/src/pages/courses/components/CourseList/CourseList.tsx b/src/pages/courses/components/CourseList/CourseList.tsx index 6dd15d3..712d223 100644 --- a/src/pages/courses/components/CourseList/CourseList.tsx +++ b/src/pages/courses/components/CourseList/CourseList.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { observer } from 'mobx-react'; import { Box, Grid, Text } from '@chakra-ui/react'; /** @@ -10,7 +11,7 @@ import { CourseStatusEnum } from '@educt/enums'; /** * Components */ -import CourseItem from './CourseItem'; +import CourseItem, { CourseItemPropsType } from './CourseItem'; import CourseListLoading from './CourseListLoading'; import DeleteCourseDialog from '../DeleteCourseDialog'; @@ -29,11 +30,10 @@ import { useErrorHandler } from 'react-error-boundary'; import { CoursesPageContext } from '@educt/contexts'; type CourseListPropsType = { - courses: Omit[] | null; - isLoading: boolean; + render: React.FC; }; -const CourseList: React.FC = ({ courses, isLoading }) => { +const CourseList: React.FC = ({ render: Item }) => { const { userStore: { me }, courseStore, @@ -42,6 +42,7 @@ const CourseList: React.FC = ({ courses, isLoading }) => { const { onOpen: onOpenDeleteDialog, onClose: onCloseDeleteDialog, isOpen: isOpenDeleteDialog } = useDisclosure(); const handleError = useErrorHandler(); const toast = useToast(); + const { courses, isLoading } = courseStore; /** * Fetch courses handler @@ -80,27 +81,31 @@ const CourseList: React.FC = ({ courses, isLoading }) => { } }; - if (isLoading || courses === null) { - return ; - } + /** + * Loading + */ + if (courses === null || isLoading) return ; + + /** + * No courses + */ + if (courses.length === 0) + return ( + + There are no courses in this category {courseStatus && 'or with this status'}. + + ); return ( - <> + {deletingCourse && } - {courses.length !== 0 ? ( - - {/* Render items */} - {courses.map(course => ( - - ))} - - ) : ( - - There are no courses in this category {courseStatus && 'or with this status'}. - - )} - + + {courses.map(course => ( + + ))} + + ); }; -export default CourseList; +export default observer(CourseList); diff --git a/src/pages/courses/courses.tsx b/src/pages/courses/courses.tsx index 24e8c74..33485dc 100644 --- a/src/pages/courses/courses.tsx +++ b/src/pages/courses/courses.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import { observer } from 'mobx-react'; import { Flex, Box, Heading, Text, Button } from '@chakra-ui/react'; import { AddIcon } from '@chakra-ui/icons'; @@ -26,6 +25,8 @@ import { CoursesPageContextProvider } from '@educt/providers'; */ import { useRootStore } from '@educt/hooks/useRootStore'; import { useHistory } from 'react-router'; +import CategoryItem from './components/CategoryList/CategoryItem'; +import CourseItem from './components/CourseList/CourseItem'; /** * Courses page @@ -33,8 +34,6 @@ import { useHistory } from 'react-router'; const CoursesPage: React.FC = () => { const { userStore: { me }, - categoryStore, - courseStore, } = useRootStore(); const history = useHistory(); @@ -62,8 +61,8 @@ const CoursesPage: React.FC = () => { {(me.isAdmin || me.isTeacher) && } - - + + @@ -71,4 +70,4 @@ const CoursesPage: React.FC = () => { ); }; -export default observer(CoursesPage); +export default CoursesPage; diff --git a/src/pages/courses/create/create.tsx b/src/pages/courses/create/create.tsx index 9e0bdd8..1dc3936 100644 --- a/src/pages/courses/create/create.tsx +++ b/src/pages/courses/create/create.tsx @@ -1,21 +1,29 @@ import React from 'react'; -import { Box, Heading, Text } from '@chakra-ui/react'; +import { Flex, Box, Heading, Text } from '@chakra-ui/react'; /** * Types */ import { IPageProps } from '@educt/interfaces'; + +/** + * Components + */ +import PrevPageButton from '@educt/components/PrevPageButton'; import CreateCourseForm from './components'; /** * Create course page */ -const CreateCoursePage: React.FC = ({ title }) => { +const CreateCoursePage: React.FC = () => { return ( - Create course - Fill in the required fields to create a course + + + Create course + + Fill in the required fields to create a course diff --git a/src/pages/profile/change-email/change-email.tsx b/src/pages/profile/change-email/change-email.tsx index 2cad6e7..a28e321 100644 --- a/src/pages/profile/change-email/change-email.tsx +++ b/src/pages/profile/change-email/change-email.tsx @@ -1,7 +1,6 @@ import React from 'react'; +import { observer } from 'mobx-react'; import { Box, Flex, Heading, Text } from '@chakra-ui/layout'; -import { IconButton } from '@chakra-ui/button'; -import { ChevronLeftIcon } from '@chakra-ui/icons'; /** * Types @@ -22,9 +21,7 @@ import ConfirmEmailContainer from './containers/ConfirmEmailContainer'; /** * Hooks */ -import { useHistory } from 'react-router'; import { useRootStore } from '@educt/hooks/useRootStore'; -import { observer } from 'mobx-react'; /** * Contexts @@ -35,6 +32,7 @@ import { ChangeEmailPageContext } from '@educt/contexts'; * Providers */ import { ChangeEmailPageContextProvider } from '@educt/providers'; +import PrevPageButton from '@educt/components/PrevPageButton'; /** * Change email page @@ -43,7 +41,6 @@ const ChangeEmailPage: React.FC = () => { const { userStore: { me }, } = useRootStore(); - const history = useHistory(); if (me === null) return ; @@ -55,13 +52,7 @@ const ChangeEmailPage: React.FC = () => { {!isCodeSent ? ( - } - onClick={() => history.push('/profile')} - mr='5' - /> + Edit email address diff --git a/src/pages/profile/change-password/change-password.tsx b/src/pages/profile/change-password/change-password.tsx index d159591..d8a66ba 100644 --- a/src/pages/profile/change-password/change-password.tsx +++ b/src/pages/profile/change-password/change-password.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { Box, Heading, Flex, Text, IconButton } from '@chakra-ui/react'; -import { ChevronLeftIcon } from '@chakra-ui/icons'; +import { observer } from 'mobx-react'; +import { Box, Heading, Flex, Text } from '@chakra-ui/react'; /** * Types @@ -11,14 +11,13 @@ import { IPageProps } from '@educt/interfaces'; * Components */ import UpdatePasswordForm from './components/UpdatePasswordForm'; +import PrevPageButton from '@educt/components/PrevPageButton'; +import LoadingPage from '@educt/components/LoadingPage'; /** * Hooks */ import { useRootStore } from '@educt/hooks/useRootStore'; -import { useHistory } from 'react-router'; -import LoadingPage from '@educt/components/LoadingPage'; -import { observer } from 'mobx-react'; /** * Change password page @@ -27,20 +26,13 @@ const ChangePasswordPage: React.FC = () => { const { userStore: { me }, } = useRootStore(); - const history = useHistory(); if (me === null) return ; return ( - } - onClick={() => history.push('/profile')} - mr='5' - /> + Update password diff --git a/src/pages/profile/components/UpdateUserContactsForm/UpdateUserContactsForm.tsx b/src/pages/profile/components/UpdateUserContactsForm/UpdateUserContactsForm.tsx index 2cbf3c4..1de20c8 100644 --- a/src/pages/profile/components/UpdateUserContactsForm/UpdateUserContactsForm.tsx +++ b/src/pages/profile/components/UpdateUserContactsForm/UpdateUserContactsForm.tsx @@ -3,7 +3,7 @@ import { observer } from 'mobx-react'; import { SubmitHandler, useForm } from 'react-hook-form'; import { MdSave } from 'react-icons/md'; import { Text, Input, Button } from '@chakra-ui/react'; -import { Box, Heading, Stack } from '@chakra-ui/layout'; +import { Box, Stack } from '@chakra-ui/layout'; import { FormControl, FormHelperText } from '@chakra-ui/form-control'; import { yupResolver } from '@hookform/resolvers/yup'; @@ -90,7 +90,7 @@ const UpdateUserContactsForm: React.FC = ({ con return (
- + Phone number with country code diff --git a/src/pages/profile/profile.tsx b/src/pages/profile/profile.tsx index 979fb52..4f01db9 100644 --- a/src/pages/profile/profile.tsx +++ b/src/pages/profile/profile.tsx @@ -83,7 +83,7 @@ const ProfilePage: React.FC = () => { - + First name diff --git a/src/pages/users/components/UserList/UserItem.tsx b/src/pages/users/components/UserList/UserItem.tsx index 8e00fb1..d47d80c 100644 --- a/src/pages/users/components/UserList/UserItem.tsx +++ b/src/pages/users/components/UserList/UserItem.tsx @@ -1,8 +1,8 @@ import React from 'react'; +import { Link as ReactRouterLink } from 'react-router-dom'; import * as helpres from '@educt/helpers'; import { Box, Flex, Avatar, Text, IconButton, Link } from '@chakra-ui/react'; -import { Link as ReactRouterLink } from 'react-router-dom'; -import UserBadge from '@educt/components/UserBadge'; +import { DeleteIcon, EditIcon } from '@chakra-ui/icons'; /** * Types @@ -10,11 +10,16 @@ import UserBadge from '@educt/components/UserBadge'; import { IUser } from '@educt/interfaces'; import { UserRoleEnum } from '@educt/enums'; +/** + * Components + */ +import UserBadge from '@educt/components/UserBadge'; + /** * Hooks */ import { useRootStore } from '@educt/hooks/useRootStore'; -import { DeleteIcon, EditIcon } from '@chakra-ui/icons'; +import { useColorModeValue } from '@chakra-ui/react'; type UserItemPropsType = { user: IUser; @@ -46,7 +51,7 @@ const UserItem: React.FC = ({ user, onEdit, onDelete }) => { })(); return ( - + diff --git a/src/pages/users/components/UserList/UserList.tsx b/src/pages/users/components/UserList/UserList.tsx index c9bc920..998f7f4 100644 --- a/src/pages/users/components/UserList/UserList.tsx +++ b/src/pages/users/components/UserList/UserList.tsx @@ -8,6 +8,7 @@ import { Button } from '@chakra-ui/button'; */ import UserItem from './UserItem'; import EditUserForm from '../EditUserForm'; +import DeleteUserDialog from '../DeleteUserDialog'; /** * Types @@ -27,7 +28,6 @@ import { useContext } from 'react'; import { useRootStore } from '@educt/hooks/useRootStore'; import { useDisclosure } from '@chakra-ui/hooks'; import { useErrorHandler } from 'react-error-boundary'; -import DeleteUserDialog from '../DeleteUserDialog'; type UserListPropsType = { users: IUser[]; pagination: IPaginationMeta }; @@ -85,7 +85,6 @@ const UserList: React.FC = ({ users, pagination }) => { const onEditUser = (user: IUser) => { setEditingUser(user); onOpenEditModal(); - console.log(`[LOG]: Editing user "${user.id}"`); }; /** @@ -95,7 +94,6 @@ const UserList: React.FC = ({ users, pagination }) => { const onDeleteUser = (user: IUser) => { setDeletingUser(user); onOpenDeleteDialog(); - console.log(`[LOG]: Alert delete "${user.id}"`); }; return (