Skip to content

Commit

Permalink
feat: redesign article details, add counts translations
Browse files Browse the repository at this point in the history
  • Loading branch information
TomatoVan committed Apr 25, 2024
1 parent c8ef753 commit 28edc59
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 30 deletions.
9 changes: 9 additions & 0 deletions extractedTranslations/en/translation.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
{
"": "",
"123": "123",
"About site": "",
"Admin panel": "",
"All": "",
"Article ratings coming soon!": "",
"Articles": "",
"Articles app": "",
"Articles not found": "",
"Ascending": "",
Expand Down Expand Up @@ -33,6 +35,8 @@
"Incorrect country": "",
"Incorrect user data": "",
"Leave your feedback on the article, it will help improve the quality": "",
"Main page": "",
"Main_page": "",
"Name": "",
"New": "",
"No data": "",
Expand Down Expand Up @@ -89,6 +93,10 @@
"read more": "",
"throw error": "throw error",
"views": "",
"{{count}} views": "",
"{{count}} views_plural": "",
"{{count}} просмотров": "",
"{{count}} просмотров_plural": "",
"Айти": "",
"Ваш отзыв": "",
"Все статьи": "",
Expand All @@ -102,6 +110,7 @@
"Попробуйте обновить страницу": "",
"Произошла непредвиденная ошибка": "",
"Произошла ошибка при загрузке профиля": "",
"Редактировать": "",
"Сортировать ПО": "",
"Статьи не найдены": "",
"Экономика": "",
Expand Down
5 changes: 4 additions & 1 deletion public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,8 @@
"auth_password": "Enter password",
"login_error": "An incorrect username or password",
"exit": "Exit",
"main_page": "Main page"
"main_page": "Main page",
"{{count}} views_zero": "{{count}} views",
"{{count}} views_one": "{{count}} view",
"{{count}} views_other": "{{count}} views"
}
10 changes: 9 additions & 1 deletion public/locales/ru/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,13 @@
"auth_password": "Введите пароль",
"login_error": "Вы ввели неверный логин или пароль",
"exit": "Выйти",
"main_page": "Главная страница"
"main_page": "Главная страница",
"Main page": "Главная страница",
"About site": "О сайте",
"Profile": "Профиль",
"Articles": "Статьи",
"{{count}} views_zero": "{{count}} просмотров",
"{{count}} views_one": "{{count}} просмотр",
"{{count}} views_few": "{{count}} просмотров",
"{{count}} views_many": "{{count}} просмотров"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.card {
width: 264px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { memo, useCallback } from 'react';
import { useSelector } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import { Card } from '@/shared/ui/redesigned/Card';
import { ArticleAdditionalInfo } from '@/widgets/ArticleAdditionalInfo';
import cls from './AdditionalInfoContainer.module.scss';
import { getRouteArticleEdit } from '@/shared/const/router';
import { getArticlesDetailsData } from '@/entities/Article';

export const AdditionalInfoContainer = memo(() => {
const article = useSelector(getArticlesDetailsData);

const navigate = useNavigate();

const onEditArticle = useCallback(() => {
if (article) {
navigate(getRouteArticleEdit(article.id));
}
}, [article, navigate]);

if (!article) {
return null;
}

return (
<Card padding="24" border="round" className={cls.card}>
<ArticleAdditionalInfo
onEdit={onEditArticle}
author={article.user}
createdAt={article.createdAt}
views={article.views}
/>
</Card>
);
});
Original file line number Diff line number Diff line change
@@ -1,56 +1,44 @@
import { memo } from 'react';
import { useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { VStack } from '@/shared/ui/redesigned/Stack';
import { Card } from '@/shared/ui/deprecated/Card';
import {
DynamicModuleLoader,
ReducersList,
} from '@/shared/lib/components/DynamicModuleLoared/DynamicModuleLoared';
import { ArticleRecommendationsList } from '@/features/articleRecommendationsList';
import { ArticleDetailsComments } from '../../ui/ArticleDetailsComments/ArticleDetailsComments';

import { ArticlesDetailsPageHeader } from '../../ui/ArticlesDetailsPageHeader/ArticlesDetailsPageHeader';
import { articleDetailsPageReducer } from '../../model/slices';
import { ArticleDetails } from '../../../../entities/Article';
import { ArticleRating } from '@/features/articleRating';
import { Page } from '@/widgets/Page';
import { ToggleFeatures } from '@/shared/lib/features';
import { StickyContentLayout } from '@/shared/layouts/StickyContentLayout';
import { DetailsContainer } from '../DetailsContainer/DetailsContainer';
import { AdditionalInfoContainer } from '../AdditionalInfoContainer/AdditionalInfoContainer';

const reducers: ReducersList = {
articleDetailsPage: articleDetailsPageReducer,
};

const ArticlesDetailsPage = (props: any) => {
const { id } = useParams<{ id: string }>();
const { t } = useTranslation();

if (!id) {
return null;
}

// usage example for func
// const articleRatingCard = toggleFeatures({
// name: 'isArticleRatingEnabled',
// on: () => todo1(),
// off: () => todo2(),
// });

return (
<DynamicModuleLoader reducers={reducers}>
<Page>
<VStack gap="16" max>
<ArticlesDetailsPageHeader />
<ArticleDetails id={id} />
<ToggleFeatures
feature="isArticleRatingEnabled"
on={<ArticleRating articleId={id} />}
off={<Card>{t('Article ratings coming soon!')}</Card>}
/>
<ArticleRecommendationsList />
<ArticleDetailsComments id={id} />
</VStack>
</Page>
<StickyContentLayout
content={
<Page>
<VStack gap="16" max>
<DetailsContainer />
<ArticleRating articleId={id} />
<ArticleRecommendationsList />
<ArticleDetailsComments id={id} />
</VStack>
</Page>
}
right={<AdditionalInfoContainer />}
/>
</DynamicModuleLoader>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { memo } from 'react';
import { useParams } from 'react-router-dom';
import { ArticleDetails } from '@/entities/Article';
import { Card } from '@/shared/ui/redesigned/Card';

interface DetailsContainerProps {
className?: string;
}

export const DetailsContainer = memo((props: DetailsContainerProps) => {
const { className } = props;

const { id } = useParams<{ id: string }>();

if (!id) {
return null;
}
return (
<Card max padding="24" className={className}>
<ArticleDetails id={id} />
</Card>
);
});
1 change: 1 addition & 0 deletions src/widgets/ArticleAdditionalInfo/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ArticleAdditionalInfo } from './ui/ArticleAdditionalInfo/ArticleAdditionalInfo';
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { classNames } from '@/shared/lib/classNames/classNames';
import { User } from '@/entities/User';
import { HStack, VStack } from '@/shared/ui/redesigned/Stack';
import { Avatar } from '@/shared/ui/redesigned/Avatar';
import { Text } from '@/shared/ui/redesigned/Text';
import { Button } from '@/shared/ui/redesigned/Button';

interface ArticleAdditionalInfoProps {
className?: string;
author: User;
createdAt: string;
views: number;
onEdit: () => void;
}

export const ArticleAdditionalInfo = memo(
(props: ArticleAdditionalInfoProps) => {
const { className, author, createdAt, views, onEdit } = props;
const { t } = useTranslation();

return (
<VStack gap="32" className={classNames('', {}, [className])}>
<HStack gap="8">
<Avatar src={author.avatar} size={32} />
<Text text={author.username} bold />
<Text text={createdAt} />
</HStack>
<Button onClick={onEdit}>{t('Edit')}</Button>
<Text text={t('{{count}} views', { count: views })} />
</VStack>
);
},
);

0 comments on commit 28edc59

Please sign in to comment.