Skip to content

Commit

Permalink
Add feature ArticleEditButton, plural form and edit widget
Browse files Browse the repository at this point in the history
  • Loading branch information
vladislav0sidorov committed Oct 31, 2023
1 parent df74ff4 commit 73cf8c1
Show file tree
Hide file tree
Showing 13 changed files with 179 additions and 29 deletions.
2 changes: 1 addition & 1 deletion json-server/db.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
"isAppRedesigned": true
},
"jsonSettings": {
"theme": "app_dark_theme",
"theme": "app_light_theme",
"isArticlePageWasOpen": true
},
"avatar": "https://sun9-60.userapi.com/impg/eqo5sYxr_jyw_yWO9_pKJRMkx8WVwVENfJrecQ/1zVSkEZs5NM.jpg?size=1620x2160&quality=95&sign=73cab6427b2934395f04d96835eb3720&type=album"
Expand Down
5 changes: 4 additions & 1 deletion public/locales/en/article-details.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@
"Назад к списку": "Back to list",
"Оцените статью": "Rate the article",
"Оставьте свой отзыв, это поможет нам улучшить качество": "Leave your feedback, it will help us improve the quality",
"Спасибо за ваш отзыв!": "Thank for your feedback!"
"Спасибо за ваш отзыв!": "Thank for your feedback!",
"{{count}} просмотров_zero": "{{count}} view",
"{{count}} просмотров_one": "{{count}} views",
"{{count}} просмотров_other": "{{count}} views"
}
6 changes: 5 additions & 1 deletion public/locales/ru/article-details.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@
"Назад к списку": "Назад к списку",
"Оцените статью": "Оцените статью",
"Оставьте свой отзыв, это поможет нам улучшить качество": "Оставьте свой отзыв, это поможет нам улучшить качество",
"Спасибо за ваш отзыв!": "Спасибо за ваш отзыв!"
"Спасибо за ваш отзыв!": "Спасибо за ваш отзыв!",
"{{count}} просмотров_zero": "{{count}} просмотров",
"{{count}} просмотров_one": "{{count}} просмотр",
"{{count}} просмотров_few": "{{count}} просмотра",
"{{count}} просмотров_many": "{{count}} просмотров"
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

.PLATE {
.card {
width: 240px;
width: 235px;
height: 350px;
overflow: hidden;
display: flex;
Expand Down
1 change: 1 addition & 0 deletions src/features/ArticleEditButton/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ArticleEditButton } from './ui/ArticleEditButton'
41 changes: 41 additions & 0 deletions src/features/ArticleEditButton/ui/ArticleEditButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { FC, useCallback } from 'react'
import { useSelector } from 'react-redux'
import { useNavigate } from 'react-router-dom'
import { useTranslation } from 'react-i18next'

import { ToggleFeaturesComponent } from '@/shared/lib/features'
import { Button as DeprecatedButton, ButtonVariables } from '@/shared/ui/deprecated/Button'
import { getRouteArticleEdit } from '@/shared/const/router'
import { getArticleDetailsData } from '@/entities/Article'
import { Button } from '@/shared/ui/redesigned/Button'

interface ArticleEditButtonProps {
className?: string
}

export const ArticleEditButton: FC<ArticleEditButtonProps> = React.memo((props) => {
const { className } = props
const { t } = useTranslation('article-details')
const navigate = useNavigate()
const article = useSelector(getArticleDetailsData)

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

const deprecatedContent = (
<DeprecatedButton onClick={onEditArticle} theme={ButtonVariables.OUTLINE}>
{t('Редактировать')}
</DeprecatedButton>
)

const redesignedContent = (
<Button onClick={onEditArticle} variant="outline">
{t('Редактировать')}
</Button>
)

return <ToggleFeaturesComponent featureName="isAppRedesigned" on={redesignedContent} off={deprecatedContent} />
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.AdditionalInfoContainer {
width: 264px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, { FC } from 'react'
import { useSelector } from 'react-redux'

import cls from './AdditionalInfoContainer.module.scss'

import { ArticleAdditionalInfo } from '@/widgets/ArticleAdditionalInfo'
import { Card } from '@/shared/ui/redesigned/Card'
import { getArticleDetailsData } from '@/entities/Article'

interface AdditionalInfoContainerProps {
className?: string
}

export const AdditionalInfoContainer: FC<AdditionalInfoContainerProps> = React.memo((props) => {
const { className } = props

const article = useSelector(getArticleDetailsData)

if (!article) {
return null
}

return (
// eslint-disable-next-line i18next/no-literal-string
<Card className={cls.AdditionalInfoContainer} padding="24" borderRadius="round">
<ArticleAdditionalInfo author={article.user} views={article.views} createdAt={article.createdAt} />
</Card>
)
})
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@ import React from 'react'
import { articleDetailsPageReducer } from '../../model/slice'
import { ArticleDetailsPageHeader } from '../ArticleDetailsPageHeader/ArticleDetailsPageHeader'
import { ArticleDetailsComments } from '../ArticleDetailsComments/ArticleDetailsComments'
import { DetailsContainer } from '../DetailsContainer/DetailsContainer'
import { AdditionalInfoContainer } from '../AdditionalInfoContainer/AdditionalInfoContainer'

import { ArticleDetails } from '@/entities/Article'
import { DynamicModuleLoader, ReducersList } from '@/shared/lib/components/DynamicModuleLoader/DynamicModuleLoader'
import { Page } from '@/widgets/Page'
import { ArticleRecomendationsList } from '@/features/ArticleRecomendationsList'
import { ArticleRating } from '@/features/ArticleRating'
import { toggleFeatures } from '@/shared/lib/features'
import { ToggleFeaturesComponent, toggleFeatures } from '@/shared/lib/features'
import { Card } from '@/shared/ui/deprecated/Card'
import { VStack } from '@/shared/ui/redesigned/Stack'
import { StickyComponentLayout } from '@/shared/layouts/StickyComponentLayout'

interface ArticleDetailsPageProps {
className?: string
Expand All @@ -38,18 +41,39 @@ const ArticleDetailsPage: React.FC<ArticleDetailsPageProps> = (props) => {
off: () => <Card>{t('Оценка статей скоро появится!')}</Card>,
})

const deprecatedContent = (
<Page>
<VStack data-testid="ArticleDetailsPage.ParentBlock" max gap="16">
<ArticleDetailsPageHeader />
<ArticleDetails id={id} />
<ArticleRating articleId={id} />
{ArticleRatingCard}
<ArticleRecomendationsList />
<ArticleDetailsComments id={id} />
</VStack>
</Page>
)

const redesignedContent = (
<StickyComponentLayout
content={
<Page>
<VStack data-testid="ArticleDetailsPage.ParentBlock" max gap="16">
<DetailsContainer />
<ArticleRating articleId={id} />
{ArticleRatingCard}
<ArticleRecomendationsList />
<ArticleDetailsComments id={id} />
</VStack>
</Page>
}
right={<AdditionalInfoContainer />}
/>
)

return (
<DynamicModuleLoader reducers={reducers} removeAfterUnmount>
<Page>
<VStack data-testid="ArticleDetailsPage.ParentBlock" max gap="16">
<ArticleDetailsPageHeader />
<ArticleDetails id={id} />
<ArticleRating articleId={id} />
{ArticleRatingCard}
<ArticleRecomendationsList />
<ArticleDetailsComments id={id} />
</VStack>
</Page>
<ToggleFeaturesComponent featureName="isAppRedesigned" on={redesignedContent} off={deprecatedContent} />
</DynamicModuleLoader>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { useSelector } from 'react-redux'
import { getCanEditArticle } from '../../model/selectors/getCanEditArticle/getCanEditArticle'

import { classNames } from '@/shared/lib/ClassNames/ClassNames'
import { getArticleDetailsData } from '@/entities/Article'
import { getRouteArticleEdit, getRouteArticles } from '@/shared/const/router'
import { getRouteArticles } from '@/shared/const/router'
import { HStack } from '@/shared/ui/redesigned/Stack'
import { Button, ButtonVariables } from '@/shared/ui/deprecated/Button'
import { ArticleEditButton } from '@/features/ArticleEditButton'

interface ArticleDetailsPageHeaderProps {
className?: string
Expand All @@ -20,28 +20,17 @@ export const ArticleDetailsPageHeader: FC<ArticleDetailsPageHeaderProps> = React
const { t } = useTranslation('article-details')
const navigate = useNavigate()
const canEdit = useSelector(getCanEditArticle)
const article = useSelector(getArticleDetailsData)

const onBackToList = useCallback(() => {
navigate(getRouteArticles())
}, [navigate])

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

return (
<HStack max justify="between" className={classNames('', {}, [className])}>
<Button onClick={onBackToList} theme={ButtonVariables.OUTLINE}>
{t('Назад к списку')}
</Button>
{canEdit && (
<Button onClick={onEditArticle} theme={ButtonVariables.OUTLINE}>
{t('Редактировать')}
</Button>
)}
{canEdit && <ArticleEditButton />}
</HStack>
)
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React, { FC } from 'react'
import { useParams } from 'react-router-dom'

import { Card } from '@/shared/ui/redesigned/Card'
import { ArticleDetails } from '@/entities/Article'

interface DetailsContainerProps {
className?: string
}

export const DetailsContainer: FC<DetailsContainerProps> = React.memo((props) => {
const { className } = props
const { id } = useParams<{ id: string }>()

return (
<Card max className={className} padding="24">
<ArticleDetails id={id} />
</Card>
)
})
35 changes: 35 additions & 0 deletions src/widgets/ArticleAdditionalInfo/ArticleAdditionalInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React, { FC } from 'react'
import { useTranslation } from 'react-i18next'

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 { ArticleEditButton } from '@/features/ArticleEditButton'

interface ArticleAdditionalInfoProps {
className?: string
author?: User
createdAt?: string
views?: number
}

export const ArticleAdditionalInfo: FC<ArticleAdditionalInfoProps> = React.memo((props) => {
const { className, author, createdAt, views } = props
const { t } = useTranslation('article-details')

return (
<VStack gap="24">
<HStack gap="8">
<Avatar src={author?.avatar} size={32} />
<Text text={author?.username} bold />
</HStack>
<ArticleEditButton />
<VStack gap="8">
<Text text={t('{{count}} просмотров', { count: views })} />

<Text text={createdAt} />
</VStack>
</VStack>
)
})
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 './ArticleAdditionalInfo'

0 comments on commit 73cf8c1

Please sign in to comment.