diff --git a/frontend/src/components/PropertyDetail/PhotoCarousel.tsx b/frontend/src/components/PropertyDetail/PhotoCarousel.tsx index 6d6fd4d..918a5c4 100644 --- a/frontend/src/components/PropertyDetail/PhotoCarousel.tsx +++ b/frontend/src/components/PropertyDetail/PhotoCarousel.tsx @@ -1,8 +1,10 @@ import { useCallback, useEffect, useRef, useState } from 'react' import type { PropertyPhoto } from '../../types/property' +import VideoPlayer from './VideoPlayer' interface PhotoCarouselProps { photos: PropertyPhoto[] + videoUrl?: string | null } function ChevronLeft() { @@ -34,18 +36,20 @@ function NoPhotoPlaceholder() { ) } -export default function PhotoCarousel({ photos }: PhotoCarouselProps) { +export default function PhotoCarousel({ photos, videoUrl }: PhotoCarouselProps) { const [activeIndex, setActiveIndex] = useState(0) const touchStartX = useRef(null) const containerRef = useRef(null) + const hasVideo = Boolean(videoUrl) + const totalSlides = photos.length + (hasVideo ? 1 : 0) const prev = useCallback(() => { - setActiveIndex((i) => (i === 0 ? photos.length - 1 : i - 1)) - }, [photos.length]) + setActiveIndex((i) => (i === 0 ? totalSlides - 1 : i - 1)) + }, [totalSlides]) const next = useCallback(() => { - setActiveIndex((i) => (i === photos.length - 1 ? 0 : i + 1)) - }, [photos.length]) + setActiveIndex((i) => (i === totalSlides - 1 ? 0 : i + 1)) + }, [totalSlides]) useEffect(() => { const el = containerRef.current @@ -58,21 +62,29 @@ export default function PhotoCarousel({ photos }: PhotoCarouselProps) { return () => el.removeEventListener('keydown', handleKey) }, [prev, next]) - if (photos.length === 0) return + if (totalSlides === 0) return - const active = photos[activeIndex] - const single = photos.length === 1 + const isVideoSlide = hasVideo && activeIndex === 0 + const photoIndex = hasVideo ? activeIndex - 1 : activeIndex + const active = !isVideoSlide ? photos[photoIndex] : null + const single = totalSlides === 1 return (
- {/* Main photo */} -
- {active.alt_text + {/* Main slide */} +
+ {isVideoSlide ? ( + + ) : ( +
+ {active!.alt_text +
+ )} {/* Nav buttons */} {!single && ( @@ -94,7 +106,7 @@ export default function PhotoCarousel({ photos }: PhotoCarouselProps) { {/* Counter */}
- {activeIndex + 1} / {photos.length} + {activeIndex + 1} / {totalSlides}
)} @@ -113,25 +125,53 @@ export default function PhotoCarousel({ photos }: PhotoCarouselProps) { touchStartX.current = null }} > - {photos.map((photo, idx) => ( + {hasVideo && ( - ))} + )} + {photos.map((photo, idx) => { + const slideIdx = hasVideo ? idx + 1 : idx + return ( + + ) + })}
)}
diff --git a/frontend/src/components/PropertyDetail/PriceBox.tsx b/frontend/src/components/PropertyDetail/PriceBox.tsx index ec0c6cc..6c915b2 100644 --- a/frontend/src/components/PropertyDetail/PriceBox.tsx +++ b/frontend/src/components/PropertyDetail/PriceBox.tsx @@ -17,7 +17,7 @@ export default function PriceBox({ price, condo_fee, listing_type }: PriceBoxPro const isVenda = listing_type === 'venda' return ( -
+
{/* Badge */} +