Skip to content

Commit

Permalink
feat: refactor router paths
Browse files Browse the repository at this point in the history
  • Loading branch information
TomatoVan committed Mar 17, 2024
1 parent 443d526 commit 3c43b6a
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 56 deletions.
32 changes: 21 additions & 11 deletions src/app/providers/router/config/routeConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,55 +8,65 @@ import { AdminPanelPage } from '@/pages/AdminPanelPage';
import { UserRole } from '@/entities/User';
import { ForbiddenPage } from '@/pages/ForbiddenPage';
import { NotFoundPage } from '@/pages/NotFoundPage';
import { AppRoutes, RoutePath } from '@/shared/const/router';
import {
AppRoutes,
getRouterAbout,
getRouterAdminPanel,
getRouterArticleCreate,
getRouterArticleDetails,
getRouterArticleEdit,
getRouterArticles, getRouterForbidden,
getRouterMain, getRouterNotFound,
getRouterProfile,
} from '@/shared/const/router';
import { AppRoutesProps } from '@/shared/types/router';

export const routeConfig: Record<AppRoutes, AppRoutesProps> = {
[AppRoutes.MAIN]: {
path: RoutePath.main,
path: getRouterMain(),
element: <MainPage />,
},
[AppRoutes.ABOUT]: {
path: RoutePath.about,
path: getRouterAbout(),
element: <AboutPage />,
},
[AppRoutes.PROFILE]: {
path: `${RoutePath.profile}:id`,
path: getRouterProfile(':id'),
element: <ProfilePage />,
authOnly: true,
},
[AppRoutes.ARTICLES]: {
path: RoutePath.articles,
path: getRouterArticles(),
element: <ArticlesPage />,
authOnly: true,
},
[AppRoutes.ARTICLE_DETAILS]: {
path: `${RoutePath.article_details}:id`,
path: getRouterArticleDetails(':id'),
element: <ArticlesDetailsPage />,
authOnly: true,
},
[AppRoutes.ARTICLE_CREATE]: {
path: `${RoutePath.article_create}`,
path: getRouterArticleCreate(),
element: <ArticleEditPage />,
authOnly: true,
},
[AppRoutes.ARTICLE_EDIT]: {
path: `${RoutePath.article_edit}`,
path: getRouterArticleEdit(':id'),
element: <ArticleEditPage />,
authOnly: true,
},
[AppRoutes.ADMIN_PANEL]: {
path: RoutePath.admin_panel,
path: getRouterAdminPanel(),
element: <AdminPanelPage />,
authOnly: true,
roles: [UserRole.ADMIN, UserRole.MANAGER],
},
[AppRoutes.FORBIDDEN]: {
path: RoutePath.forbidden,
path: getRouterForbidden(),
element: <ForbiddenPage />,
},
[AppRoutes.NOT_FOUND]: {
path: RoutePath.not_found,
path: getRouterNotFound(),
element: <NotFoundPage />,
},
};
16 changes: 10 additions & 6 deletions src/app/providers/router/ui/RequireAuth.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { useSelector } from 'react-redux';
import { Navigate, useLocation } from 'react-router-dom';
import { useMemo } from 'react';
import { getUserAuthData, getUserRoles, UserRole } from '../../../../entities/User';
import { RoutePath } from '@/shared/const/router';
import {
getUserAuthData,
getUserRoles,
UserRole,
} from '../../../../entities/User';
import { getRouterForbidden, getRouterMain } from '@/shared/const/router';

interface RequireAuthProps {
children: JSX.Element;
roles?: UserRole[];
children: JSX.Element;
roles?: UserRole[];
}

export function RequireAuth({ children, roles }: RequireAuthProps) {
Expand All @@ -23,11 +27,11 @@ export function RequireAuth({ children, roles }: RequireAuthProps) {
}, [roles, userRoles]);

if (!auth) {
return <Navigate to={RoutePath.main} state={{ from: location }} replace />;
return <Navigate to={getRouterMain()} state={{ from: location }} replace />;
}

if (!hasRequiredRoles) {
return <Navigate to={RoutePath.forbidden} state={{ from: location }} replace />;
return <Navigate to={getRouterForbidden()} state={{ from: location }} replace />;
}

return children;
Expand Down
12 changes: 4 additions & 8 deletions src/entities/Article/ui/ArticleListItem/ArticleListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,9 @@ import { Button, ButtonTheme } from '@/shared/ui/Button';
import { AppLink } from '@/shared/ui/AppLink';
import { ArticleBlockType, ArticleView } from '../../model/consts/consts';
import { ArticleTextBlockComponent } from '../ArticleTextBlockComponent/ArticleTextBlockComponent';
import {
Article,
ArticleTextBlock,

} from '../../model/types/article';
import { Article, ArticleTextBlock } from '../../model/types/article';
import cls from './ArticleListItem.module.scss';
import { RoutePath } from '@/shared/const/router';
import { getRouterArticleDetails } from '@/shared/const/router';

interface ArticleListItemProps {
className?: string;
Expand Down Expand Up @@ -62,7 +58,7 @@ export const ArticleListItem = memo((props: ArticleListItemProps) => {
<div className={cls.footer}>
<AppLink
target={target}
to={RoutePath.article_details + article.id}
to={getRouterArticleDetails(article.id)}
>
<Button theme={ButtonTheme.OUTLINE}>
{t('Read more...')}
Expand All @@ -78,7 +74,7 @@ export const ArticleListItem = memo((props: ArticleListItemProps) => {
return (
<AppLink
target={target}
to={RoutePath.article_details + article.id}
to={getRouterArticleDetails(article.id)}
className={classNames(cls.ArticleListItem, {}, [className, cls[view]])}
>
<Card>
Expand Down
4 changes: 2 additions & 2 deletions src/entities/Comment/ui/CommentCard/CommentCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Comment } from '../../model/types/comment';
import { Avatar } from '../../../../shared/ui/Avatar/Avatar';
import { Text } from '../../../../shared/ui/Text/Text';
import { Skeleton } from '../../../../shared/ui/Skeleton/Skeleton';
import { RoutePath } from '@/shared/const/router';
import { getRouterProfile } from '@/shared/const/router';

interface CommentCardProps {
className?: string;
Expand Down Expand Up @@ -38,7 +38,7 @@ export const CommentCard = memo(({ className, comment, isLoading }: CommentCardP

return (
<VStack max gap="8" className={classNames(cls.CommentCard, {}, [className])}>
<AppLink to={`${RoutePath.profile}${comment.user.id}`} className={cls.header}>
<AppLink to={getRouterProfile(comment.user.id)} className={cls.header}>
{comment.user.avatar && <Avatar src={comment.user.avatar} alt={comment.user.username} size={30} />}
<Text className={cls.username} title={comment.user.username} />
</AppLink>
Expand Down
16 changes: 10 additions & 6 deletions src/features/avatarDropdown/ui/AvatarDropDown/AvatarDropDown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
isUserManager,
userActions,
} from '../../../../entities/User';
import { RoutePath } from '@/shared/const/router';
import { getRouterAdminPanel, getRouterProfile } from '@/shared/const/router';

export const AvatarDropDown = memo(() => {
const { t } = useTranslation();
Expand All @@ -35,13 +35,17 @@ export const AvatarDropDown = memo(() => {
<Dropdown
direction="bottom left"
items={[
...(isAdminPanelAvailable ? [{
content: t('Admin panel'),
href: RoutePath.admin_panel,
}] : []),
...(isAdminPanelAvailable
? [
{
content: t('Admin panel'),
href: getRouterAdminPanel(),
},
]
: []),
{
content: t('Profile'),
href: RoutePath.profile + authData.id,
href: getRouterProfile(authData.id),
},
{
content: t('Exit'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { classNames } from '@/shared/lib/classNames/classNames';
import { HStack } from '@/shared/ui/Stack';
import { getCanEditArticle } from '../../model/selectors/article';
import { getArticlesDetailsData } from '../../../../entities/Article';
import { RoutePath } from '@/shared/const/router';
import { getRouterArticleEdit, getRouterArticles } from '@/shared/const/router';

interface ArticlesDetailsPageHeaderProps {
className?: string;
Expand All @@ -21,11 +21,11 @@ export const ArticlesDetailsPageHeader = memo((props: ArticlesDetailsPageHeaderP
const article = useSelector(getArticlesDetailsData);

const onBackToList = useCallback(() => {
navigate(RoutePath.articles);
navigate(getRouterArticles());
}, [navigate]);

const onEditArticle = useCallback(() => {
navigate(`${RoutePath.article_details}${article?.id}/edit`);
navigate(getRouterArticleEdit(article?.id || ''));
}, [article?.id, navigate]);

const canEdit = useSelector(getCanEditArticle);
Expand Down
22 changes: 10 additions & 12 deletions src/shared/const/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,13 @@ export enum AppRoutes {
NOT_FOUND = 'not_found',
}

export const RoutePath: Record<AppRoutes, string> = {
[AppRoutes.MAIN]: '/',
[AppRoutes.ABOUT]: '/about',
[AppRoutes.PROFILE]: '/profile/', // + :id
[AppRoutes.ARTICLES]: '/articles',
[AppRoutes.ARTICLE_DETAILS]: '/articles/', // + :id
[AppRoutes.ARTICLE_CREATE]: '/articles/new',
[AppRoutes.ARTICLE_EDIT]: '/articles/:id/edit',
[AppRoutes.ADMIN_PANEL]: '/admin',
[AppRoutes.FORBIDDEN]: '/forbidden',
[AppRoutes.NOT_FOUND]: '*',
};
export const getRouterMain = () => '/';
export const getRouterAbout = () => '/about';
export const getRouterProfile = (id: string) => `/profile/${id}`;
export const getRouterArticles = () => '/articles';
export const getRouterArticleDetails = (id: string) => `/articles/${id}`;
export const getRouterArticleCreate = () => '/articles/new';
export const getRouterArticleEdit = (id: string) => `/articles/${id}/edit`;
export const getRouterAdminPanel = () => '/admin';
export const getRouterForbidden = () => '/forbidden';
export const getRouterNotFound = () => '*';
4 changes: 2 additions & 2 deletions src/widgets/Navbar/ui/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { NotificationButton } from '@/features/notificationButton';
import { AvatarDropDown } from '@/features/avatarDropdown';
import { getUserAuthData } from '../../../entities/User';
import cls from './Navbar.module.scss';
import { RoutePath } from '@/shared/const/router';
import { getRouterArticleCreate } from '@/shared/const/router';

interface NavbarProps {
className?: string;
Expand Down Expand Up @@ -40,7 +40,7 @@ export const Navbar = memo(({ className }: NavbarProps) => {
/>
<AppLink
theme={AppLinkTheme.SECONDARY}
to={RoutePath.article_create}
to={getRouterArticleCreate()}
className={cls.createBtn}
>
{t('Create new article')}
Expand Down
16 changes: 10 additions & 6 deletions src/widgets/Sidebar/model/selectors/getSidebarItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,37 @@ import ProfileIcon from '@/shared/assets/icons/profile-20-20.svg';
import ArticleIcon from '@/shared/assets/icons/article-20-20.svg';
import { getUserAuthData } from '../../../../entities/User';
import { SidebarItemType } from '../types/sidebar';
import { RoutePath } from '@/shared/const/router';
import {
getRouterAbout,
getRouterArticles,
getRouterMain,
getRouterProfile,
} from '@/shared/const/router';

export const getSidebarItems = createSelector(getUserAuthData, (userData) => {
const sidebarItemsList: SidebarItemType[] = [
{
path: RoutePath.main,
path: getRouterMain(),
Icon: MainIcon,
text: 'Main page',
},
{
path: RoutePath.about,
path: getRouterAbout(),
Icon: AboutIcon,
text: 'About site',
},

];

if (userData) {
sidebarItemsList.push(
{
path: RoutePath.profile + userData.id,
path: getRouterProfile(userData.id),
Icon: ProfileIcon,
text: 'Profile',
authOnly: true,
},
{
path: RoutePath.articles,
path: getRouterArticles(),
Icon: ArticleIcon,
text: 'Articles',
authOnly: true,
Expand Down

0 comments on commit 3c43b6a

Please sign in to comment.