Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ViewedProductsSkeleton #421

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/app/providers/StoreProvider/config/StateSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { ICartSchema } from '@/pages/CartPage/model/types'
import { IProductAmountStateSchema } from '@/features/CartEdit/model/types'
import { IFeedbackSchema } from '@/features/Reviews/model/types/types'
import { TNumberOfPageSchema } from '@/components/Pagination/types/types'
// import { LoadingState } from '@/widgets/ViewedProducts/model/types/types'

export interface StateSchema {
aboutUs: IAboutUsSchema
Expand All @@ -46,6 +47,7 @@ export interface StateSchema {
productAmount: IProductAmountStateSchema
feedbacks: IFeedbackSchema
pagination: TNumberOfPageSchema
// loading: LoadingState
}

export interface ThunkExtraArg {
Expand Down
2 changes: 2 additions & 0 deletions src/app/providers/StoreProvider/config/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { cartEntityReducer } from '@/entities/CartEntity/model/slice/cartEntityS
import { productAmountReducer } from '@/features/CartEdit/model/slice/productAmountSlice'
import { feedbacksReducer } from '@/features/Reviews/model/slice/feedbacksSlice'
import { paginationSliceReducer } from '@/components/Pagination/slice/paginationSlice'
// import { loadingSliceReducer } from '@/widgets/ViewedProducts/model/functions/loadingSlice'

export type RootState = StateSchema

Expand Down Expand Up @@ -53,6 +54,7 @@ const rootReducer: ReducersMapObject<RootState> = {
categoryFilters: categoryFiltersSliceReducer,
productAmount: productAmountReducer,
pagination: paginationSliceReducer
// loading: loadingSliceReducer
}

export function createReduxStore(initialState: RootState) {
Expand Down
17 changes: 1 addition & 16 deletions src/widgets/ProductItem/ProductItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { CardPreview } from '@/widgets/ProductItem/CardPreview/CardPreview'

import styles from './ProductItem.module.scss'

type TProductCard = {
export type TProductCard = {
layout: ECardView
name: string
price: number
Expand All @@ -36,21 +36,6 @@ type TProductCard = {
id: number
}

/**
* Компонент карточки товара в списке товаров из категории.
* @param {string} layout - тип выбранной сетки отображения карточек товаров;
* @param {string} name - название товара;
* @param {number} price - цена;
* @param {string} brand - производитель;
* @param {string} slug - URL для страницы товара;
* @param {string} description - описание;
* @param {number} code - артикул;
* @param {TImgList} images - массив с изображениями;
* @param {boolean} label_popular - лейбл Популярный на товаре;
* @param {boolean} label_hit - лейбл Хит на товаре;
* @param {number} quantity - количество на склаладе (если > 0, то товар считается в наличии);
* @param {number} id - id товара в backend;
*/
export const ProductItem: FC<TProductCard> = ({
layout,
name,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.skeletonViewedProductsCard {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 292px;
height: 531.6px;
background-color: #f0f0f0;
border-radius: 8px;
overflow: hidden;
margin:0;
gap: 8px;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { FC } from 'react'
import Skeleton from 'react-loading-skeleton'
import 'react-loading-skeleton/dist/skeleton.css'

import styles from './ViewedProductsSkeleton.module.scss'

const ViewedProductsSkeleton: FC = () => {
return (
<div className={styles.skeletonViewedProductsCard}>
<Skeleton width="100%" height="100%" />
</div>
)
}

export default ViewedProductsSkeleton
4 changes: 4 additions & 0 deletions src/widgets/ViewedProducts/model/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ export type TProduct = {
wholesale: number
images: TImgList
}

export type LoadingState = {
isLoading: boolean
}
73 changes: 38 additions & 35 deletions src/widgets/ViewedProducts/ui/ViewedProducts.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { FC } from 'react'
import { FC, useEffect, useState } from 'react'

import { VIEWED_PRODUCTS_COUNT_ON_MAIN } from '@/shared/constants/constants'
import { ECardView } from '@/shared/model/types/common'
import Heading from '@/shared/ui/Heading/Heading'
import Scroll from '@/shared/ui/Scroll/Scroll'
import { ProductItem } from '@/widgets/ProductItem/ProductItem'
import { ProductItem, TProductCard } from '@/widgets/ProductItem/ProductItem'

import { getViewedProductsFromStorage } from '../model/functions/functions'
import ViewedProductsSkeleton from '../ViewedProductsSkeleton/ViewedProductsSkeleton'

import styles from './ViewedProducts.module.scss'

Expand All @@ -21,46 +22,48 @@ interface IViewedProductsProps {
* @param hasLabel {boolean} - Флаг, сигнализирующий о том, должна ли выводиться слева плашка с лейблом. При этом в случае true выводится ограниченное количество карточек
*/

{
/*TODO по FSD нельзя использовать widget ProductItem в widget, нужно перенести ProductItem в features или entities*/
}

const ViewedProducts: FC<IViewedProductsProps> = ({ title, hasLabel }) => {
const viewedProducts = getViewedProductsFromStorage()
const [showSkeleton, setShowSkeleton] = useState(true)
const viewedProducts: TProductCard[] = getViewedProductsFromStorage().map(product => ({
...product,
layout: ECardView.GRID,
isLoading: false
}))

{
/*TODO по FSD нельзя использовать widget ProductItem в widget, нужно перенести ProductItem в features или entities*/
}
const productList = viewedProducts.map((item, index) => {
if (hasLabel && index > VIEWED_PRODUCTS_COUNT_ON_MAIN) return
if (hasLabel && index > VIEWED_PRODUCTS_COUNT_ON_MAIN) return null

return (
<ProductItem
key={item.slug}
layout={ECardView.GRID}
id={item.id}
name={item.name}
price={item.price}
brand={item.brand}
slug={item.slug}
description={item.description}
code={item.code}
images={item.images}
label_hit={item.label_hit}
label_popular={item.label_popular}
quantity={item.quantity}
/>
)
return <ProductItem key={item.slug} {...item} />
})

useEffect(() => {
const timer = setTimeout(() => {
setShowSkeleton(false)
}, 1000)

return () => clearTimeout(timer)
}, [])

const skeletonCount = hasLabel
? Math.min(VIEWED_PRODUCTS_COUNT_ON_MAIN, viewedProducts.length)
: viewedProducts.length

return (
viewedProducts?.length !== 0 && (
<section className={styles.viewedproducts}>
<div className={styles.viewedproducts__header}>
<Heading className={styles.viewedproducts__title}>{title}</Heading>
{hasLabel && <span className={styles.viewedproducts__label}>Вы смотрели</span>}
</div>
<Scroll className={styles.viewedproducts__scroll} withManualGrip={true}>
{productList}
</Scroll>
</section>
)
<section className={styles.viewedproducts}>
<div className={styles.viewedproducts__header}>
<Heading className={styles.viewedproducts__title}>{title}</Heading>
{hasLabel && <span className={styles.viewedproducts__label}>Вы смотрели</span>}
</div>
<Scroll className={styles.viewedproducts__scroll} withManualGrip={true}>
{showSkeleton
? Array.from({ length: skeletonCount }).map((_, index) => <ViewedProductsSkeleton key={index} />)
: productList}
</Scroll>
</section>
)
}

Expand Down