Skip to content

Commit

Permalink
feat: redesign text, card, popups, header, article filters
Browse files Browse the repository at this point in the history
  • Loading branch information
TomatoVan committed Apr 21, 2024
1 parent 144d9f2 commit f1343ae
Show file tree
Hide file tree
Showing 29 changed files with 707 additions and 87 deletions.
3 changes: 3 additions & 0 deletions extractedTranslations/en/Sort by.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"": ""
}
14 changes: 13 additions & 1 deletion extractedTranslations/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,24 @@
"read more": "",
"throw error": "throw error",
"views": "",
"Айти": "",
"Ваш отзыв": "",
"Все статьи": "",
"Главная страница": "",
"Закрыть": "",
"Наука": "",
"Обновить страницу": "",
"Отправить": "",
"Оценка статей скоро появится!": "",
"Поиск": "",
"Произошла непредвиденная ошибка": "",
"Статьи не найдены": ""
"Сортировать ПО": "",
"Статьи не найдены": "",
"Экономика": "",
"возрастанию": "",
"дате создания": "",
"названию": "",
"по": "",
"просмотрам": "",
"убыванию": ""
}
3 changes: 3 additions & 0 deletions extractedTranslations/en/Сортировать по.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"": ""
}
30 changes: 23 additions & 7 deletions src/features/ArticleTypeTabs/ui/ArticleTypeTabs.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { useTranslation } from 'react-i18next';
import { memo, useCallback, useMemo } from 'react';
import { TabItem, Tabs } from '@/shared/ui/deprecated/Tabs';
import { classNames } from '@/shared/lib/classNames/classNames';
import { ArticleType } from '../../../entities/Article';
import { TabItem, Tabs as TabsDeprecated } from '@/shared/ui/deprecated/Tabs';
import { ArticleType } from '@/entities/Article';
import { ToggleFeatures } from '@/shared/lib/features';
import { Tabs } from '@/shared/ui/redesigned/Tabs';

interface ArticleTypeTabsProps {
className?: string;
Expand Down Expand Up @@ -44,11 +46,25 @@ export const ArticleTypeTabs = memo((props: ArticleTypeTabsProps) => {
);

return (
<Tabs
className={classNames('', {}, [className])}
tabs={typeTabs}
value={value}
onTabClick={onTabClick}
<ToggleFeatures
feature="isAppRedesigned"
on={
<Tabs
direction="column"
tabs={typeTabs}
value={value}
onTabClick={onTabClick}
className={classNames('', {}, [className])}
/>
}
off={
<TabsDeprecated
tabs={typeTabs}
value={value}
onTabClick={onTabClick}
className={classNames('', {}, [className])}
/>
}
/>
);
});
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
.notSelected {
fill: var(--secondary-color);
.ArticleViewSelector {
.notSelected {
fill: var(--secondary-color);
}
}

.ArticleViewSelectorRedesigned {
.notSelected {
color: var(--light-bg-redesigned);
}
}
99 changes: 75 additions & 24 deletions src/features/ArticleViewSelector/ui/ArticleViewSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
import { memo } from 'react';
import { Button, ButtonTheme } from '@/shared/ui/deprecated/Button';
import { classNames } from '@/shared/lib/classNames/classNames';
import ListIcon from '@/shared/assets/icons/list-24-24.svg';
import TiledIcon from '@/shared/assets/icons/tiled-24-24.svg';
import { ArticleView } from '../../../entities/Article';
import ListIconDeprecated from '@/shared/assets/icons/list-24-24.svg';
import TiledIconDeprecated from '@/shared/assets/icons/tiled-24-24.svg';

import ListIcon from '@/shared/assets/icons/burger.svg';
import TiledIcon from '@/shared/assets/icons/tile.svg';

import { Icon as IconDeprecated } from '@/shared/ui/deprecated/Icon';
import {
Button as ButtonDeprecated,
ButtonTheme,
} from '@/shared/ui/deprecated/Button';
import cls from './ArticleViewSelector.module.scss';
import { Icon } from '@/shared/ui/deprecated/Icon';
import { ArticleView } from '@/entities/Article';
import { ToggleFeatures, toggleFeatures } from '@/shared/lib/features';
import { Icon } from '@/shared/ui/redesigned/Icon';
import { Card } from '@/shared/ui/redesigned/Card';
import { HStack } from '@/shared/ui/redesigned/Stack';

interface ArticleViewSelectorProps {
className?: string;
Expand All @@ -16,11 +27,19 @@ interface ArticleViewSelectorProps {
const viewTypes = [
{
view: ArticleView.SMALL,
icon: TiledIcon,
icon: toggleFeatures({
name: 'isAppRedesigned',
on: () => TiledIcon,
off: () => TiledIconDeprecated,
}),
},
{
view: ArticleView.BIG,
icon: ListIcon,
icon: toggleFeatures({
name: 'isAppRedesigned',
on: () => ListIcon,
off: () => ListIconDeprecated,
}),
},
];

Expand All @@ -32,23 +51,55 @@ export const ArticleViewSelector = memo((props: ArticleViewSelectorProps) => {
};

return (
<div className={classNames(cls.ArticleViewSelector, {}, [className])}>
{viewTypes.map((viewType) => (
<Button
theme={ButtonTheme.CLEAR}
onClick={() => onClick(viewType.view)}
key={viewType.view}
<ToggleFeatures
feature="isAppRedesigned"
on={
<Card
className={classNames(
cls.ArticleViewSelectorRedesigned,
{},
[className],
)}
border="round"
>
<HStack gap="8">
{viewTypes.map((viewType) => (
<Icon
clickable
onClick={() => onClick(viewType.view)}
Svg={viewType.icon}
className={classNames('', {
[cls.notSelected]: viewType.view !== view,
})}
/>
))}
</HStack>
</Card>
}
off={
<div
className={classNames(cls.ArticleViewSelector, {}, [
className,
])}
>
<Icon
className={classNames('', {
[cls.notSelected]: viewType.view !== view,
})}
Svg={viewType.icon}
width={24}
height={24}
/>
</Button>
))}
</div>
{viewTypes.map((viewType) => (
<ButtonDeprecated
key={viewType.view}
theme={ButtonTheme.CLEAR}
onClick={() => onClick(viewType.view)}
>
<IconDeprecated
width={24}
height={24}
Svg={viewType.icon}
className={classNames('', {
[cls.notSelected]: viewType.view !== view,
})}
/>
</ButtonDeprecated>
))}
</div>
}
/>
);
});
72 changes: 54 additions & 18 deletions src/features/ArtilcleSortSelector/ui/ArticleSortSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import { useTranslation } from 'react-i18next';
import { memo, useMemo } from 'react';
import { Select, SelectOption } from '@/shared/ui/deprecated/Select';
import { classNames } from '@/shared/lib/classNames/classNames';
import { Select, SelectOption } from '@/shared/ui/deprecated/Select';
import { SortOrder } from '@/shared/types/sort';
import cls from './ArticleSortSelector.module.scss';
import { ArticleSortField } from '@/entities/Article';
import { ToggleFeatures } from '@/shared/lib/features';
import { ListBox } from '@/shared/ui/redesigned/Popups';
import { VStack } from '@/shared/ui/redesigned/Stack';
import { Text } from '@/shared/ui/redesigned/Text';

interface ArticleSortSelectorProps {
className?: string;
sort: ArticleSortField;
order: SortOrder;
onChangeSort: (newSort: ArticleSortField) => void;
onChangeOrder: (newOrder: SortOrder) => void;
onChangeSort: (newSort: ArticleSortField) => void;
}

export const ArticleSortSelector = memo((props: ArticleSortSelectorProps) => {
const { className, sort, order, onChangeSort, onChangeOrder } = props;
const { className, onChangeOrder, onChangeSort, order, sort } = props;
const { t } = useTranslation();

const orderOptions = useMemo<SelectOption<SortOrder>[]>(
Expand Down Expand Up @@ -51,20 +55,52 @@ export const ArticleSortSelector = memo((props: ArticleSortSelectorProps) => {
);

return (
<div className={classNames(cls.ArticleSortSelector, {}, [className])}>
<Select
options={sortFieldOptions}
label={t('Sort by')}
value={sort}
onChange={onChangeSort}
/>
<Select
options={orderOptions}
label={t('by')}
value={order}
onChange={onChangeOrder}
className={cls.order}
/>
</div>
<ToggleFeatures
feature="isAppRedesigned"
on={
<div
className={classNames(
cls.ArticleSortSelectorRedesigned,
{},
[className],
)}
>
<VStack gap="8">
<Text text={t('Sort by:')} />
<ListBox
items={sortFieldOptions}
value={sort}
onChange={onChangeSort}
/>
<ListBox
items={orderOptions}
value={order}
onChange={onChangeOrder}
/>
</VStack>
</div>
}
off={
<div
className={classNames(cls.ArticleSortSelector, {}, [
className,
])}
>
<Select<ArticleSortField>
options={sortFieldOptions}
label={t('Sort by')}
value={sort}
onChange={onChangeSort}
/>
<Select
options={orderOptions}
label={t('by')}
value={order}
onChange={onChangeOrder}
className={cls.order}
/>
</div>
}
/>
);
});
87 changes: 87 additions & 0 deletions src/pages/ArticlesPage/lib/hooks/useArticleFilters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { useSelector } from 'react-redux';
import { useCallback } from 'react';
import {
getArticlesPageOrder,
getArticlesPageSearch,
getArticlesPageSort,
getArticlesPageType,
getArticlesPageView,
} from '../../model/selectors/articlesPageSelectors';
import { ArticleSortField, ArticleType, ArticleView } from '@/entities/Article';
import { articlesPageActions } from '../../model/slices/articlesPageSlice';
import { SortOrder } from '@/shared/types/sort';
import { fetchArticlesList } from '../../model/services/fetchArticlesList/fetchArticlesList';
import { useDebounce } from '@/shared/lib/hook/useDebounce/useDebounce';
import { useAppDispatch } from '@/shared/lib/hook/useAppDispatch/useAppDispatch';

export function useArticleFilters() {
const view = useSelector(getArticlesPageView);
const sort = useSelector(getArticlesPageSort);
const order = useSelector(getArticlesPageOrder);
const search = useSelector(getArticlesPageSearch);
const type = useSelector(getArticlesPageType);

const dispatch = useAppDispatch();

const fetchData = useCallback(() => {
dispatch(fetchArticlesList({ replace: true }));
}, [dispatch]);

const debouncedFetchData = useDebounce(fetchData, 500);

const onChangeView = useCallback(
(view: ArticleView) => {
dispatch(articlesPageActions.setView(view));
},
[dispatch],
);

const onChangeSort = useCallback(
(newSort: ArticleSortField) => {
dispatch(articlesPageActions.setSort(newSort));
dispatch(articlesPageActions.setPage(1));
fetchData();
},
[dispatch, fetchData],
);

const onChangeOrder = useCallback(
(newOrder: SortOrder) => {
dispatch(articlesPageActions.setOrder(newOrder));
dispatch(articlesPageActions.setPage(1));
fetchData();
},
[dispatch, fetchData],
);

const onChangeSearch = useCallback(
(search: string) => {
dispatch(articlesPageActions.setSearch(search));
dispatch(articlesPageActions.setPage(1));
debouncedFetchData();
},
[dispatch, debouncedFetchData],
);

const onChangeType = useCallback(
(value: ArticleType) => {
dispatch(articlesPageActions.setType(value));
dispatch(articlesPageActions.setPage(1));
fetchData();
},
[dispatch, fetchData],
);

return {
view,
sort,
order,
search,
type,
onChangeView,
onChangeSort,
onChangeOrder,
onChangeSearch,
onChangeType,
};
}
Loading

0 comments on commit f1343ae

Please sign in to comment.