From 40b06ca270e8d54daa489b16b433d6c10b12e042 Mon Sep 17 00:00:00 2001 From: Amir Movahedi Date: Mon, 17 May 2021 20:37:09 +0700 Subject: [PATCH] fix: navigate invalid sub route to not found page #41 Signed-off-by: Amir Movahedi --- public/locales/translations/enjson_en.json | 7 +++ src/components/about/index.tsx | 2 +- src/constants/userActionType.ts | 1 + src/containers/profile/IProfileProps.ts | 8 --- src/containers/profile/index.tsx | 3 +- .../services/circles/UserTieService.ts | 11 ++-- .../services/users/UserService.ts | 4 +- src/pages/notFound/index.tsx | 53 +++++++++++++++++++ src/routes/index.tsx | 19 ++++--- src/store/actions/userActions.ts | 11 ++++ src/store/sagas/userSaga.ts | 15 ++++++ 11 files changed, 109 insertions(+), 25 deletions(-) delete mode 100644 src/containers/profile/IProfileProps.ts create mode 100644 src/pages/notFound/index.tsx diff --git a/public/locales/translations/enjson_en.json b/public/locales/translations/enjson_en.json index b0cdc2c..42eb7ce 100644 --- a/public/locales/translations/enjson_en.json +++ b/public/locales/translations/enjson_en.json @@ -428,6 +428,13 @@ }, "support": { "content": "### Support \nFor general questions the best place is our community in [Slack](https://docs.google.com/forms/d/e/1FAIpQLSdkwt5pxmyCZQO0AmyAghBOdA-XBG298Pfm5Dw1xjNGaGeCYQ/viewform). The [Slack](https://docs.google.com/forms/d/e/1FAIpQLSdkwt5pxmyCZQO0AmyAghBOdA-XBG298Pfm5Dw1xjNGaGeCYQ/viewform) community is the place for questions and advice about [Telar Social](https://telar.dev) project. If you are not sure where to aks, we will guide you to the right place. \n\nTo request technical support, reporting a bug or want a new feature, [Github](https://github.com/red-gold/ts-ui/issues) is the right place to track. Please make sure to add as many information as possible, in order for us to reproduce your issue. \n\nCustomers who purchased Sky plan or Enterprise plan are in high priority for thechnical support. You are always welcome to ask for feature requests and give suggestions that can improve this project. \n\n\nCheers, \nThe Telar team" + }, + "notFound": { + "header": "04 | \"{{appName}}\"", + "title": "404: The page you are looking for isn’t here", + "description": "You either tried some shady route or you came here by mistake. Whichever it is, try using the navigation", + "homeButton": "Back to home" + } diff --git a/src/components/about/index.tsx b/src/components/about/index.tsx index 2a5310d..887c912 100644 --- a/src/components/about/index.tsx +++ b/src/components/about/index.tsx @@ -12,10 +12,10 @@ import * as userActions from 'store/actions/userActions'; import { useTranslation } from 'react-i18next'; import { useStyles } from './peopleBoxStyles'; import { IAboutProps } from './IAboutProps'; -import { experimentalStyled as styled } from '@material-ui/core/styles'; import moment from 'moment/moment'; import { Link } from '@material-ui/core'; import { SocialIcon } from 'react-social-icons'; +import { experimentalStyled as styled } from '@material-ui/core/styles'; const ProfileItem = styled('div')({ display: 'flex', diff --git a/src/constants/userActionType.ts b/src/constants/userActionType.ts index 09b47a4..1aec5d4 100644 --- a/src/constants/userActionType.ts +++ b/src/constants/userActionType.ts @@ -38,6 +38,7 @@ export enum UserActionType { DB_FETCH_USER_SEARCH = 'DB_FETCH_USER_SEARCH', DB_FETCH_USER_SUGGESTIONS = 'DB_FETCH_USER_SUGGESTIONS', DB_FETCH_USER_PROFILE_BY_ID = 'DB_FETCH_USER_PROFILE_BY_ID', + GET_USER_PROFILE_PAGE = 'GET_USER_PROFILE_PAGE', INCREASE_SHARE_COUNT_USER = 'INCREASE_SHARE_COUNT_USER', DECREASE_SHARE_COUNT_USER = 'DECREASE_SHARE_COUNT_USER', INCREASE_FOLLOWING_COUNT_USER = 'INCREASE_FOLLOWING_COUNT_USER', diff --git a/src/containers/profile/IProfileProps.ts b/src/containers/profile/IProfileProps.ts deleted file mode 100644 index 0f82519..0000000 --- a/src/containers/profile/IProfileProps.ts +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2021 Amirhossein Movahedi (@qolzam) -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -export interface IProfileProps { - profile: Map; -} diff --git a/src/containers/profile/index.tsx b/src/containers/profile/index.tsx index f7d488d..142e7f3 100644 --- a/src/containers/profile/index.tsx +++ b/src/containers/profile/index.tsx @@ -36,10 +36,11 @@ export function ProfileComponent() { const location = useLocation(); const { userId } = useParams(); const classes = useStyles(); + // Dispatcher const dispatch = useDispatch(); const loadPosts = (page: number) => dispatch(postActions.dbGetPostsByUserId(userId, page)); - const loadUserInfo = () => dispatch(userActions.dbGetUserInfoByUserId(userId)); + const loadUserInfo = () => dispatch(userActions.getUserProfilePage(userId)); const setHeaderTitle = (title: string) => dispatch(globalActions.setHeaderTitle(title)); // Selectors diff --git a/src/data/openFaaSClient/services/circles/UserTieService.ts b/src/data/openFaaSClient/services/circles/UserTieService.ts index 0833540..29a5e13 100644 --- a/src/data/openFaaSClient/services/circles/UserTieService.ts +++ b/src/data/openFaaSClient/services/circles/UserTieService.ts @@ -1,4 +1,3 @@ - import { UserTie } from 'core/domain/circles/userTie'; import { SocialError } from 'core/domain/common/socialError'; import { IUserTieService } from 'core/services/circles/IUserTieService'; @@ -46,7 +45,7 @@ export class UserTieService implements IUserTieService { const result = await this._httpService.post('user-rels/follow', payload); return result.objectId; } catch (error) { - throw new SocialError(error.code, 'firestore/tieUseres :' + error.message); + throw new SocialError(error.code, 'service/tieUseres :' + error.message); } }; @@ -61,7 +60,7 @@ export class UserTieService implements IUserTieService { }; await this._httpService.put('user-rels/circles', payload); } catch (error) { - throw new SocialError(error.code, 'firestore/updateUsersTie :' + error.message); + throw new SocialError(error.code, 'service/updateUsersTie :' + error.message); } }; @@ -72,7 +71,7 @@ export class UserTieService implements IUserTieService { try { await this._httpService.delete(`user-rels/unfollow/${secondUserId}`); } catch (error) { - throw new SocialError(error.code, 'firestore/removeUsersTie :' + error.message); + throw new SocialError(error.code, 'service/removeUsersTie :' + error.message); } }; @@ -102,7 +101,7 @@ export class UserTieService implements IUserTieService { }); return parsedData; } catch (error) { - throw new SocialError(error.code, 'firestore/getUserTies :' + error.message); + throw new SocialError(error.code, 'service/getUserTies :' + error.message); } }; @@ -133,7 +132,7 @@ export class UserTieService implements IUserTieService { }); return parsedData; } catch (error) { - throw new SocialError(error.code, 'firestore/getUserTieSender :' + error.message); + throw new SocialError(error.code, 'service/getUserTieSender :' + error.message); } }; } diff --git a/src/data/openFaaSClient/services/users/UserService.ts b/src/data/openFaaSClient/services/users/UserService.ts index 1324d13..8d0dede 100644 --- a/src/data/openFaaSClient/services/users/UserService.ts +++ b/src/data/openFaaSClient/services/users/UserService.ts @@ -25,7 +25,7 @@ export class UserService implements IUserService { const result = await this._httpService.get(`profile/id/${userId}`); return { ...result, userId: result.objectId, creationDate: result['created_date'] } as User; } catch (error) { - throw new SocialError(error.code, 'firestore/getUserProfile :' + error.message); + throw new SocialError(error.code, 'service/getUserProfile :' + error.message); } }; @@ -38,7 +38,7 @@ export class UserService implements IUserService { return { ...result, userId: result.objectId, creationDate: result['created_date'] } as User; } catch (error) { - throw new SocialError(error.code, 'firestore/getUserProfile :' + error.message); + throw new SocialError(error.code, 'service/getUserProfile :' + error.message); } }; diff --git a/src/pages/notFound/index.tsx b/src/pages/notFound/index.tsx new file mode 100644 index 0000000..fe8149f --- /dev/null +++ b/src/pages/notFound/index.tsx @@ -0,0 +1,53 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import { Box, Button, Container, Typography } from '@material-ui/core'; +import { useTranslation } from 'react-i18next'; +import config from 'config'; +import { experimentalStyled as styled } from '@material-ui/core/styles'; + +const HomeButtonRoot = styled('div')({ + textAlign: 'center', +}); +const NotFound = () => { + const { t } = useTranslation(); + return ( + <> + + {t('notFound.header', { appName: config.settings.appName })} + + + + + {t('notFound.title')} + + + {t('notFound.description')} + + + + + + Under development + + + + + ); +}; +export default NotFound; diff --git a/src/routes/index.tsx b/src/routes/index.tsx index baa8ed2..a735b6b 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -4,6 +4,7 @@ import Loadable from 'react-loadable'; import { PartialRouteObject } from 'react-router'; import { MasterLoadingComponent } from 'components/masterLoading'; import { homeRoutes } from './homeRouter'; +import NotFound from 'pages/notFound'; const AsyncSignup = Loadable({ loader: () => import('containers/signupWrapper'), @@ -42,33 +43,37 @@ const AsyncMaster: any = Loadable({ const routes = (isLoggedIn: boolean) => [ { - path: '/signup', + path: 'signup', element: isLoggedIn ? : , }, { - path: '/emailVerification', + path: 'emailVerification', element: isLoggedIn ? : , }, { - path: '/smsVerification', + path: 'smsVerification', element: isLoggedIn ? : , }, { - path: '/resetPassword', + path: 'resetPassword', element: isLoggedIn ? : , }, { - path: '/terms', + path: 'terms', element: isLoggedIn ? : , }, { - path: '/login', + path: 'login', element: isLoggedIn ? : , }, { - path: '/newPassword', + path: 'newPassword', element: isLoggedIn ? : , }, + { + path: '404', + element: , + }, { path: '/', element: isLoggedIn ? : , diff --git a/src/store/actions/userActions.ts b/src/store/actions/userActions.ts index 0f9db47..a37c7c8 100644 --- a/src/store/actions/userActions.ts +++ b/src/store/actions/userActions.ts @@ -36,6 +36,17 @@ export const dbGetUserInfoByUserId = (uid: string) => { payload: { uid }, }; }; + +/** + * Get user info from database + */ +export const getUserProfilePage = (uid: string) => { + return { + type: UserActionType.GET_USER_PROFILE_PAGE, + payload: { uid }, + }; +}; + /** * Updata user information */ diff --git a/src/store/sagas/userSaga.ts b/src/store/sagas/userSaga.ts index d83b22b..aaf5dfe 100644 --- a/src/store/sagas/userSaga.ts +++ b/src/store/sagas/userSaga.ts @@ -49,6 +49,20 @@ function* dbFetchUserProfileById(action: { type: UserActionType; payload: any }) } } +function* getUserProfilePage(action: { type: UserActionType; payload: any }) { + const { uid } = action.payload; + if (uid) { + try { + const userProfile: User = yield call(userService.getUserProfile, uid); + + yield put(userActions.addUserInfo(uid, Map({ ...userProfile, userId: uid }))); + } catch (error) { + window.location.href = '/404'; + yield put(globalActions.showMessage(error.message)); + } + } +} + /** * Fetch users for search */ @@ -208,5 +222,6 @@ export default function* userSaga() { takeEvery(UserActionType.DB_FETCH_FIND_PEOPLE, watchFindPeople), takeLatest(UserActionType.DB_FETCH_USER_PROFILE, dbFetchUserProfile), takeLatest(UserActionType.DB_FETCH_USER_PROFILE_BY_ID, dbFetchUserProfileById), + takeLatest(UserActionType.GET_USER_PROFILE_PAGE, getUserProfilePage), ]); }