From a14ed5eff9db367c589733ccbdd29a4db2195688 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Wed, 2 Feb 2022 19:03:44 +0300 Subject: [PATCH] refactor: page --- .../AddStudentsModal/AddSudentsModal.tsx | 2 +- src/components/PageElements/index.tsx | 24 ++++++++----- src/components/UserProfile/Avatar/Avatar.tsx | 2 +- src/components/UserProfile/Avatar/index.ts | 2 +- src/components/UserProfile/index.tsx | 15 ++++---- src/pages/404/404.tsx | 10 +++--- src/pages/categories/categories.tsx | 18 ++++++---- src/pages/course/course.tsx | 10 +++--- src/pages/courses/courses.tsx | 14 ++++---- .../courses/create-lesson/create-lesson.tsx | 12 +++---- src/pages/courses/create/create.tsx | 13 ++++--- src/pages/courses/edit/edit.tsx | 14 ++++---- src/pages/lesson/lesson.tsx | 14 ++++---- src/pages/lessons/edit-lesson/edit-lesson.tsx | 14 ++++---- src/pages/main/components/index.tsx | 2 +- src/pages/main/main.tsx | 20 ++++++----- src/pages/messages/messages.tsx | 9 ++--- src/pages/profile/components/index.tsx | 10 ------ src/pages/profile/profile.tsx | 34 ++++++++++--------- src/pages/user/user.tsx | 28 ++++++++++----- src/pages/users/users.tsx | 12 +++---- src/stores/UserStore.ts | 19 ++++++++++- 22 files changed, 167 insertions(+), 131 deletions(-) diff --git a/src/components/Modals/AddStudentsModal/AddSudentsModal.tsx b/src/components/Modals/AddStudentsModal/AddSudentsModal.tsx index cd2164e..4fddfb1 100644 --- a/src/components/Modals/AddStudentsModal/AddSudentsModal.tsx +++ b/src/components/Modals/AddStudentsModal/AddSudentsModal.tsx @@ -53,7 +53,7 @@ const AddStudentsModal: React.FC = ({ icon={MdGroup} heading='Add new students' description='Attach new students to current course.' - confirmText='Add students' + confirmText='Add' isOpen={isOpen} onClose={onClose} onProceed={handleAttachStudents} diff --git a/src/components/PageElements/index.tsx b/src/components/PageElements/index.tsx index 1d06fc4..b11f8c6 100644 --- a/src/components/PageElements/index.tsx +++ b/src/components/PageElements/index.tsx @@ -1,17 +1,23 @@ import React from 'react'; import { BoxProps, Box, Flex, Heading, Text, Divider } from '@chakra-ui/react'; -interface IPageHeadingProps extends BoxProps { +interface IPageComposition { + Heading: React.FC; + Content: React.FC; + Footer: React.FC; +} + +const Page: React.FC & IPageComposition = props => { + return {props.children}; +}; + +interface IPageHeadingProps { headingPrefix?: JSX.Element; heading: string; description?: string; } -export const PageWrapper: React.FC = props => { - return {props.children}; -}; - -export const PageHeading: React.FC = props => { +Page.Heading = props => { const { headingPrefix, heading, description, ...boxProps } = props; return ( @@ -26,15 +32,17 @@ export const PageHeading: React.FC = props => { ); }; -export const PageContent: React.FC = props => ( +Page.Content = props => ( {props.children} ); -export const PageFooter: React.FC = props => ( +Page.Footer = props => ( {props.children} ); + +export { Page }; diff --git a/src/components/UserProfile/Avatar/Avatar.tsx b/src/components/UserProfile/Avatar/Avatar.tsx index e1b507f..cc6ba4d 100644 --- a/src/components/UserProfile/Avatar/Avatar.tsx +++ b/src/components/UserProfile/Avatar/Avatar.tsx @@ -10,7 +10,7 @@ const Avatar: React.FC = props => { return ( - + {isOnline && } {props.children} diff --git a/src/components/UserProfile/Avatar/index.ts b/src/components/UserProfile/Avatar/index.ts index e2e6c6b..191590b 100644 --- a/src/components/UserProfile/Avatar/index.ts +++ b/src/components/UserProfile/Avatar/index.ts @@ -3,7 +3,7 @@ import { ChatButton } from './ChatButton'; export interface IAvatarProps { name: string; - isOnline: boolean; + isOnline?: boolean | undefined; } export interface IChatButtonProps { diff --git a/src/components/UserProfile/index.tsx b/src/components/UserProfile/index.tsx index 399c265..43b705f 100644 --- a/src/components/UserProfile/index.tsx +++ b/src/components/UserProfile/index.tsx @@ -1,6 +1,5 @@ -import React, { createContext } from 'react'; -import { BoxProps, Flex } from '@chakra-ui/react'; -import { IUser } from '@educt/interfaces'; +import React from 'react'; +import { BoxProps, Flex, FlexProps } from '@chakra-ui/react'; import { Avatar, ChatButton, IAvatarProps, IChatButtonProps } from './Avatar'; import { About, Details, Heading, IAboutProps, IDetailsProps, IHeadingProps, Info } from './Info'; @@ -13,10 +12,12 @@ interface IUserProfileComposition { About: React.FC; } -export const UserProfileContext = createContext(undefined); - -const UserProfile: React.FC & IUserProfileComposition = props => { - return {props.children}; +const UserProfile: React.FC & IUserProfileComposition = props => { + return ( + + {props.children} + + ); }; UserProfile.Avatar = Avatar; diff --git a/src/pages/404/404.tsx b/src/pages/404/404.tsx index 2d67e41..7e9bf88 100644 --- a/src/pages/404/404.tsx +++ b/src/pages/404/404.tsx @@ -8,7 +8,7 @@ import { MdError } from 'react-icons/md'; * Types */ import { IPageProps } from '@educt/interfaces'; -import { PageContent, PageWrapper } from '@educt/components/PageElements'; +import { Page } from '@educt/components/PageElements'; /** * Hooks @@ -28,8 +28,8 @@ const NotFoundPage: React.FC = ({ title }) => { {title} - - + + Page not found @@ -38,8 +38,8 @@ const NotFoundPage: React.FC = ({ title }) => { Return to main page - - + + ); }; diff --git a/src/pages/categories/categories.tsx b/src/pages/categories/categories.tsx index 676047c..7d9f47f 100644 --- a/src/pages/categories/categories.tsx +++ b/src/pages/categories/categories.tsx @@ -1,10 +1,14 @@ import React from 'react'; import { IPageProps } from '@educt/interfaces'; -import { PageContent, PageHeading, PageWrapper } from '@educt/components/PageElements'; +import { Page } from '@educt/components/PageElements'; import { CategoryTableList, CategoryTableRow } from '@educt/components/Tables/CategoryTableList'; -import { useFetchCategories } from '@educt/hooks/queries'; import LoadingPage from '@educt/components/LoadingPage'; +/** + * Hooks + */ +import { useFetchCategories } from '@educt/hooks/queries'; + /** * Categories page */ @@ -14,12 +18,12 @@ const CategoriesPage: React.FC = () => { if (isLoading || categories === null) return ; return ( - - - + + + - - + + ); }; diff --git a/src/pages/course/course.tsx b/src/pages/course/course.tsx index 3888fb2..38dd412 100644 --- a/src/pages/course/course.tsx +++ b/src/pages/course/course.tsx @@ -15,7 +15,7 @@ import type { IPageProps } from '@educt/interfaces'; * Components */ import { CourseBackgroundImage, CourseHeader, CourseHeading, CourseInfo, LessonItem, LessonList } from '.'; -import { PageWrapper, PageContent } from '@educt/components/PageElements'; +import { Page } from '@educt/components/PageElements'; import LoadingPage from '@educt/components/LoadingPage'; /** @@ -50,7 +50,7 @@ const CoursePage: React.FC = () => { const handleEditCourse = () => history.push(`/courses/edit/${course.id}`); return ( - + {course.title} @@ -64,7 +64,7 @@ const CoursePage: React.FC = () => { /> - + @@ -158,8 +158,8 @@ const CoursePage: React.FC = () => { - - + + ); }; diff --git a/src/pages/courses/courses.tsx b/src/pages/courses/courses.tsx index c678e1d..61ca3ce 100644 --- a/src/pages/courses/courses.tsx +++ b/src/pages/courses/courses.tsx @@ -8,7 +8,7 @@ import { IPageProps } from '@educt/interfaces'; /** * Components */ -import { PageWrapper, PageHeading, PageContent } from '@educt/components/PageElements'; +import { Page } from '@educt/components/PageElements'; import { CreateButton } from '@educt/components/Buttons'; import { Box } from '@chakra-ui/layout'; import LoadingPage from '@educt/components/LoadingPage'; @@ -38,18 +38,18 @@ const CoursesPage: React.FC = () => { if (me === null) return ; return ( - - + + {(me.isAdmin || me.isTeacher) && } - - + + - - + + ); }; diff --git a/src/pages/courses/create-lesson/create-lesson.tsx b/src/pages/courses/create-lesson/create-lesson.tsx index bd19b90..8a95c90 100644 --- a/src/pages/courses/create-lesson/create-lesson.tsx +++ b/src/pages/courses/create-lesson/create-lesson.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { IPageProps } from '@educt/interfaces'; -import { PageContent, PageHeading, PageWrapper } from '@educt/components/PageElements'; +import { Page } from '@educt/components/PageElements'; import CreateLessonForm from '@educt/components/Forms/LessonForm/CreateLessonForm'; import { Redirect, useParams } from 'react-router-dom'; import { useFetchCourse } from '@educt/hooks/queries'; @@ -21,12 +21,12 @@ const CreateLessonPage: React.FC = () => { if (!course || isLoading) return ; return ( - - - + + + - - + + ); }; diff --git a/src/pages/courses/create/create.tsx b/src/pages/courses/create/create.tsx index d0593b7..20f655c 100644 --- a/src/pages/courses/create/create.tsx +++ b/src/pages/courses/create/create.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import { Flex, Box, Heading, Text } from '@chakra-ui/react'; /** * Types @@ -11,23 +10,23 @@ import { IPageProps } from '@educt/interfaces'; */ import PrevPageButton from '@educt/components/PrevPageButton'; import { CreateCourseForm } from '@educt/components/Forms/CourseForm'; -import { PageContent, PageHeading, PageWrapper } from '@educt/components/PageElements'; +import { Page } from '@educt/components/PageElements'; /** * Create course page */ const CreateCoursePage: React.FC = () => { return ( - - + } heading='Course Creation' description='Fill in the required fields to create a new course' /> - + - - + + ); }; diff --git a/src/pages/courses/edit/edit.tsx b/src/pages/courses/edit/edit.tsx index 5f31d85..0bcea87 100644 --- a/src/pages/courses/edit/edit.tsx +++ b/src/pages/courses/edit/edit.tsx @@ -17,7 +17,7 @@ import DeleteCourseDialog from '@educt/components/Dialogs/DeleteCourseDialog'; import PrevPageButton from '@educt/components/PrevPageButton'; import { DeleteButton } from '@educt/components/Buttons'; import { StatusButton } from './components'; -import { PageContent, PageHeading, PageWrapper } from '@educt/components/PageElements'; +import { Page } from '@educt/components/PageElements'; import { StudentTableList, StudentTableRow } from './components/StudentTableList'; import LessonList from './components/LessonList'; @@ -43,13 +43,13 @@ const EditCoursePage: React.FC = () => { if (!course || isLoading) return ; return ( - + Editing {course.title} - } heading='Course editor' description={course.title} @@ -58,8 +58,8 @@ const EditCoursePage: React.FC = () => { - - + + @@ -91,8 +91,8 @@ const EditCoursePage: React.FC = () => { - - + + ); }; diff --git a/src/pages/lesson/lesson.tsx b/src/pages/lesson/lesson.tsx index 3eb9ee9..d78d318 100644 --- a/src/pages/lesson/lesson.tsx +++ b/src/pages/lesson/lesson.tsx @@ -22,7 +22,7 @@ import { import ReactPlayer from 'react-player'; import { MdOutlineCircle, MdCheckCircle, MdOutlineFilePresent, MdSkipNext, MdSkipPrevious } from 'react-icons/md'; import LoadingPage from '@educt/components/LoadingPage'; -import { PageContent, PageHeading, PageWrapper } from '@educt/components/PageElements'; +import { Page } from '@educt/components/PageElements'; /** * Types @@ -138,17 +138,17 @@ const LessonPage: React.FC = () => { if (me === null) return ; return ( - + {lesson.title} - + ~{moment.duration(lesson.duration, 'minutes').humanize()} {(me.isAdmin || me.isTeacher) && } - - + + @@ -270,8 +270,8 @@ const LessonPage: React.FC = () => { - - + + ); }; diff --git a/src/pages/lessons/edit-lesson/edit-lesson.tsx b/src/pages/lessons/edit-lesson/edit-lesson.tsx index e04896f..2d14b3e 100644 --- a/src/pages/lessons/edit-lesson/edit-lesson.tsx +++ b/src/pages/lessons/edit-lesson/edit-lesson.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { IPageProps } from '@educt/interfaces'; -import { PageContent, PageHeading, PageWrapper } from '@educt/components/PageElements'; +import { Page } from '@educt/components/PageElements'; import { Redirect, useParams } from 'react-router-dom'; import LoadingPage from '@educt/components/LoadingPage'; -import { useFetchLesson } from '@educt/hooks/queries/lesson/useFetchLesson'; import EditLessonForm from '@educt/components/Forms/LessonForm/EditLessonForm'; +import { useFetchLesson } from '@educt/hooks/queries/lesson/useFetchLesson'; /** * Create Lesson page @@ -20,12 +20,12 @@ const EditLessonPage: React.FC = () => { if (!lesson || isLoading) return ; return ( - - - + + + - - + + ); }; diff --git a/src/pages/main/components/index.tsx b/src/pages/main/components/index.tsx index d16e58b..585a174 100644 --- a/src/pages/main/components/index.tsx +++ b/src/pages/main/components/index.tsx @@ -34,7 +34,7 @@ export const CourseCard: React.FC = props => = props => ( ); -export const CourseCardTitle: React.FC = props => ; +export const CourseCardTitle: React.FC = props => ; export const CourseCardCategory: React.FC = props => ( diff --git a/src/pages/main/main.tsx b/src/pages/main/main.tsx index 70700e8..ceb9684 100644 --- a/src/pages/main/main.tsx +++ b/src/pages/main/main.tsx @@ -1,8 +1,8 @@ -import React, { useState } from 'react'; +import React from 'react'; import { Flex, Box, Text, Link, SimpleGrid, Divider } from '@chakra-ui/react'; import { Link as ReactRouterLink } from 'react-router-dom'; import { IPageProps } from '@educt/interfaces'; -import { PageContent, PageHeading, PageWrapper } from '@educt/components/PageElements'; +import { Page } from '@educt/components/PageElements'; import { Stat, StatContent, StatIcon, StatLabel, StatNumber } from '@educt/components/Stat'; import { MdOutlineCollectionsBookmark, MdOutlineGroup, MdOutlineMessage, MdOutlineVideoLibrary } from 'react-icons/md'; import { useRootStore } from '@educt/hooks/useRootStore'; @@ -21,9 +21,13 @@ import { CourseCardList, } from './components'; import { observer } from 'mobx-react'; + +/** + * Hooks + */ +import { useEffect, useState } from 'react'; import { useFetchCourses, useFetchStat } from '@educt/hooks/queries'; import { useSocketEvent } from '@educt/hooks/useSocketEvent'; -import { useEffect } from 'react'; /** * Main page @@ -52,9 +56,9 @@ const MainPage: React.FC = () => { if (me === null || courses === null || stat === null) return ; return ( - - - + + + Online @@ -121,8 +125,8 @@ const MainPage: React.FC = () => { - - + + ); }; diff --git a/src/pages/messages/messages.tsx b/src/pages/messages/messages.tsx index ba75b29..b78ffdf 100644 --- a/src/pages/messages/messages.tsx +++ b/src/pages/messages/messages.tsx @@ -1,5 +1,6 @@ import React from 'react'; -import { Box, Heading, Breadcrumb, BreadcrumbItem, BreadcrumbLink, Grid } from '@chakra-ui/react'; +import { Box, Heading } from '@chakra-ui/react'; +import { Page } from '@educt/components/PageElements'; import { IPageProps } from '@educt/interfaces'; @@ -8,9 +9,9 @@ import { IPageProps } from '@educt/interfaces'; */ const MessagesPage: React.FC = () => { return ( - - Messages page - + + + ); }; diff --git a/src/pages/profile/components/index.tsx b/src/pages/profile/components/index.tsx index 1f89cb7..882843c 100644 --- a/src/pages/profile/components/index.tsx +++ b/src/pages/profile/components/index.tsx @@ -69,16 +69,6 @@ export const ProfileDescription: React.FC = props => { ); }; -export const ProfileSignOutButton: React.FC = () => { - const { logout } = useLogout(); - - return ( - - ); -}; - export const ProfileLoading: React.FC = props => { return ( diff --git a/src/pages/profile/profile.tsx b/src/pages/profile/profile.tsx index 286998b..d8bb62f 100644 --- a/src/pages/profile/profile.tsx +++ b/src/pages/profile/profile.tsx @@ -1,6 +1,5 @@ import React from 'react'; import { - Avatar, Tabs, TabList, Tab, @@ -23,8 +22,9 @@ import { IPageProps } from '@educt/interfaces'; /** * Components */ -import { PageHeading, PageContent, PageWrapper, PageFooter } from '@educt/components/PageElements'; -import { ProfileAvatar, ProfileBaseInfo, ProfileDescription, ProfileLoading, ProfileSignOutButton } from './components'; +import { Page } from '@educt/components/PageElements'; +import { ProfileLoading } from './components'; +import { UserProfile } from '@educt/components/UserProfile'; import { CourseList } from './components/CourseList'; import UpdateUserContactsForm from '@educt/pages/profile/components/UpdateUserContactsForm'; @@ -33,6 +33,7 @@ import UpdateUserContactsForm from '@educt/pages/profile/components/UpdateUserCo */ import { useHistory } from 'react-router-dom'; import { useRootStore } from '@educt/hooks/useRootStore'; +import { observer } from 'mobx-react'; /** * Profile page @@ -46,13 +47,17 @@ const ProfilePage: React.FC = () => { if (me === null) return ; return ( - - - - - - - + + + + + + + + + + + Account information @@ -116,12 +121,9 @@ const ProfilePage: React.FC = () => { )} - - - - - + + ); }; -export default ProfilePage; +export default observer(ProfilePage); diff --git a/src/pages/user/user.tsx b/src/pages/user/user.tsx index ec006a8..57fe9fe 100644 --- a/src/pages/user/user.tsx +++ b/src/pages/user/user.tsx @@ -1,7 +1,8 @@ import React from 'react'; +import { observer } from 'mobx-react'; import { Redirect } from 'react-router-dom'; import LoadingPage from '@educt/components/LoadingPage'; -import { PageContent, PageWrapper } from '@educt/components/PageElements'; +import { Page } from '@educt/components/PageElements'; import { UserProfile } from '@educt/components/UserProfile'; import type { IPageProps } from '@educt/interfaces'; @@ -10,18 +11,27 @@ import type { IPageProps } from '@educt/interfaces'; */ import { useParams } from 'react-router-dom'; import { useFetchUser } from '@educt/hooks/queries/user/useFetchUser'; +import { useRootStore } from '@educt/hooks/useRootStore'; const UserPage: React.FC = () => { - const { id } = useParams<{ id: string }>(); - const { data: user, error, isLoading } = useFetchUser(id); + const params = useParams<{ id: string }>(); + const { + userStore: { me }, + } = useRootStore(); + const { data: user, error, isLoading } = useFetchUser(params.id); if (error?.response?.status === 404) return ; - if (user === null || isLoading) return ; + if (user === null || me === null || isLoading) return ; + + /** + * Redirect to profile page + */ + if (me.id === params.id) return ; return ( - - + + @@ -32,9 +42,9 @@ const UserPage: React.FC = () => { - - + + ); }; -export default UserPage; +export default observer(UserPage); diff --git a/src/pages/users/users.tsx b/src/pages/users/users.tsx index 727bf5e..1615720 100644 --- a/src/pages/users/users.tsx +++ b/src/pages/users/users.tsx @@ -8,7 +8,7 @@ import type { IPageProps } from '@educt/interfaces'; /** * Components */ -import { PageContent, PageHeading, PageWrapper } from '@educt/components/PageElements'; +import { Page } from '@educt/components/PageElements'; import { UserList, UserItem } from './components/UserList'; import LoadingPage from '@educt/components/LoadingPage'; @@ -35,12 +35,12 @@ const UsersPage: React.FC = () => { return ( // TODO: delete page context for better performance - - - + + + - - + + ); }; diff --git a/src/stores/UserStore.ts b/src/stores/UserStore.ts index aef29e3..8d7ca7f 100644 --- a/src/stores/UserStore.ts +++ b/src/stores/UserStore.ts @@ -62,10 +62,25 @@ export default class UserStore { public async loadCurrentUserData() { const result = await UserServiceInstance.fetchMe(); const { - data: { id, first_name, last_name, fullname, email, roles, likes, contacts, courses, created_at, updated_at }, + data: { + id, + first_name, + last_name, + fullname, + about, + last_login, + email, + roles, + likes, + contacts, + courses, + created_at, + updated_at, + }, } = result; runInAction(() => { + // TODO Fix this this.me = { id, first_name, @@ -73,6 +88,8 @@ export default class UserStore { email, roles, fullname, + about, + last_login, likes, contacts, courses,