avarage rate + count comment

This commit is contained in:
hamid zarghami
2025-11-01 16:20:07 +03:30
parent ca2bfa7906
commit a893677d1c
3 changed files with 16 additions and 18 deletions
+10 -16
View File
@@ -1,33 +1,27 @@
'use client' 'use client'
import { Star1 } from 'iconsax-react' import { Star1 } from 'iconsax-react'
import { FC, useEffect, useMemo } from 'react' import { FC, useEffect } from 'react'
import { Product, Review } from '@/types/product.types' import { Product } from '@/types/product.types'
import Image from 'next/image' import Image from 'next/image'
import { clx } from '@/helpers/utils' import { clx } from '@/helpers/utils'
import { useProductStore } from '../store/Store' import { useProductStore } from '../store/Store'
interface BaseInformationProps { interface BaseInformationProps {
product: Product product: Product
reviews?: Review[] stats: {
commentsCount: number;
averageRate: number;
}
} }
const BaseInformation: FC<BaseInformationProps> = ({ product, reviews = [] }) => { const BaseInformation: FC<BaseInformationProps> = ({ product, stats }) => {
const { setVariantId, variantId } = useProductStore() const { setVariantId, variantId } = useProductStore()
const brand = product.brand const brand = product.brand
// محاسبه میانگین امتیاز و تعداد دیدگاه‌ها // محاسبه میانگین امتیاز و تعداد دیدگاه‌ها
const { averageRating, reviewsCount } = useMemo(() => {
if (!reviews.length) {
return { averageRating: 0, reviewsCount: 0 }
}
const totalRating = reviews.reduce((sum, review) => sum + review.rating, 0)
return {
averageRating: Number((totalRating / reviews.length).toFixed(1)),
reviewsCount: reviews.length
}
}, [reviews])
// تابع برای انتخاب variant // تابع برای انتخاب variant
const handleVariantSelect = (variantId: string) => { const handleVariantSelect = (variantId: string) => {
@@ -65,7 +59,7 @@ const BaseInformation: FC<BaseInformationProps> = ({ product, reviews = [] }) =>
> >
<Star1 size={16} color='#FFC107' variant='Bold' className='sm:w-5 sm:h-5' /> <Star1 size={16} color='#FFC107' variant='Bold' className='sm:w-5 sm:h-5' />
<span className='text-xs sm:text-sm'> <span className='text-xs sm:text-sm'>
{reviewsCount > 0 ? `${averageRating} امتیاز` : '۰ امتیاز'} {stats.commentsCount > 0 ? `${stats.averageRate} امتیاز` : '۰ امتیاز'}
</span> </span>
</button> </button>
<div className='size-1.5 rounded-full bg-[#E5E5E5]'></div> <div className='size-1.5 rounded-full bg-[#E5E5E5]'></div>
@@ -76,7 +70,7 @@ const BaseInformation: FC<BaseInformationProps> = ({ product, reviews = [] }) =>
}} }}
className='text-primary text-xs sm:text-sm hover:underline' className='text-primary text-xs sm:text-sm hover:underline'
> >
{reviewsCount} دیدگاه {stats.commentsCount} دیدگاه
</button> </button>
</div> </div>
+2 -2
View File
@@ -35,7 +35,7 @@ const SingleProduct = ({ id }: SingleProductProps) => {
notFound() notFound()
} }
const { product, categoryPath, reviews, questions } = productData.results const { product, categoryPath, reviews, stats } = productData.results
return ( return (
<div className='mt-14 px-4 sm:px-6 md:px-8 lg:px-12 xl:px-20'> <div className='mt-14 px-4 sm:px-6 md:px-8 lg:px-12 xl:px-20'>
@@ -69,7 +69,7 @@ const SingleProduct = ({ id }: SingleProductProps) => {
<div className='flex-1 flex flex-col gap-6'> <div className='flex-1 flex flex-col gap-6'>
<div className='flex flex-col lg:flex-row gap-4 sm:gap-6'> <div className='flex flex-col lg:flex-row gap-4 sm:gap-6'>
<ProductImage product={product} /> <ProductImage product={product} />
<BaseInformation product={product} reviews={reviews} /> <BaseInformation product={product} stats={stats} />
</div> </div>
<div> <div>
<Specifications product={product} /> <Specifications product={product} />
+4
View File
@@ -172,5 +172,9 @@ export interface ProductDetailResponse {
categoryPath: CategoryPathItem[]; categoryPath: CategoryPathItem[];
reviews?: Review[]; reviews?: Review[];
questions?: Question[]; questions?: Question[];
stats: {
commentsCount: number;
averageRate: number;
};
}; };
} }