Files
rudarksh-frontend/components/products/AddToCardLeftSection.jsx

159 lines
5.6 KiB
JavaScript

"use client";
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
import ProductContext from "@/app/contexts/productContext";
import { backendUrl } from "@/utils/axios";
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);
};
const prevImage = () => {
setCurrentImageIndex(
(prevIndex) =>
(prevIndex - 1 + productImages.length) % productImages.length
);
};
const product = products?.find((pr) => pr.id == productId);
if (!product) {
return null;
}
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 (
<div className="flex flex-col md:flex-row gap-4 p-4 sm:w-[70%] ">
<div className="hidden md:flex flex-col gap-2">
{productImages?.map((src, index) => (
<Image
key={index}
src={`${backendUrl}${src}`}
alt={`Thumbnail ${index + 1}`}
width={160}
height={128}
className="object-cover cursor-pointer border border-gray-300 hover:border-blue-500"
onClick={() => setCurrentImageIndex(index)}
/>
))}
</div>
<div className="flex-grow h-full">
<Card className="p-4 h-[380px] sm:h-[80vh] relative">
{/* Certificate Badge */}
{hasCertificate && (
<div className="absolute top-2 right-2 z-10 bg-green-100 text-green-800 px-2 py-1 rounded-md flex items-center text-xs font-medium">
<Award className="w-3 h-3 mr-1" />
Certified
</div>
)}
<div
className="relative mb-4 h-full"
ref={imageContainerRef}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
>
<Image
src={`${backendUrl}${productImages[currentImageIndex]}`}
alt="Main product"
width={500}
height={500}
className="object-cover w-full h-full cursor-zoom-in"
/>
<Button
className="absolute top-1/2 left-2 transform -translate-y-1/2 md:hidden"
onClick={prevImage}
variant="ghost"
>
<ChevronLeft />
</Button>
<Button
className="absolute top-1/2 right-2 transform -translate-y-1/2 md:hidden"
onClick={nextImage}
variant="ghost"
>
<ChevronRight />
</Button>
{/* Zoom overlay */}
{showZoom && (
<div className="absolute top-0 right-0 w-40 h-40 md:w-60 md:h-60 lg:w-[300px] lg:h-[300px] border-2 border-gray-300 overflow-hidden z-20 bg-white shadow-lg">
<div
className="absolute w-[1000px] h-[1000px]"
style={{
backgroundImage: `url(${backendUrl}${productImages[currentImageIndex]})`,
backgroundPosition: `${zoomPosition.x}% ${zoomPosition.y}%`,
backgroundSize: '250%',
backgroundRepeat: 'no-repeat',
transform: 'translate(-50%, -50%)',
left: '50%',
top: '50%',
}}
/>
</div>
)}
</div>
</Card>
<div className="my-6">
<div className="flex gap-3">
<h3 className="p-1 px-2 rounded-3xl border text-xs border-yellow-700">
A+ Grade
</h3>
<h3 className="p-1 px-2 rounded-3xl border text-xs border-yellow-700">
IRL Certified
</h3>
<h3 className="p-1 px-2 rounded-3xl border text-xs border-yellow-700">
Expert Rating
</h3>
{hasCertificate && (
<h3 className="p-1 px-2 rounded-3xl border text-xs border-green-700 bg-green-50">
Certificate Available
</h3>
)}
</div>
<h2 className="mt-3">Note: Free Shipping on order above $ 300</h2>
<h2 className="my-1">100% Secured Payment</h2>
<h2>Authenticity Guaranteed</h2>
</div>
<div className="mt-8 border-t pt-6 hidden md:block">
<h2 className="text-xl font-semibold mb-4">Beej Mantra</h2>
<div
dangerouslySetInnerHTML={{ __html: product.beej_mantra }}
className="text-sm prose prose-sm max-w-none"
/>
</div>
</div>
</div>
);
};
export default ProductGallery;