93 lines
3.6 KiB
TypeScript
93 lines
3.6 KiB
TypeScript
'use client';
|
|
|
|
import Image from 'next/image';
|
|
import { useState, useEffect } from 'react';
|
|
import { Drawer } from 'vaul';
|
|
|
|
import { Button } from '@/components/ui/button';
|
|
import type { Shoe } from '@/lib/shoe-database';
|
|
|
|
interface ShoeResultsPopupProps {
|
|
shoe: Shoe | null;
|
|
isOpen: boolean;
|
|
onOpenChange: (isOpen: boolean) => void;
|
|
}
|
|
|
|
export default function ShoeResultsPopup({ shoe, isOpen, onOpenChange }: ShoeResultsPopupProps) {
|
|
const [activeImageUrl, setActiveImageUrl] = useState(shoe?.imageUrl);
|
|
|
|
useEffect(() => {
|
|
// Reset the image when the shoe prop changes
|
|
if (shoe) {
|
|
setActiveImageUrl(shoe.imageUrl);
|
|
}
|
|
}, [shoe]);
|
|
|
|
if (!shoe) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<Drawer.Root open={isOpen} onOpenChange={onOpenChange}>
|
|
<Drawer.Portal>
|
|
<Drawer.Overlay className="fixed inset-0 bg-black/40" />
|
|
<Drawer.Content className="fixed bottom-0 left-0 right-0 mt-24 flex h-[90%] flex-col rounded-t-[10px] bg-gray-100 dark:bg-gray-900">
|
|
<div className="flex-1 overflow-y-auto rounded-t-[10px]">
|
|
{/* Drag Handle */}
|
|
<div className="sticky top-0 z-10 w-full bg-inherit rounded-t-[10px] py-4">
|
|
<div className="mx-auto h-1.5 w-12 flex-shrink-0 rounded-full bg-gray-300 dark:bg-gray-700" />
|
|
</div>
|
|
|
|
{/* Main Content */}
|
|
<div className="p-4">
|
|
{/* Image Section */}
|
|
<div className="relative mb-6 h-64 w-full overflow-hidden rounded-lg md:h-80">
|
|
<Image
|
|
src={activeImageUrl || shoe.imageUrl}
|
|
alt={shoe.name}
|
|
layout="fill"
|
|
objectFit="contain"
|
|
className="transition-opacity duration-300"
|
|
/>
|
|
</div>
|
|
|
|
{/* Info Section */}
|
|
<div className="mb-6">
|
|
<h1 className="text-3xl font-bold tracking-tight text-gray-900 dark:text-gray-50 md:text-4xl">
|
|
{shoe.name}
|
|
</h1>
|
|
<p className="mt-2 text-3xl font-bold text-gray-800 dark:text-gray-100">
|
|
${shoe.price.toFixed(2)}
|
|
</p>
|
|
<p className="mt-4 text-base text-gray-600 dark:text-gray-300">
|
|
{shoe.description}
|
|
</p>
|
|
</div>
|
|
|
|
{/* Color Picker */}
|
|
<div className="mb-8">
|
|
<h3 className="mb-3 text-lg font-semibold text-gray-800 dark:text-gray-200">Colores</h3>
|
|
<div className="flex flex-wrap gap-3">
|
|
{shoe.colorOptions.map((option) => (
|
|
<button
|
|
key={option.color}
|
|
onClick={() => setActiveImageUrl(option.imageUrl)}
|
|
className={`relative h-16 w-16 overflow-hidden rounded-md border-2 transition-all duration-200 ${activeImageUrl === option.imageUrl ? 'border-blue-500 scale-105' : 'border-gray-300 dark:border-gray-600'}`}>
|
|
<Image src={option.imageUrl} alt={option.color} layout="fill" objectFit="cover" />
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{/* Bottom Action Button */}
|
|
<div className="sticky bottom-0 w-full border-t border-gray-200 bg-gray-100/80 p-4 backdrop-blur-sm dark:border-gray-700 dark:bg-gray-900/80">
|
|
<Button size="lg" className="w-full h-12 text-lg">
|
|
Añadir al Carrito
|
|
</Button>
|
|
</div>
|
|
</Drawer.Content>
|
|
</Drawer.Portal>
|
|
</Drawer.Root>
|
|
);
|
|
} |