Skip to content

Commit

Permalink
redesign articles page
Browse files Browse the repository at this point in the history
  • Loading branch information
roman-adamchik-sw committed Sep 22, 2023
1 parent 6a56737 commit 9889197
Show file tree
Hide file tree
Showing 37 changed files with 742 additions and 187 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ module.exports = {
'borderRadius',
'feature',
'variant',
'activeClassName'
'activeClassName',
'border'
],
}],
'max-len': [
Expand Down
2 changes: 1 addition & 1 deletion json-server/db.json
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@
"isNewDesign": true
},
"jsonSettings": {
"theme": "app-theme-dark",
"theme": "app-theme-yellow",
"isFirstVisit": true,
"settingsPageHasBeenOpened": true,
"isArticlesPageGreetingsOpened": true
Expand Down
1 change: 1 addition & 0 deletions public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"Something went wrong while loading data": "Something went wrong while loading data",
"Something went wrong. Please, try again": "Something went wrong. Please, try again",
"Sort by": "Sort by",
"Sort by...": "Sort by...",
"Techno blog app": "Techno blog app",
"Thanks for your feedback": "Thanks for your feedback",
"There are no articles": "There are no articles",
Expand Down
1 change: 1 addition & 0 deletions public/locales/ru/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"Something went wrong while loading data": "Something went wrong while loading data",
"Something went wrong. Please, try again": "Что-то пошло нет так. Попробуйте позже",
"Sort by": "Sort by",
"Sort by...": "Sort by...",
"Techno blog app": "Techno blog app",
"Thanks for your feedback": "Thanks for your feedback",
"There are no articles": "There are no articles",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,9 @@
align-items: center;
gap: 8px;
}

.articleSortSelectorRedesign {
display: flex;
align-items: center;
gap: 8px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { Select, type SelectOption } from '@/shared/ui/deprecated/Select';
import { useTranslation } from 'react-i18next';
import { type SortOrder } from '@/shared/types/sort';
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;
Expand Down Expand Up @@ -51,20 +55,46 @@ export const ArticleSortSelector = memo((props: ArticleSortSelectorProps) => {
);

return (
<div className={classNames(cls.articleSortSelector, {}, [className])}>
<Select<ArticleSortField>
placeholder={t('Sort by')}
options={optionsFieldOptions}
value={sort}
onChange={onSortChange}
/>
<Select<SortOrder>
placeholder={t('by')}
options={sortOrderOptions}
value={order}
onChange={onOrderChange}
/>
</div>
<ToggleFeatures
feature="isNewDesign"
on={
<div
className={classNames(cls.articleSortSelectorRedesign, {}, [
className,
])}
>
<VStack gap="8">
<Text text={t('Sort by...')} />
<ListBox<ArticleSortField>
items={optionsFieldOptions}
value={sort}
onChange={onSortChange}
/>
<ListBox<SortOrder>
items={sortOrderOptions}
value={order}
onChange={onOrderChange}
/>
</VStack>
</div>
}
off={
<div className={classNames(cls.articleSortSelector, {}, [className])}>
<Select<ArticleSortField>
placeholder={t('Sort by')}
options={optionsFieldOptions}
value={sort}
onChange={onSortChange}
/>
<Select<SortOrder>
placeholder={t('by')}
options={sortOrderOptions}
value={order}
onChange={onOrderChange}
/>
</div>
}
/>
);
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { classNames } from '@/shared/lib/classNames/classNames';
import { memo, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { Tabs, type TabItem } from '@/shared/ui/deprecated/Tabs';
import { Tabs as TabsDeprecated } from '@/shared/ui/deprecated/Tabs';
import { ArticleType } from '@/entities/Article';
import { ToggleFeatures } from '@/shared/lib/features';
import { type TabItem, Tabs } from '@/shared/ui/redesigned/Tabs';

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

return (
<Tabs
className={classNames('', {}, [className])}
tabs={typeTabs}
value={type}
onTabClick={handleTypeChange}
<ToggleFeatures
feature="isNewDesign"
on={
<Tabs
className={classNames('', {}, [className])}
tabs={typeTabs}
value={type}
onTabClick={handleTypeChange}
direction="column"
/>
}
off={
<TabsDeprecated
className={classNames('', {}, [className])}
tabs={typeTabs}
value={type}
onTabClick={handleTypeChange}
/>
}
/>
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,27 @@
height: 24px;
color: var(--secondary-color);
}

.selected {
svg {
color: var(--primary-color);
}
}
}

.selected {
.articleViewSelectorRedesign {
/* stylelint-disable-next-line no-descending-specificity */
svg {
color: var(--primary-color);
color: var(--light-bg-redesigned);
}

.selected {
svg {
color: var(--icon-redesigned);
}
}

.button {
display: flex;
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import { classNames } from '@/shared/lib/classNames/classNames';
import cls from './ArticleViewSelector.module.scss';
import { memo } from 'react';
import GridIcon from '@/shared/assets/icons/grid.svg';
import ListIcon from '@/shared/assets/icons/list.svg';
import { Button, ButtonTheme } from '@/shared/ui/deprecated/Button';
import GridIconDeprecated from '@/shared/assets/icons/grid.svg';
import ListIconDeprecated from '@/shared/assets/icons/list.svg';
import ListIcon from '@/shared/assets/icons/redesign_list.svg';
import GridIcon from '@/shared/assets/icons/redesign_grid.svg';
import {
Button as ButtonDeprecated,
ButtonTheme,
} from '@/shared/ui/deprecated/Button';
import { ArticleListViewType } from '@/entities/Article';
import { ToggleFeatures, toggleFeatures } from '@/shared/lib/features';
import { Button } from '@/shared/ui/redesigned/Button';
import { Card } from '@/shared/ui/redesigned/Card';
import { HStack } from '@/shared/ui/redesigned/Stack';

interface ArticleViewSelectorProps {
className?: string;
Expand All @@ -15,11 +24,19 @@ interface ArticleViewSelectorProps {
const viewTypes = [
{
view: ArticleListViewType.LIST,
icon: <ListIcon />,
icon: toggleFeatures({
feature: 'isNewDesign',
on: () => <ListIcon width={32} height={32} />,
off: () => <ListIconDeprecated />,
}),
},
{
view: ArticleListViewType.TABLE,
icon: <GridIcon />,
icon: toggleFeatures({
feature: 'isNewDesign',
on: () => <GridIcon width={32} height={32} />,
off: () => <GridIconDeprecated />,
}),
},
];

Expand All @@ -31,18 +48,48 @@ export const ArticleViewSelector = memo((props: ArticleViewSelectorProps) => {
};

return (
<div className={classNames(cls.articleViewSelector, {}, [className])}>
{viewTypes.map((viewType) => (
<Button
key={viewType.view}
onClick={handleClick(viewType.view)}
className={classNames('', { [cls.selected]: viewType.view === view })}
theme={ButtonTheme.CLEAR}
<ToggleFeatures
feature="isNewDesign"
on={
<Card
className={classNames(cls.articleViewSelectorRedesign, {}, [
className,
])}
border="rounded"
>
{viewType.icon}
</Button>
))}
</div>
<HStack align="center">
{viewTypes.map((viewType) => (
<Button
key={viewType.view}
onClick={handleClick(viewType.view)}
className={classNames(cls.button, {
[cls.selected]: viewType.view === view,
})}
variant={ButtonTheme.CLEAR}
>
{viewType.icon}
</Button>
))}
</HStack>
</Card>
}
off={
<div className={classNames(cls.articleViewSelector, {}, [className])}>
{viewTypes.map((viewType) => (
<ButtonDeprecated
key={viewType.view}
onClick={handleClick(viewType.view)}
className={classNames('', {
[cls.selected]: viewType.view === view,
})}
theme={ButtonTheme.CLEAR}
>
{viewType.icon}
</ButtonDeprecated>
))}
</div>
}
/>
);
});

Expand Down
85 changes: 85 additions & 0 deletions src/pages/ArticlesPage/lib/hooks/useArticleFilters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { ArticleListViewType, ArticleSortField, ArticleType } from "@/entities/Article";
import { useAppDispatch } from "@/shared/lib/hooks/useAppDispatch/useAppDispatch";
import { useDebounce } from "@/shared/lib/hooks/useDebounce/useDebounce";
import { SortOrder } from "@/shared/types/sort";
import { TabItem } from "@/shared/ui/deprecated/Tabs";
import { useCallback } from "react";
import { useSelector } from "react-redux";
import { getArticlesPageOrder, getArticlesPageSearch, getArticlesPageSort, getArticlesPageType, getArticlesPageView } from "../../model/selectors/articlesPageSelectors";
import { fetchArticlesList } from "../../model/services/fetchArticlesList/fetchArticlesList";
import { articlePageActions } from "../../model/slice/articlePageSlice";

export function useArticleFilters() {
const dispatch = useAppDispatch();

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


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

const debouncedFetchData = useDebounce(fetchData, 500);


const handleViewClick = useCallback(
(view: ArticleListViewType) => {
dispatch(articlePageActions.setView(view));
},
[dispatch],
);

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

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

const handleSearchChange = useCallback(
(newSearch: string) => {
dispatch(articlePageActions.setSearch(newSearch));
dispatch(articlePageActions.setPage(1));
debouncedFetchData();
},
[dispatch, debouncedFetchData],
);

const handleTypeChange = useCallback(
(tab: TabItem<ArticleType>) => {
const { value: newType } = tab;
dispatch(articlePageActions.setType(newType));
dispatch(articlePageActions.setPage(1));
fetchData();
},
[dispatch, fetchData],
);

return {
sort,
order,
search,
type,
view,
handleSortChange,
handleOrderChange,
handleSearchChange,
handleTypeChange,
handleViewClick,
};
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
.articlesPage {
opacity: 1;
}

.articleList {
margin-top: 16px;
.articleList {
margin-top: 16px;
}
}
Loading

0 comments on commit 9889197

Please sign in to comment.