From 344b03b048c5fe2e0b8c41afdaad50eaa7c042e7 Mon Sep 17 00:00:00 2001 From: Tariq Jamal A Date: Sun, 18 May 2025 11:38:08 +0530 Subject: [PATCH] refactor: add product image zoom container --- components/products/AddToCardLeftSection.jsx | 56 ++++++++++++++++--- components/products/AddToCardRightSection.jsx | 7 +++ 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/components/products/AddToCardLeftSection.jsx b/components/products/AddToCardLeftSection.jsx index 64f114a..9f2a818 100644 --- a/components/products/AddToCardLeftSection.jsx +++ b/components/products/AddToCardLeftSection.jsx @@ -1,5 +1,5 @@ "use client"; -import React, { useContext, useState } from "react"; +import React, { useContext, useState, useRef } from "react"; import { Button } from "@/components/ui/button"; import { Card } from "@/components/ui/card"; import { ChevronLeft, ChevronRight, Award } from "lucide-react"; // Added Award icon @@ -9,8 +9,10 @@ import Image from "next/image"; const ProductGallery = ({ productId }) => { const { products } = useContext(ProductContext); - const [currentImageIndex, setCurrentImageIndex] = useState(0); + const [showZoom, setShowZoom] = useState(false); + const [zoomPosition, setZoomPosition] = useState({ x: 0, y: 0 }); + const imageContainerRef = useRef(null); const nextImage = () => { setCurrentImageIndex((prevIndex) => (prevIndex + 1) % productImages.length); @@ -22,6 +24,7 @@ const ProductGallery = ({ productId }) => { (prevIndex - 1 + productImages.length) % productImages.length ); }; + const product = products?.find((pr) => pr.id == productId); if (!product) { return null; @@ -30,6 +33,23 @@ const ProductGallery = ({ productId }) => { const productImages = product?.images?.map((img) => img.image) || []; const hasCertificate = product.certificate && product.certificate !== "NA"; + const handleMouseMove = (e) => { + if (!imageContainerRef.current) return; + + const { left, top, width, height } = imageContainerRef.current.getBoundingClientRect(); + + // Calculate position as percentage + const x = ((e.clientX - left) / width) * 100; + const y = ((e.clientY - top) / height) * 100; + + setZoomPosition({ x, y }); + setShowZoom(true); + }; + + const handleMouseLeave = () => { + setShowZoom(false); + }; + return (
@@ -38,8 +58,8 @@ const ProductGallery = ({ productId }) => { key={index} src={`${backendUrl}${src}`} alt={`Thumbnail ${index + 1}`} - width={160} // Width of w-40 (160px) - height={128} // Height of h-32 (128px) + width={160} + height={128} className="object-cover cursor-pointer border border-gray-300 hover:border-blue-500" onClick={() => setCurrentImageIndex(index)} /> @@ -55,14 +75,18 @@ const ProductGallery = ({ productId }) => {
)} - {/* Main image with carousel controls */} -
+
Main product + + {/* Zoom overlay */} + {showZoom && ( +
+
+
+ )}
diff --git a/components/products/AddToCardRightSection.jsx b/components/products/AddToCardRightSection.jsx index 868e7bc..07a5fa3 100644 --- a/components/products/AddToCardRightSection.jsx +++ b/components/products/AddToCardRightSection.jsx @@ -221,6 +221,13 @@ function ProductDetails({ productId }) { className="text-sm prose prose-sm max-w-none" />
+
+

Beej Mantra

+
+
{showCertificate && !product.certificate.toLowerCase().endsWith('.pdf') && (