From 1a67296c415a736a283549f3331fcb249406c3c2 Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Tue, 2 Sep 2025 09:04:16 +0330 Subject: [PATCH] audio and video --- src/app/products/DetailService.tsx | 8 +- src/app/products/components/ServiceAudios.tsx | 35 +++++++ src/app/products/components/ServiceImages.tsx | 92 ++++++++++++++++--- src/app/products/types/ProductTypes.ts | 2 + 4 files changed, 121 insertions(+), 16 deletions(-) create mode 100644 src/app/products/components/ServiceAudios.tsx diff --git a/src/app/products/DetailService.tsx b/src/app/products/DetailService.tsx index 5755b71..6541606 100644 --- a/src/app/products/DetailService.tsx +++ b/src/app/products/DetailService.tsx @@ -9,6 +9,7 @@ import Image from 'next/image' import Loading from '../loading' import Rate from 'rc-rate' import { ReviewItem } from './types/ProductTypes' +import ServiceAudios from './components/ServiceAudios' // Default avatar image const defaultAvatar = '/images/logo.svg' // Using an existing image @@ -86,14 +87,17 @@ const DetailService: FC<{ id: string }> = ({ id }) => { - {getDetailService?.data?.data?.danakService?.images && ( - + {getDetailService?.data?.data?.danakService && ( + )}
توضیحات کامل
+ + + {getDetailService.data?.data?.danakService?.metaDescription && ( )} diff --git a/src/app/products/components/ServiceAudios.tsx b/src/app/products/components/ServiceAudios.tsx new file mode 100644 index 0000000..d3048af --- /dev/null +++ b/src/app/products/components/ServiceAudios.tsx @@ -0,0 +1,35 @@ +import { FC } from 'react' +import { ServiceDetailResponse } from '../types/ProductTypes' + +type Props = { + item: ServiceDetailResponse | undefined +} + +const ServiceAudios: FC = ({ item }) => { + if (!item?.data?.danakService?.audios || item.data.danakService.audios.length === 0) { + return null + } + + return ( +
+ +
+ {item.data.danakService.audios.map((audio) => ( +
+
+ فایل صوتی +
+ +
+ ))} +
+
+ ) +} + +export default ServiceAudios diff --git a/src/app/products/components/ServiceImages.tsx b/src/app/products/components/ServiceImages.tsx index 8822938..f448ac4 100644 --- a/src/app/products/components/ServiceImages.tsx +++ b/src/app/products/components/ServiceImages.tsx @@ -1,6 +1,8 @@ import Image from 'next/image' -import { FC } from 'react' +import { FC, useState, useRef } from 'react' import { Swiper, SwiperSlide } from 'swiper/react' +import { Play, Pause } from 'iconsax-react' +import { DanakService } from '../types/ProductTypes' const SWIPER_SLIDE_STYLE = { overflow: 'visible !important', @@ -8,10 +10,46 @@ const SWIPER_SLIDE_STYLE = { } type Props = { - images: { id: string, imageUrl: string }[] + item: DanakService } -const ServiceImages: FC = ({ images }) => { +const ServiceImages: FC = ({ item }) => { + const [playingVideos, setPlayingVideos] = useState<{ [key: string]: boolean }>({}) + const videoRefs = useRef<{ [key: string]: HTMLVideoElement | null }>({}) + + const toggleVideo = (videoId: string) => { + const video = videoRefs.current[videoId] + if (!video) return + + if (playingVideos[videoId]) { + video.pause() + setPlayingVideos(prev => ({ + ...prev, + [videoId]: false + })) + } else { + video.play() + setPlayingVideos(prev => ({ + ...prev, + [videoId]: true + })) + } + } + + const handleVideoPlay = (videoId: string) => { + setPlayingVideos(prev => ({ + ...prev, + [videoId]: true + })) + } + + const handleVideoPause = (videoId: string) => { + setPlayingVideos(prev => ({ + ...prev, + [videoId]: false + })) + } + return (
= ({ images }) => { spaceBetween={20} // فاصله پیش‌فرض بین اسلایدها slidesPerView='auto' > + {/* نمایش ویدیوها */} + {item?.videos?.map((video) => ( + +
+
+
+ ))} - { - images.map((item) => { - return ( - -
- {item.imageUrl} -
-
- ) - }) - } + {/* نمایش تصاویر */} + {item?.images?.map((image) => ( + +
+ {image.imageUrl} +
+
+ ))}
) diff --git a/src/app/products/types/ProductTypes.ts b/src/app/products/types/ProductTypes.ts index a3afca7..7e99055 100644 --- a/src/app/products/types/ProductTypes.ts +++ b/src/app/products/types/ProductTypes.ts @@ -84,6 +84,8 @@ export interface DanakService { reviews: ReviewItem[]; // reviews: any[]; // replace with Review[] if review structure is defined deletedAt: string | null; + videos: { id: string; createdAt: string; videoUrl: string }[]; + audios: { id: string; createdAt: string; audioUrl: string }[]; } export type ServiceDetailResponse = ApiResponse<{