From 715e92959a6fe58921967ce1d8d63937e290b2b4 Mon Sep 17 00:00:00 2001 From: Yulia Avramenko Date: Mon, 5 Feb 2024 13:49:48 +0300 Subject: [PATCH 1/3] #210-api-inserted-to-StoriesBlock --- .../StoreProvider/config/StateSchema.ts | 2 ++ .../providers/StoreProvider/config/store.ts | 4 ++- src/entities/StoryCard/StoryCard.module.scss | 10 +++++-- src/entities/StoryCard/StoryCard.stories.tsx | 7 ++--- src/entities/StoryCard/StoryCard.tsx | 12 ++++---- src/shared/api/types.ts | 3 +- .../StoriesBlock/model/selectors/selectors.ts | 5 ++++ .../StoriesBlock/model/services/getStories.ts | 18 ++++++++++++ .../StoriesBlock/model/slice/storiesSlice.ts | 29 +++++++++++++++++++ src/widgets/StoriesBlock/model/types/types.ts | 21 ++++++++++++++ src/widgets/StoriesBlock/ui/StoriesBlock.tsx | 18 +++++++++--- 11 files changed, 110 insertions(+), 19 deletions(-) create mode 100644 src/widgets/StoriesBlock/model/selectors/selectors.ts create mode 100644 src/widgets/StoriesBlock/model/services/getStories.ts create mode 100644 src/widgets/StoriesBlock/model/slice/storiesSlice.ts create mode 100644 src/widgets/StoriesBlock/model/types/types.ts diff --git a/src/app/providers/StoreProvider/config/StateSchema.ts b/src/app/providers/StoreProvider/config/StateSchema.ts index fb954d60..e2dcbf99 100644 --- a/src/app/providers/StoreProvider/config/StateSchema.ts +++ b/src/app/providers/StoreProvider/config/StateSchema.ts @@ -6,6 +6,7 @@ import { ApiInstance } from '@/shared/api/api' import { ShopNewsSchema } from '@/widgets/NewsBlock/model/types/types' import { StoreReviewsSchema } from '@/widgets/ReviewsBlock/model/types/types' import { CoreBaseFooterSchema } from '@/widgets/Footer/model/types/types' +import { IStoriesSchema } from '@/widgets/StoriesBlock/model/types/types' export interface StateSchema { login: LoginSchema @@ -15,6 +16,7 @@ export interface StateSchema { brand: BrandSchema searchResult: SearchResultSchema shopNews: ShopNewsSchema + stories: IStoriesSchema } export interface ThunkExtraArg { diff --git a/src/app/providers/StoreProvider/config/store.ts b/src/app/providers/StoreProvider/config/store.ts index 8074f338..f6426e56 100644 --- a/src/app/providers/StoreProvider/config/store.ts +++ b/src/app/providers/StoreProvider/config/store.ts @@ -8,6 +8,7 @@ import searchProductSlice from '@/features/SearchProduct/slice/searchProductSlic import { storeReviewsReducer } from '@/widgets/ReviewsBlock/model/slice/reviewsSlice' import footerSlice from '@/widgets/Footer/model/slice/footerSlice' import { shopNewsReducer } from '@/widgets/NewsBlock/model/slice/shopNewsSlice' +import { storiesReducer } from '@/widgets/StoriesBlock/model/slice/storiesSlice' export type RootState = StateSchema @@ -18,7 +19,8 @@ const rootReducer: ReducersMapObject = { brand: brandSlice, searchResult: searchProductSlice, storeReviews: storeReviewsReducer, - shopNews: shopNewsReducer + shopNews: shopNewsReducer, + stories: storiesReducer } export function createReduxStore(initialState: RootState) { diff --git a/src/entities/StoryCard/StoryCard.module.scss b/src/entities/StoryCard/StoryCard.module.scss index 5cbcdd55..eb6cdc53 100644 --- a/src/entities/StoryCard/StoryCard.module.scss +++ b/src/entities/StoryCard/StoryCard.module.scss @@ -1,6 +1,8 @@ @use '@/app/styles/index' as var; .card { + max-width: 160px; + min-width: 160px; position: relative; transition: transform 0.3s ease-in-out; display: flex; @@ -13,9 +15,13 @@ transition: transform 0.3s ease-in-out; } - img { + .img { + height: 240px; + width: 100%; border-radius: 6px; transition: transform 0.3s ease-in-out; scroll-snap-align: start; - } + object-fit: cover; + + } } \ No newline at end of file diff --git a/src/entities/StoryCard/StoryCard.stories.tsx b/src/entities/StoryCard/StoryCard.stories.tsx index 3ca6aeec..8da6e6a1 100644 --- a/src/entities/StoryCard/StoryCard.stories.tsx +++ b/src/entities/StoryCard/StoryCard.stories.tsx @@ -16,10 +16,7 @@ type Story = StoryObj export const Default: Story = { args: { - card: { - id: 1, - src: Img1, - alt: 'Stock image' - } + pictures: [Img1], + link: 'https://gealit.ru/api/catalogue/3w-clinic--krem-dlya-glaz-s-ekstraktom-chernogo-zhemchuga-black-pearl-eye-cream-whitening-40-ml-410158271/' } } diff --git a/src/entities/StoryCard/StoryCard.tsx b/src/entities/StoryCard/StoryCard.tsx index 31e326da..2c6b9ecd 100644 --- a/src/entities/StoryCard/StoryCard.tsx +++ b/src/entities/StoryCard/StoryCard.tsx @@ -1,10 +1,10 @@ import { FC } from 'react' -import { TCard } from '@/models/CardModel' import styles from './StoryCard.module.scss' import Link from '@/shared/ui/Link/Link' -export type Props = { - card: TCard +type TProps = { + link: string + pictures: string[] } /** @@ -12,10 +12,10 @@ export type Props = { * @param {TCard} card - параметры карточки из группы историй */ -const StoryCard: FC = ({ card }) => { +const StoryCard: FC = ({ link, pictures }) => { return ( - - {card.alt} + + история ) } diff --git a/src/shared/api/types.ts b/src/shared/api/types.ts index 7c9dc6fe..eebc2531 100644 --- a/src/shared/api/types.ts +++ b/src/shared/api/types.ts @@ -6,7 +6,8 @@ export enum ApiRoutes { STORE_REVIEWS = 'store-reviews', CATEGORIES = 'catalogue/category', CORE_BASE = 'core/base', - SHOP_NEWS = 'shopnews' + SHOP_NEWS = 'shopnews', + STORIES = 'stories' } export enum ApiErrorTypes { diff --git a/src/widgets/StoriesBlock/model/selectors/selectors.ts b/src/widgets/StoriesBlock/model/selectors/selectors.ts new file mode 100644 index 00000000..0c115414 --- /dev/null +++ b/src/widgets/StoriesBlock/model/selectors/selectors.ts @@ -0,0 +1,5 @@ +import { StateSchema } from '@/app/providers/StoreProvider' + +export const getStoriesSelector = (state: StateSchema) => { + return state.stories.stories +} diff --git a/src/widgets/StoriesBlock/model/services/getStories.ts b/src/widgets/StoriesBlock/model/services/getStories.ts new file mode 100644 index 00000000..41ca387c --- /dev/null +++ b/src/widgets/StoriesBlock/model/services/getStories.ts @@ -0,0 +1,18 @@ +import { ThunkConfig } from '@/app/providers/StoreProvider/config/StateSchema' +import { apiErrorIdentify } from '@/shared/api/apiErrorIdentify' +import { ApiError, ApiErrorTypes, ApiRoutes } from '@/shared/api/types' +import { createAsyncThunk } from '@reduxjs/toolkit' +import { IStoriesData } from '../types/types' + +export const getStories = createAsyncThunk>( + 'stories', + async (_, thunkAPI) => { + const { rejectWithValue, extra } = thunkAPI + try { + const { data } = await extra.api.get(ApiRoutes.STORIES) + return data.results + } catch (error) { + return rejectWithValue(apiErrorIdentify(error, ApiErrorTypes.DATA_EMPTY_ERROR)) + } + } +) diff --git a/src/widgets/StoriesBlock/model/slice/storiesSlice.ts b/src/widgets/StoriesBlock/model/slice/storiesSlice.ts new file mode 100644 index 00000000..898c6627 --- /dev/null +++ b/src/widgets/StoriesBlock/model/slice/storiesSlice.ts @@ -0,0 +1,29 @@ +import { createSlice } from '@reduxjs/toolkit' +import { getStories } from '../services/getStories' +import { IStoriesSchema } from '../types/types' + +const initialState: IStoriesSchema = { + isLoading: false, + stories: [] +} + +export const storiesSlice = createSlice({ + name: 'stories', + initialState, + reducers: {}, + extraReducers: builder => { + builder + .addCase(getStories.pending, state => { + state.isLoading = true + }) + .addCase(getStories.fulfilled, (state, { payload }) => { + state.isLoading = false + state.stories = payload + }) + .addCase(getStories.rejected, state => { + state.isLoading = false + }) + } +}) + +export const { actions: storiesActions, reducer: storiesReducer } = storiesSlice diff --git a/src/widgets/StoriesBlock/model/types/types.ts b/src/widgets/StoriesBlock/model/types/types.ts new file mode 100644 index 00000000..ad83f7d4 --- /dev/null +++ b/src/widgets/StoriesBlock/model/types/types.ts @@ -0,0 +1,21 @@ +export interface IPaginatedResponse { + count: number + previous: string + next: string + results: T[] +} +export interface IStoriesPicturesData { + image: string +} + +export interface IStoriesData { + id: number + name: string + link: string + pictures: IStoriesPicturesData[] +} + +export interface IStoriesSchema { + isLoading: boolean + stories: IStoriesData[] +} diff --git a/src/widgets/StoriesBlock/ui/StoriesBlock.tsx b/src/widgets/StoriesBlock/ui/StoriesBlock.tsx index b81fd60d..88586391 100644 --- a/src/widgets/StoriesBlock/ui/StoriesBlock.tsx +++ b/src/widgets/StoriesBlock/ui/StoriesBlock.tsx @@ -1,22 +1,32 @@ -import { FC } from 'react' +import { FC, useEffect } from 'react' +import { getStories } from '../model/services/getStories' +import { useAppDispatch } from '@/shared/libs/hooks/store' +import { getStoriesSelector } from '../model/selectors/selectors' +import { useSelector } from 'react-redux' import Heading, { HeadingType } from '@/shared/ui/Heading/Heading' import styles from './StoriesBlock.module.scss' import Scroll from '@/shared/ui/Scroll/Scroll' -import { storiesData } from '@/mockData/storiesData' import StoryCard from '@/entities/StoryCard/StoryCard' /** * Блок группы историй */ const StoriesBlock: FC = () => { + const dispatch = useAppDispatch() + const stories = useSelector(getStoriesSelector) + + useEffect(() => { + dispatch(getStories()) + }, []) + return (
Истории
- {storiesData.map(item => ( - + {stories.map(item => ( + item.image)} /> ))}
From 9821355d7d1a6bf25907656629e5cc54d563c204 Mon Sep 17 00:00:00 2001 From: Yulia Avramenko Date: Wed, 21 Feb 2024 12:22:23 +0300 Subject: [PATCH 2/3] #210-enhancement-bug-fix --- .../CardReview/ui/CardReview/CardReview.stories.tsx | 1 + src/entities/StoryCard/StoryCard.module.scss | 8 +++----- src/widgets/StoriesBlock/model/services/getStories.ts | 4 +++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/entities/CardReview/ui/CardReview/CardReview.stories.tsx b/src/entities/CardReview/ui/CardReview/CardReview.stories.tsx index 1289f31a..3d80613d 100644 --- a/src/entities/CardReview/ui/CardReview/CardReview.stories.tsx +++ b/src/entities/CardReview/ui/CardReview/CardReview.stories.tsx @@ -1,4 +1,5 @@ import type { Meta, StoryObj } from '@storybook/react' + import CardReview from './CardReview' const meta = { diff --git a/src/entities/StoryCard/StoryCard.module.scss b/src/entities/StoryCard/StoryCard.module.scss index eb6cdc53..fdc8273a 100644 --- a/src/entities/StoryCard/StoryCard.module.scss +++ b/src/entities/StoryCard/StoryCard.module.scss @@ -1,8 +1,7 @@ @use '@/app/styles/index' as var; .card { - max-width: 160px; - min-width: 160px; + width: 160px; position: relative; transition: transform 0.3s ease-in-out; display: flex; @@ -14,14 +13,13 @@ transform: scale(1.1, 1.05); transition: transform 0.3s ease-in-out; } - + .img { height: 240px; width: 100%; border-radius: 6px; transition: transform 0.3s ease-in-out; scroll-snap-align: start; - object-fit: cover; - + object-fit: cover; } } \ No newline at end of file diff --git a/src/widgets/StoriesBlock/model/services/getStories.ts b/src/widgets/StoriesBlock/model/services/getStories.ts index 41ca387c..7e89a387 100644 --- a/src/widgets/StoriesBlock/model/services/getStories.ts +++ b/src/widgets/StoriesBlock/model/services/getStories.ts @@ -1,7 +1,9 @@ +import { createAsyncThunk } from '@reduxjs/toolkit' + import { ThunkConfig } from '@/app/providers/StoreProvider/config/StateSchema' import { apiErrorIdentify } from '@/shared/api/apiErrorIdentify' import { ApiError, ApiErrorTypes, ApiRoutes } from '@/shared/api/types' -import { createAsyncThunk } from '@reduxjs/toolkit' + import { IStoriesData } from '../types/types' export const getStories = createAsyncThunk>( From 2e894c50753656ccebcf85606f34f8bc7c8db63b Mon Sep 17 00:00:00 2001 From: Yulia Avramenko Date: Wed, 28 Feb 2024 13:24:41 +0300 Subject: [PATCH 3/3] #210-bug-fix --- src/entities/BlogCard/BlogCard.module.scss | 3 +-- src/entities/NewsCard/NewsCard.module.scss | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/entities/BlogCard/BlogCard.module.scss b/src/entities/BlogCard/BlogCard.module.scss index a6175bb4..42ef225a 100644 --- a/src/entities/BlogCard/BlogCard.module.scss +++ b/src/entities/BlogCard/BlogCard.module.scss @@ -1,8 +1,7 @@ @use '@/app/styles/index' as var; .card { - max-width: 340px; - min-width: 340px; + width: 340px; position: relative; transition: transform 0.3s ease-in-out; display: flex; diff --git a/src/entities/NewsCard/NewsCard.module.scss b/src/entities/NewsCard/NewsCard.module.scss index 52fad4c9..502b48aa 100644 --- a/src/entities/NewsCard/NewsCard.module.scss +++ b/src/entities/NewsCard/NewsCard.module.scss @@ -1,8 +1,7 @@ @use '@/app/styles/index' as var; .card { - max-width: 340px; - min-width: 340px; + width: 340px; position: relative; transition: transform 0.3s ease-in-out; display: flex;