← back to Wine Finder Next

components/mobile/MobileWineCard.tsx

149 lines

'use client'

import { useState } from 'react';
import Image from 'next/image';
import { Wine } from '@/lib/types/wine';
import WineDetailModal from './WineDetailModal';

interface MobileWineCardProps {
  wine: Wine;
  onClick?: (wine: Wine) => void;
}

export default function MobileWineCard({ wine, onClick }: MobileWineCardProps) {
  const [showModal, setShowModal] = useState(false);

  const handleClick = () => {
    if (onClick) {
      onClick(wine);
    } else {
      setShowModal(true);
    }
  };

  const isInStock = wine.availability?.toLowerCase().includes('stock');
  const priceNum = typeof wine.price === 'string' ? parseFloat(wine.price) : wine.price;

  return (
    <>
      <div
        onClick={handleClick}
        className="bg-white rounded-xl shadow-md overflow-hidden active:scale-[0.98] transition-transform duration-150 cursor-pointer touch-manipulation"
        style={{ WebkitTapHighlightColor: 'transparent' }}
        data-wine-id={wine.id || wine.name}
      >
        {/* Image Section */}
        <div className="relative h-48 bg-gradient-to-br from-purple-100 to-pink-100">
          {wine.image ? (
            <Image
              src={wine.image}
              alt={wine.name}
              fill
              className="object-contain p-4"
              sizes="(max-width: 428px) 100vw, 50vw"
              loading="lazy"
            />
          ) : (
            <div className="flex items-center justify-center h-full text-5xl">
              🍷
            </div>
          )}

          {/* Badge */}
          {wine.badge && (
            <div className="absolute top-2 right-2">
              <span className="bg-gradient-to-r from-purple-600 to-pink-600 text-white text-xs px-3 py-1 rounded-full font-bold shadow-lg">
                {wine.badge === 'new' && '🆕 New'}
                {wine.badge === 'deal' && '🔥 Deal'}
                {wine.badge === 'featured' && '⭐'}
              </span>
            </div>
          )}

          {/* Price Change */}
          {wine.priceHistory?.priceChange && (
            <div className="absolute bottom-2 left-2 bg-black/70 text-white px-2 py-1 rounded-full text-xs font-bold">
              {wine.priceHistory.priceChange.startsWith('-') ? '📉' : '📈'} {wine.priceHistory.priceChange}
            </div>
          )}
        </div>

        {/* Content */}
        <div className="p-4 space-y-2">
          {/* Title */}
          <h3 className="font-bold text-base text-gray-900 line-clamp-2 leading-tight min-h-[2.5rem]">
            {wine.name}
          </h3>

          {/* Winery */}
          {wine.winery && (
            <p className="text-xs text-purple-600 font-medium truncate">
              🏛️ {wine.winery}
            </p>
          )}

          {/* Price & Rating Row */}
          <div className="flex items-center justify-between pt-2">
            <div className="flex-1">
              <div className="text-2xl font-bold text-purple-700">
                ${priceNum.toFixed(2)}
              </div>
              {wine.priceHistory?.previousPrice && (
                <div className="text-xs text-gray-500 line-through">
                  ${wine.priceHistory.previousPrice}
                </div>
              )}
            </div>

            {wine.rating && (
              <div className="flex items-center gap-1 bg-yellow-50 px-2 py-1 rounded-lg border border-yellow-200">
                <span className="text-yellow-500 text-sm">⭐</span>
                <span className="text-sm font-bold text-gray-800">
                  {wine.rating}
                </span>
              </div>
            )}
          </div>

          {/* Quick Info Row */}
          <div className="flex items-center gap-2 text-xs">
            {wine.vintage && (
              <span className="bg-purple-50 text-purple-700 px-2 py-1 rounded font-medium">
                {wine.vintage}
              </span>
            )}
            {wine.region && (
              <span className="bg-gray-50 text-gray-700 px-2 py-1 rounded truncate flex-1">
                📍 {wine.region}
              </span>
            )}
          </div>

          {/* Source & Availability */}
          <div className="flex items-center justify-between text-xs pt-2 border-t border-gray-100">
            <span className="text-gray-600 font-medium">
              {wine.source}
            </span>
            {wine.availability && (
              <span className={`px-2 py-1 rounded-full font-bold ${
                isInStock
                  ? 'bg-green-100 text-green-700'
                  : 'bg-gray-100 text-gray-600'
              }`}>
                {isInStock ? '✓' : '○'} {wine.availability}
              </span>
            )}
          </div>
        </div>
      </div>

      {/* Detail Modal */}
      <WineDetailModal
        wine={wine}
        isOpen={showModal}
        onClose={() => setShowModal(false)}
      />
    </>
  );
}