diff --git a/src/App.tsx b/src/App.tsx
index 7c635de..237cb83 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -23,6 +23,8 @@ import PublicRoute from '@educt/components/PublicRoute';
import AuthPage from '@educt/pages/auth/auth';
import NotFoundPage from '@educt/pages/404/404';
import CreateCoursePage from '@educt/pages/courses/create/create';
+import ChangePasswordPage from '@educt/pages/profile/change-password/change-password';
+import ChangeEmailPage from '@educt/pages/profile/change-email/change-email';
const CoursesPage = React.lazy(() => import('@educt/pages/courses/courses'));
const MainPage = React.lazy(() => import('@educt/pages/main/main'));
const MessagesPage = React.lazy(() => import('@educt/pages/messages/messages'));
@@ -46,7 +48,9 @@ const App = () => {
roles={[UserRoleEnum.ADMIN, UserRoleEnum.TEACHER]}
/>
-
+
+
+
{
- const {
- uiStore: { isDesktop },
- } = useRootStore();
+ const [isDesktop] = useMediaQuery('(min-width: 992px)');
const { colorMode } = useColorMode();
return (
@@ -22,7 +28,9 @@ const Header: React.FC = () => {
top={0}
left={0}
right={0}
- borderBottomWidth={1}
+ // borderBottomWidth={1}
+ // h='43px'
+ boxShadow='md'
backgroundColor={colorMode === 'dark' ? 'gray.800' : 'white'}
zIndex={4}
>
diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx
index 4585475..8d28180 100644
--- a/src/components/Layout/Layout.tsx
+++ b/src/components/Layout/Layout.tsx
@@ -44,24 +44,7 @@ const Layout: React.FC = ({ children, roles }) => {
-
+
}>
{(() => {
/**
diff --git a/src/components/Nav/Desktop/index.tsx b/src/components/Nav/Desktop/index.tsx
index 24c2762..02a9e5c 100644
--- a/src/components/Nav/Desktop/index.tsx
+++ b/src/components/Nav/Desktop/index.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { observer } from 'mobx-react';
-import { Flex, Box, useColorMode } from '@chakra-ui/react';
+import { Flex, Box, Text, Link, IconButton } from '@chakra-ui/react';
import config from '@educt/config';
/**
@@ -11,7 +11,8 @@ import NavList from '../NavList';
/**
* Hooks
*/
-import { useRootStore } from '@educt/hooks/useRootStore';
+import { useColorMode, useMediaQuery } from '@chakra-ui/react';
+import { FaGithub } from 'react-icons/fa';
/**
*
@@ -19,14 +20,13 @@ import { useRootStore } from '@educt/hooks/useRootStore';
* Component for navigating the application.
*/
const Nav: React.FC = () => {
- const {
- uiStore: { isDesktop },
- } = useRootStore();
const { colorMode } = useColorMode();
+ const [isDesktop] = useMediaQuery('(min-width: 992px)');
if (isDesktop) {
return (
- {
>
-
+
+
+ Learning Management System
Made by Sergey Yarkov
+
+
+
+
+
+
+
+
+
+
);
}
return null;
diff --git a/src/contexts/index.ts b/src/contexts/index.ts
index cc7afd6..4a1b5e4 100644
--- a/src/contexts/index.ts
+++ b/src/contexts/index.ts
@@ -1,14 +1,14 @@
import { createContext } from 'react';
-import { CoursesPageContextType, ProfilePageContextType, UsersPageContextType } from '@educt/types';
+import { ChangeEmailPageContextType, CoursesPageContextType, UsersPageContextType } from '@educt/types';
import RootStore from '../stores/RootStore';
export const StoreContext = createContext(undefined);
-export const ProfilePageContext = createContext({
- statusPageView: 'default',
- setStatusPageView: () => {},
- pageData: {},
- setPageData: () => {},
+export const ChangeEmailPageContext = createContext({
+ isCodeSent: false,
+ setIsCodeSent: () => {},
+ confirmEmailData: undefined,
+ setConfirmEmailData: () => {},
});
export const UsersPageContext = createContext({
diff --git a/src/pages/courses/components/CourseList/CourseList.tsx b/src/pages/courses/components/CourseList/CourseList.tsx
index 054521c..5fad702 100644
--- a/src/pages/courses/components/CourseList/CourseList.tsx
+++ b/src/pages/courses/components/CourseList/CourseList.tsx
@@ -88,7 +88,7 @@ const CourseList: React.FC = ({ courses, isLoading }) => {
<>
{deletingCourse && }
{courses.length !== 0 ? (
-
+
{/* Render items */}
{courses.map(course => (
diff --git a/src/pages/profile/change-email/change-email.tsx b/src/pages/profile/change-email/change-email.tsx
new file mode 100644
index 0000000..9ebfec1
--- /dev/null
+++ b/src/pages/profile/change-email/change-email.tsx
@@ -0,0 +1,84 @@
+import React from 'react';
+import { Box, Flex, Heading, Text } from '@chakra-ui/layout';
+import { IconButton } from '@chakra-ui/button';
+import { ChevronLeftIcon } from '@chakra-ui/icons';
+
+/**
+ * Types
+ */
+import { IPageProps } from '@educt/interfaces';
+
+/**
+ * Components
+ */
+import LoadingPage from '@educt/components/LoadingPage';
+import UpdateEmailForm from './components/UpdateEmailForm';
+
+/**
+ * Hooks
+ */
+import { useHistory } from 'react-router';
+import { useRootStore } from '@educt/hooks/useRootStore';
+import { observer } from 'mobx-react';
+
+/**
+ * Providers
+ */
+import { ChangeEmailPageContextProvider } from '@educt/providers';
+import { ChangeEmailPageContext } from '@educt/contexts';
+import ConfirmEmailContainer from './containers/ConfirmEmailContainer';
+
+{
+ /* <>
+ {!isCodeSent ? (
+
+ ) : (
+ confirmEmailData &&
+ )}
+ > */
+}
+
+/**
+ * Change email page
+ */
+const ChangeEmailPage: React.FC = () => {
+ const {
+ userStore: { me },
+ } = useRootStore();
+ const history = useHistory();
+
+ if (me === null) return ;
+
+ return (
+
+
+ {({ isCodeSent, confirmEmailData }) => (
+ <>
+ {!isCodeSent ? (
+
+
+ }
+ onClick={() => history.push('/profile')}
+ mr='5'
+ />
+ Edit email address
+
+
+ Type your new email address.
+
+
+
+ ) : (
+ confirmEmailData &&
+ )}
+ >
+ )}
+
+
+ );
+};
+
+export default observer(ChangeEmailPage);
diff --git a/src/pages/profile/containers/UpdateEmailContainer/UpdateEmailForm/UpdateEmailForm.tsx b/src/pages/profile/change-email/components/UpdateEmailForm/UpdateEmailForm.tsx
similarity index 60%
rename from src/pages/profile/containers/UpdateEmailContainer/UpdateEmailForm/UpdateEmailForm.tsx
rename to src/pages/profile/change-email/components/UpdateEmailForm/UpdateEmailForm.tsx
index 5e9aaa8..6cc11ad 100644
--- a/src/pages/profile/containers/UpdateEmailContainer/UpdateEmailForm/UpdateEmailForm.tsx
+++ b/src/pages/profile/change-email/components/UpdateEmailForm/UpdateEmailForm.tsx
@@ -1,26 +1,46 @@
+import React from 'react';
import { Button } from '@chakra-ui/button';
import { FormControl, FormHelperText, FormLabel } from '@chakra-ui/form-control';
import { Input } from '@chakra-ui/input';
import { Box, Stack } from '@chakra-ui/layout';
import { yupResolver } from '@hookform/resolvers/yup';
-import { ProfilePageContext } from '@educt/contexts';
-import { useRootStore } from '@educt/hooks/useRootStore';
+
+/**
+ * Types
+ */
+import type { SubmitHandler } from 'react-hook-form';
+
+/**
+ * Hooks
+ */
+import { useContext, useEffect, useState } from 'react';
+import { useForm } from 'react-hook-form';
import useUpdateUserEmailQuery from '@educt/hooks/useUpdateUserEmailQuery.ts';
-import React, { useContext, useEffect, useState } from 'react';
-import { SubmitHandler, useForm } from 'react-hook-form';
+
+/**
+ * Contexts
+ */
+import { ChangeEmailPageContext } from '@educt/contexts';
+
+/**
+ * Schema
+ */
import UpdateEmailSchema from './UpdateEmailForm.validator';
type UpdateEmailInputType = {
email: string;
};
+type UpdateEmailFormPropsType = {
+ currentEmail: string;
+};
+
/**
- * Update email using form
+ * Send confirmation code before change email using form
*/
-const UpdateEmailForm: React.FC = () => {
- const [email, setEmail] = useState(null);
- const { setStatusPageView, setPageData } = useContext(ProfilePageContext);
- const { userStore } = useRootStore();
+const UpdateEmailForm: React.FC = ({ currentEmail }) => {
+ const [newEmail, setNewEmail] = useState(null);
+ const { setIsCodeSent, setConfirmEmailData } = useContext(ChangeEmailPageContext);
const { sendConfirmationCode, loading, result } = useUpdateUserEmailQuery();
const {
handleSubmit,
@@ -30,16 +50,25 @@ const UpdateEmailForm: React.FC = () => {
resolver: yupResolver(UpdateEmailSchema),
});
+ /**
+ * Change page view in confirmation code has been sent
+ */
useEffect(() => {
- if (email !== null && result !== null) {
- setStatusPageView('confirm-email');
- setPageData({ confirmEmailData: { newEmail: email, expired_seconds: result.data.expired_seconds } });
+ if (newEmail !== null && result !== null) {
+ setIsCodeSent(true);
+ setConfirmEmailData({ newEmail, expired_seconds: result.data.expired_seconds });
}
- });
+ }, [result]);
- const onSubmit: SubmitHandler = ({ email }) => {
- setEmail(email);
- sendConfirmationCode(email);
+ /**
+ * Submit form handler
+ */
+ const onSubmit: SubmitHandler = async ({ email }) => {
+ /**
+ * Set new email state and send confirmation code
+ */
+ setNewEmail(email);
+ await sendConfirmationCode(email);
};
return (
@@ -48,7 +77,7 @@ const UpdateEmailForm: React.FC = () => {
Current email
-
+
New email
diff --git a/src/pages/profile/containers/UpdateEmailContainer/UpdateEmailForm/UpdateEmailForm.validator.ts b/src/pages/profile/change-email/components/UpdateEmailForm/UpdateEmailForm.validator.ts
similarity index 100%
rename from src/pages/profile/containers/UpdateEmailContainer/UpdateEmailForm/UpdateEmailForm.validator.ts
rename to src/pages/profile/change-email/components/UpdateEmailForm/UpdateEmailForm.validator.ts
diff --git a/src/pages/profile/containers/UpdateEmailContainer/UpdateEmailForm/index.ts b/src/pages/profile/change-email/components/UpdateEmailForm/index.ts
similarity index 100%
rename from src/pages/profile/containers/UpdateEmailContainer/UpdateEmailForm/index.ts
rename to src/pages/profile/change-email/components/UpdateEmailForm/index.ts
diff --git a/src/pages/profile/containers/ConfirmEmailContainer/ConfirmEmailContainer.tsx b/src/pages/profile/change-email/containers/ConfirmEmailContainer/ConfirmEmailContainer.tsx
similarity index 93%
rename from src/pages/profile/containers/ConfirmEmailContainer/ConfirmEmailContainer.tsx
rename to src/pages/profile/change-email/containers/ConfirmEmailContainer/ConfirmEmailContainer.tsx
index 5efc44f..693c418 100644
--- a/src/pages/profile/containers/ConfirmEmailContainer/ConfirmEmailContainer.tsx
+++ b/src/pages/profile/change-email/containers/ConfirmEmailContainer/ConfirmEmailContainer.tsx
@@ -1,22 +1,30 @@
-import React, { useContext, useEffect, useState } from 'react';
+import React from 'react';
import { PinInput, PinInputField } from '@chakra-ui/react';
import { Button } from '@chakra-ui/button';
import { Box, Flex, Heading, HStack, Text } from '@chakra-ui/layout';
-import { ConfirmEmailContainerDataType } from '@educt/types';
+
+/**
+ * Types
+ */
+import { ConfirmEmailDataType } from '@educt/types';
+
+/**
+ * Hooks
+ */
+import { useEffect, useState } from 'react';
import useUpdateUserEmailQuery from '@educt/hooks/useUpdateUserEmailQuery.ts';
+import useIsMountedRef from '@educt/hooks/useIsMountedRef';
import { useRootStore } from '@educt/hooks/useRootStore';
import { useToast } from '@chakra-ui/toast';
import { useErrorHandler } from 'react-error-boundary';
-import { ProfilePageContext } from '@educt/contexts';
-import useIsMountedRef from '@educt/hooks/useIsMountedRef';
+import { useHistory } from 'react-router';
type ConfirmEmailContainerPropsType = {
- data: ConfirmEmailContainerDataType;
+ data: ConfirmEmailDataType;
};
const ConfirmEmailContainer: React.FC = ({ data }) => {
const { userStore } = useRootStore();
- const { setStatusPageView } = useContext(ProfilePageContext);
const { sendConfirmationCode, loading } = useUpdateUserEmailQuery();
const [isVerifying, setIsVerifying] = useState(false);
const [code, setCode] = useState('');
@@ -24,6 +32,7 @@ const ConfirmEmailContainer: React.FC = ({ data
const isMountedRef = useIsMountedRef();
const toast = useToast();
const handleError = useErrorHandler();
+ const history = useHistory();
useEffect(() => {
const interval = window.setInterval(() => {
@@ -47,7 +56,7 @@ const ConfirmEmailContainer: React.FC = ({ data
status: 'info',
});
if (isMountedRef.current) {
- setStatusPageView('default');
+ history.push('/profile');
}
} catch (error: any) {
if (error.response) {
diff --git a/src/pages/profile/containers/ConfirmEmailContainer/index.ts b/src/pages/profile/change-email/containers/ConfirmEmailContainer/index.ts
similarity index 100%
rename from src/pages/profile/containers/ConfirmEmailContainer/index.ts
rename to src/pages/profile/change-email/containers/ConfirmEmailContainer/index.ts
diff --git a/src/pages/profile/change-password/change-password.tsx b/src/pages/profile/change-password/change-password.tsx
new file mode 100644
index 0000000..d159591
--- /dev/null
+++ b/src/pages/profile/change-password/change-password.tsx
@@ -0,0 +1,54 @@
+import React from 'react';
+import { Box, Heading, Flex, Text, IconButton } from '@chakra-ui/react';
+import { ChevronLeftIcon } from '@chakra-ui/icons';
+
+/**
+ * Types
+ */
+import { IPageProps } from '@educt/interfaces';
+
+/**
+ * Components
+ */
+import UpdatePasswordForm from './components/UpdatePasswordForm';
+
+/**
+ * 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
+ */
+const ChangePasswordPage: React.FC = () => {
+ const {
+ userStore: { me },
+ } = useRootStore();
+ const history = useHistory();
+
+ if (me === null) return ;
+
+ return (
+
+
+ }
+ onClick={() => history.push('/profile')}
+ mr='5'
+ />
+ Update password
+
+
+ Your new password must be different from the current one.
+
+
+
+ );
+};
+
+export default observer(ChangePasswordPage);
diff --git a/src/pages/profile/containers/UpdatePasswordContainer/UpdatePasswordForm/UpdatePasswordForm.tsx b/src/pages/profile/change-password/components/UpdatePasswordForm/UpdatePasswordForm.tsx
similarity index 83%
rename from src/pages/profile/containers/UpdatePasswordContainer/UpdatePasswordForm/UpdatePasswordForm.tsx
rename to src/pages/profile/change-password/components/UpdatePasswordForm/UpdatePasswordForm.tsx
index 3fbec06..4acb56b 100644
--- a/src/pages/profile/containers/UpdatePasswordContainer/UpdatePasswordForm/UpdatePasswordForm.tsx
+++ b/src/pages/profile/change-password/components/UpdatePasswordForm/UpdatePasswordForm.tsx
@@ -1,16 +1,30 @@
-import React, { useContext, useState } from 'react';
-import { useRootStore } from '@educt/hooks/useRootStore';
+import React from 'react';
import { Box, Stack } from '@chakra-ui/layout';
import { FormControl, FormLabel, FormHelperText } from '@chakra-ui/form-control';
import { Button } from '@chakra-ui/button';
import { Input } from '@chakra-ui/input';
-import { SubmitHandler, useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
-import UpdatePasswordSchema from './UpdatePasswordForm.validator';
-import { useToast } from '@chakra-ui/toast';
+
+/**
+ * Types
+ */
+import type { SubmitHandler } from 'react-hook-form';
+
+/**
+ * Hooks
+ */
+import { useState } from 'react';
+import { useHistory } from 'react-router';
+import { useForm } from 'react-hook-form';
import { useErrorHandler } from 'react-error-boundary';
-import { ProfilePageContext } from '@educt/contexts';
+import { useRootStore } from '@educt/hooks/useRootStore';
import useIsMountedRef from '@educt/hooks/useIsMountedRef';
+import { useToast } from '@chakra-ui/toast';
+
+/**
+ * Schema
+ */
+import UpdatePasswordSchema from './UpdatePasswordForm.validator';
type UpdatePasswordInputType = {
old_password: string;
@@ -22,10 +36,9 @@ type UpdatePasswordInputType = {
* Update password using form
*/
const UpdatePasswordForm: React.FC = () => {
- const { setStatusPageView } = useContext(ProfilePageContext);
const { userStore } = useRootStore();
const isMountedRef = useIsMountedRef();
- const [loading, setLoading] = useState(false);
+ const [isLoading, setIsLoading] = useState(false);
const {
handleSubmit,
register,
@@ -35,19 +48,25 @@ const UpdatePasswordForm: React.FC = () => {
} = useForm({
resolver: yupResolver(UpdatePasswordSchema),
});
-
+ const history = useHistory();
const toast = useToast();
const handleError = useErrorHandler();
+ /**
+ * Submit form handler
+ */
const onSubmit: SubmitHandler = async ({ old_password, new_password, confirm_password }) => {
try {
- setLoading(true);
+ setIsLoading(true);
await userStore.updateCurrentUserPassword(old_password, new_password);
toast({ title: 'Password changed.', status: 'success' });
reset();
- setStatusPageView('default');
+ history.push('/profile');
} catch (error: any) {
if (error.response) {
+ /**
+ * Invalid current password handler
+ */
if (error.response.status === 401) {
toast({ title: 'Invalid current password.', status: 'error', duration: 2000 });
reset({ old_password: '', new_password, confirm_password });
@@ -60,7 +79,7 @@ const UpdatePasswordForm: React.FC = () => {
}
} finally {
if (isMountedRef.current) {
- setLoading(false);
+ setIsLoading(false);
}
}
};
@@ -76,7 +95,7 @@ const UpdatePasswordForm: React.FC = () => {
size='md'
variant='filled'
placeholder='*******'
- isInvalid={errors.old_password ? true : false}
+ isInvalid={!!errors.old_password}
{...register('old_password')}
/>
Type your current password.
@@ -88,7 +107,7 @@ const UpdatePasswordForm: React.FC = () => {
size='md'
variant='filled'
placeholder='*******'
- isInvalid={errors.new_password ? true : false}
+ isInvalid={!!errors.new_password}
{...register('new_password')}
/>
@@ -102,7 +121,7 @@ const UpdatePasswordForm: React.FC = () => {
size='md'
variant='filled'
placeholder='*******'
- isInvalid={errors.confirm_password ? true : false}
+ isInvalid={!!errors.confirm_password}
{...register('confirm_password')}
/>
@@ -116,7 +135,7 @@ const UpdatePasswordForm: React.FC = () => {
type='submit'
size='md'
variant='outline'
- isLoading={loading}
+ isLoading={isLoading}
loadingText='Saving...'
>
Change
diff --git a/src/pages/profile/containers/UpdatePasswordContainer/UpdatePasswordForm/UpdatePasswordForm.validator.ts b/src/pages/profile/change-password/components/UpdatePasswordForm/UpdatePasswordForm.validator.ts
similarity index 100%
rename from src/pages/profile/containers/UpdatePasswordContainer/UpdatePasswordForm/UpdatePasswordForm.validator.ts
rename to src/pages/profile/change-password/components/UpdatePasswordForm/UpdatePasswordForm.validator.ts
diff --git a/src/pages/profile/containers/UpdatePasswordContainer/UpdatePasswordForm/index.ts b/src/pages/profile/change-password/components/UpdatePasswordForm/index.ts
similarity index 100%
rename from src/pages/profile/containers/UpdatePasswordContainer/UpdatePasswordForm/index.ts
rename to src/pages/profile/change-password/components/UpdatePasswordForm/index.ts
diff --git a/src/pages/profile/components/CourseList/CourseItem.tsx b/src/pages/profile/components/CourseList/CourseItem.tsx
index c15a3fb..d2dc475 100644
--- a/src/pages/profile/components/CourseList/CourseItem.tsx
+++ b/src/pages/profile/components/CourseList/CourseItem.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { Link as ReactRouterLink } from 'react-router-dom';
-import { Tag, TagLabel } from '@chakra-ui/react';
+import { Tag, TagLabel, LinkBox, Heading, LinkOverlay } from '@chakra-ui/react';
import { Text, Link, Box, Flex } from '@chakra-ui/layout';
import { MdVideoLibrary, MdGroup, MdThumbUp } from 'react-icons/md';
@@ -15,24 +15,12 @@ type CourseItemPropsType = {
const CourseItem: React.FC = ({ course }) => {
return (
-
-
- {course.category.title}
-
-
-
- {course.title}
-
-
+
+
+ {course.title}
+
{course.description}
-
+
{course.lessons_count} lessons
@@ -46,7 +34,40 @@ const CourseItem: React.FC = ({ course }) => {
{course.likes_count} likes
-
+
+
+ //
+ //
+ // {course.category.title}
+ //
+ //
+ //
+ // {course.title}
+ //
+ //
+ // {course.description}
+ //
+ //
+ //
+ // {course.lessons_count} lessons
+ //
+ //
+ //
+ // {course.students_count} students
+ //
+ //
+ //
+ // {course.likes_count} likes
+ //
+ //
+ //
);
};
diff --git a/src/pages/profile/components/CourseList/CourseList.tsx b/src/pages/profile/components/CourseList/CourseList.tsx
index 97db274..26ea9ee 100644
--- a/src/pages/profile/components/CourseList/CourseList.tsx
+++ b/src/pages/profile/components/CourseList/CourseList.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { Box, Text, Flex } from '@chakra-ui/layout';
+import { Box, Text, Flex, Stack } from '@chakra-ui/layout';
/**
* Types
@@ -16,9 +16,7 @@ type CourseListPropsType = {
};
const CourseList: React.FC = ({ courses }) => {
- if (courses === undefined) {
- return null;
- }
+ if (courses === undefined) return null;
if (courses.length === 0) {
return (
@@ -31,7 +29,7 @@ const CourseList: React.FC = ({ courses }) => {
}
return (
-
+
{courses.map(course => (
))}
diff --git a/src/pages/profile/components/UserAccountInfo/UserAccountInfo.tsx b/src/pages/profile/components/UserAccountInfo/UserAccountInfo.tsx
deleted file mode 100644
index 672a2af..0000000
--- a/src/pages/profile/components/UserAccountInfo/UserAccountInfo.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import React from 'react';
-import { Box, Heading, Stack, Flex, StackDivider, Text, Button } from '@chakra-ui/react';
-
-/**
- * Types
- */
-import { IUser } from '@educt/interfaces';
-
-/**
- * Contexts
- */
-import { ProfilePageContext } from '@educt/contexts';
-
-/**
- * Hooks
- */
-import { useContext } from 'react';
-
-type UserAccountInfoPropsType = {
- user: IUser;
-};
-
-const UserAccountInfo: React.FC = ({ user }) => {
- const { setStatusPageView } = useContext(ProfilePageContext);
-
- return (
-
- }>
-
-
-
- First Name
-
-
- {user.first_name}
-
-
-
-
-
-
- Last Name
-
-
- {user.last_name}
-
-
-
-
-
-
- Email
-
-
- {user.email}
-
-
-
-
-
-
-
- Password
-
-
- **********
-
-
-
-
-
-
- );
-};
-
-export default UserAccountInfo;
diff --git a/src/pages/profile/components/UserAccountInfo/index.ts b/src/pages/profile/components/UserAccountInfo/index.ts
deleted file mode 100644
index 53711b5..0000000
--- a/src/pages/profile/components/UserAccountInfo/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import UserAccountInfo from './UserAccountInfo';
-
-export default UserAccountInfo;
diff --git a/src/pages/profile/containers/MainContainer/MainContainer.tsx b/src/pages/profile/containers/MainContainer/MainContainer.tsx
deleted file mode 100644
index a3faa31..0000000
--- a/src/pages/profile/containers/MainContainer/MainContainer.tsx
+++ /dev/null
@@ -1,82 +0,0 @@
-import React from 'react';
-import { Box, Heading, Flex, Avatar, Text, Tabs, TabList, Tab, TabPanels, TabPanel, Button } from '@chakra-ui/react';
-
-/**
- * Components
- */
-import UserBadge from '@educt/components/UserBadge';
-import UserAccountInfo from '@educt/pages/profile/components/UserAccountInfo';
-import UpdateUserContactsForm from '@educt/pages/profile/components/UpdateUserContactsForm';
-import CourseList from '@educt/pages/profile/components/CourseList';
-
-/**
- * Hooks
- */
-import useLogoutQuery from '@educt/hooks/useLogoutQuery';
-import { useRootStore } from '@educt/hooks/useRootStore';
-import { useColorMode } from '@chakra-ui/color-mode';
-
-const MainContainer: React.FC = () => {
- const {
- userStore: { me },
- } = useRootStore();
- const { colorMode } = useColorMode();
- const { logout } = useLogoutQuery();
-
- if (me === null) return null;
-
- return (
-
- My account
- Update you contacts information or password here.
-
-
-
-
-
- {me.fullname}
-
-
- {me.email}
-
-
-
-
-
-
-
-
- Account information
- My contacts
- {me.isStudent && Available courses}
-
-
-
-
-
-
-
-
- {me.isStudent && (
-
-
-
- )}
-
-
-
-
-
-
-
- );
-};
-
-export default MainContainer;
diff --git a/src/pages/profile/containers/MainContainer/index.ts b/src/pages/profile/containers/MainContainer/index.ts
deleted file mode 100644
index 416f536..0000000
--- a/src/pages/profile/containers/MainContainer/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import MainContainer from './MainContainer';
-
-export default MainContainer;
diff --git a/src/pages/profile/containers/UpdateEmailContainer/UpdateEmailContainer.tsx b/src/pages/profile/containers/UpdateEmailContainer/UpdateEmailContainer.tsx
deleted file mode 100644
index d86108c..0000000
--- a/src/pages/profile/containers/UpdateEmailContainer/UpdateEmailContainer.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import { IconButton } from '@chakra-ui/button';
-import { ChevronLeftIcon } from '@chakra-ui/icons';
-import { Box, Flex, Heading, Text } from '@chakra-ui/layout';
-import { ProfilePageContext } from '@educt/contexts';
-import React, { useContext } from 'react';
-import UpdateEmailForm from './UpdateEmailForm';
-
-const UpdateEmailContainer: React.FC = () => {
- const { setStatusPageView } = useContext(ProfilePageContext);
-
- return (
-
-
- }
- onClick={() => setStatusPageView('default')}
- mr='5'
- />
- Edit email address
-
-
- Type your new email address.
-
-
-
- );
-};
-
-export default UpdateEmailContainer;
diff --git a/src/pages/profile/containers/UpdateEmailContainer/index.ts b/src/pages/profile/containers/UpdateEmailContainer/index.ts
deleted file mode 100644
index 818243b..0000000
--- a/src/pages/profile/containers/UpdateEmailContainer/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import UpdateEmailContainer from './UpdateEmailContainer';
-
-export default UpdateEmailContainer;
diff --git a/src/pages/profile/containers/UpdatePasswordContainer/UpdatePasswordContainer.tsx b/src/pages/profile/containers/UpdatePasswordContainer/UpdatePasswordContainer.tsx
deleted file mode 100644
index 21d18e2..0000000
--- a/src/pages/profile/containers/UpdatePasswordContainer/UpdatePasswordContainer.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import React, { useContext } from 'react';
-import { Box, Heading, Flex, Text, IconButton } from '@chakra-ui/react';
-import { ChevronLeftIcon } from '@chakra-ui/icons';
-import { ProfilePageContext } from '@educt/contexts';
-import UpdatePasswordForm from './UpdatePasswordForm';
-
-const UpdatePasswordContainer: React.FC = () => {
- const { setStatusPageView } = useContext(ProfilePageContext);
-
- return (
-
-
- }
- onClick={() => setStatusPageView('default')}
- mr='5'
- />
- Update password
-
-
- Your new password must be different from the current one.
-
-
-
- );
-};
-
-export default UpdatePasswordContainer;
diff --git a/src/pages/profile/containers/UpdatePasswordContainer/index.ts b/src/pages/profile/containers/UpdatePasswordContainer/index.ts
deleted file mode 100644
index 37feee6..0000000
--- a/src/pages/profile/containers/UpdatePasswordContainer/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import UpdatePasswordContainer from './UpdatePasswordContainer';
-
-export default UpdatePasswordContainer;
diff --git a/src/pages/profile/profile.tsx b/src/pages/profile/profile.tsx
index 6d4a7b0..a8de10f 100644
--- a/src/pages/profile/profile.tsx
+++ b/src/pages/profile/profile.tsx
@@ -1,5 +1,7 @@
import React from 'react';
import { observer } from 'mobx-react';
+import { Avatar, Tabs, TabList, Tab, TabPanels, TabPanel, Button } from '@chakra-ui/react';
+import { Box, Flex, Heading, Text, Stack, StackDivider } from '@chakra-ui/layout';
/**
* Types
@@ -10,31 +12,17 @@ import { IPageProps } from '@educt/interfaces';
* Components
*/
import LoadingPage from './components/LoadingPage';
-
-/**
- * Containers
- */
-import MainContainer from './containers/MainContainer';
-import UpdatePasswordContainer from './containers/UpdatePasswordContainer';
-import UpdateEmailContainer from './containers/UpdateEmailContainer';
-import ConfirmEmailContainer from './containers/ConfirmEmailContainer';
+import UserBadge from '@educt/components/UserBadge';
+import UpdateUserContactsForm from '@educt/pages/profile/components/UpdateUserContactsForm';
+import CourseList from '@educt/pages/profile/components/CourseList';
/**
* Hooks
*/
-import { useEffect } from 'react';
-import { useRootStore } from '@educt/hooks/useRootStore';
import { useHistory } from 'react-router-dom';
-
-/**
- * Contexts
- */
-import { ProfilePageContext } from '@educt/contexts';
-
-/**
- * Providers
- */
-import { ProfilePageContextProvider } from '@educt/providers';
+import { useColorMode } from '@chakra-ui/color-mode';
+import { useRootStore } from '@educt/hooks/useRootStore';
+import useLogoutQuery from '@educt/hooks/useLogoutQuery';
/**
* Profile page
@@ -42,39 +30,109 @@ import { ProfilePageContextProvider } from '@educt/providers';
const ProfilePage: React.FC = () => {
const {
userStore: { me },
- authStore,
} = useRootStore();
const history = useHistory();
+ const { logout } = useLogoutQuery();
+ const { colorMode } = useColorMode();
- useEffect(() => {
- if (!authStore.isLoggedIn) {
- history.push('/auth');
- }
- });
-
- if (me === null) {
- return ;
- }
+ if (me === null) return ;
return (
-
-
- {({ statusPageView, pageData }) => {
- switch (statusPageView) {
- case 'default':
- return ;
- case 'update-password':
- return ;
- case 'update-email':
- return ;
- case 'confirm-email':
- return pageData.confirmEmailData && ;
- default:
- return null;
- }
- }}
-
-
+
+ My account
+ Update you contacts information or password here.
+
+
+
+
+
+ {me.fullname}
+
+
+ {me.email}
+
+
+
+
+
+
+
+
+ Account information
+ My contacts
+ {me.isStudent && Available courses}
+
+
+
+
+ }>
+
+
+
+ First Name
+
+
+ {me.first_name}
+
+
+
+
+
+
+ Last Name
+
+
+ {me.last_name}
+
+
+
+
+
+
+ Email
+
+
+ {me.email}
+
+
+
+
+
+
+
+ Password
+
+
+ **********
+
+
+
+
+
+
+
+
+
+
+ {me.isStudent && (
+
+
+
+ )}
+
+
+
+
+
+
+
);
};
diff --git a/src/providers/index.tsx b/src/providers/index.tsx
index 38bba7b..8ebcc45 100644
--- a/src/providers/index.tsx
+++ b/src/providers/index.tsx
@@ -1,11 +1,6 @@
import React, { useState, ReactNode } from 'react';
-import { CoursesPageContext, ProfilePageContext, StoreContext, UsersPageContext } from '@educt/contexts';
-import {
- CoursesPageContextType,
- ProfilePageDataType,
- ProfilePageStatusType,
- SearchingRoleStateType,
-} from '@educt/types';
+import { ChangeEmailPageContext, CoursesPageContext, StoreContext, UsersPageContext } from '@educt/contexts';
+import { ConfirmEmailDataType, SearchingRoleStateType } from '@educt/types';
import RootStore from '@educt/stores/RootStore';
import { ICategory, ICourse, IUser } from '@educt/interfaces';
import { CourseStatusEnum } from '@educt/enums';
@@ -20,16 +15,16 @@ export const RootStoreProvider = ({ children }: { children: ReactNode }) => {
};
/**
- * Profile page context provider
+ * Change email page context provider
*/
-export const ProfilePageContextProvider: React.FC = ({ children }) => {
- const [statusPageView, setStatusPageView] = useState('default');
- const [pageData, setPageData] = useState({});
+export const ChangeEmailPageContextProvider: React.FC = ({ children }) => {
+ const [isCodeSent, setIsCodeSent] = useState(false);
+ const [confirmEmailData, setConfirmEmailData] = useState(undefined);
return (
-
+
{children}
-
+
);
};
diff --git a/src/types/index.d.ts b/src/types/index.d.ts
index 19674b8..625c7e1 100644
--- a/src/types/index.d.ts
+++ b/src/types/index.d.ts
@@ -1,6 +1,6 @@
+import React from 'react';
import { CourseStatusEnum, UserRoleEnum } from '@educt/enums';
import { ICategory, ICourse, IUser } from '@educt/interfaces';
-import React from 'react';
import { IconType } from 'react-icons/lib';
export type LinkType = {
@@ -23,35 +23,32 @@ export type AttachmentFileType = {
extname: string;
};
-export type ConfirmEmailContainerDataType = {
- newEmail: string;
- expired_seconds: number;
-};
-
export type OptionType = {
value: string;
label: string;
};
-export type ProfilePageStatusType = 'update-password' | 'update-email' | 'confirm-email' | 'default';
-export type ProfilePageDataType = {
- /**
- * The field that is set when trying to change the mail address through form
- */
- confirmEmailData?: ConfirmEmailContainerDataType;
+export type ConfirmEmailContainerDataType = {
+ newEmail: string;
+ expired_seconds: number;
};
-export type ProfilePageContextType = {
- /**
- * Render current container by status
- */
- statusPageView: ProfilePageStatusType;
- setStatusPageView: React.Dispatch>;
+
+/**
+ * Change email page context
+ */
+export type ConfirmEmailDataType = {
+ newEmail: string;
+ expired_seconds: number;
+};
+export type ChangeEmailPageContextType = {
+ isCodeSent: boolean;
+ setIsCodeSent: React.Dispatch>;
/**
- * Some data for other components
+ * Set this data when confirmation code has been sent
*/
- pageData: ProfilePageDataType;
- setPageData: React.Dispatch>;
+ confirmEmailData?: ConfirmEmailDataType;
+ setConfirmEmailData: React.Dispatch>;
};
export type SearchingRoleStateType = UserRoleEnum | 'any' | undefined;