← back to Handbag Auth Nextjs

src/components/BagDetailModal.tsx

398 lines

'use client'

import { useState, useEffect } from 'react'
import type { MarketplaceBag } from '@/types/marketplace'

interface BagDetailModalProps {
  bag: MarketplaceBag | null
  isOpen: boolean
  onClose: () => void
}

export function BagDetailModal({ bag, isOpen, onClose }: BagDetailModalProps) {
  const [selectedTab, setSelectedTab] = useState<'overview' | 'chart' | 'details'>('overview')

  // Close modal on Escape key
  useEffect(() => {
    const handleEscape = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose()
    }
    if (isOpen) {
      document.addEventListener('keydown', handleEscape)
      document.body.style.overflow = 'hidden'
    }
    return () => {
      document.removeEventListener('keydown', handleEscape)
      document.body.style.overflow = 'unset'
    }
  }, [isOpen, onClose])

  if (!isOpen || !bag) return null

  // Calculate chart dimensions
  const chartWidth = 600
  const chartHeight = 300
  const padding = 40

  const maxPrice = Math.max(...bag.priceHistory.map(p => p.price))
  const minPrice = Math.min(...bag.priceHistory.map(p => p.price))
  const priceRange = maxPrice - minPrice

  // Generate SVG path for price chart
  const points = bag.priceHistory.map((point, index) => {
    const x = padding + (index / (bag.priceHistory.length - 1)) * (chartWidth - padding * 2)
    const y = chartHeight - padding - ((point.price - minPrice) / priceRange) * (chartHeight - padding * 2)
    return { x, y, ...point }
  })

  const pathD = points.map((p, i) => `${i === 0 ? 'M' : 'L'} ${p.x} ${p.y}`).join(' ')

  return (
    <div className="fixed inset-0 z-[100] flex items-center justify-center">
      {/* Backdrop */}
      <div
        className="absolute inset-0 bg-black/80 backdrop-blur-sm"
        onClick={onClose}
      />

      {/* Modal */}
      <div className="relative w-full max-w-4xl max-h-[90vh] overflow-y-auto bg-gradient-to-br from-gray-900 to-black border border-amber-500/30 rounded-2xl shadow-2xl shadow-amber-500/20 m-4">
        {/* Close Button */}
        <button
          onClick={onClose}
          className="absolute top-4 right-4 z-10 w-10 h-10 flex items-center justify-center bg-white/10 hover:bg-white/20 rounded-full transition-colors"
        >
          <span className="text-2xl text-white">×</span>
        </button>

        {/* Header */}
        <div className="p-8 border-b border-white/10">
          <div className="flex items-start gap-6">
            {/* Image */}
            <div className="w-48 h-48 rounded-xl overflow-hidden flex-shrink-0 bg-gray-800">
              <img
                src={bag.image}
                alt={`${bag.brand} ${bag.model}`}
                className="w-full h-full object-cover"
              />
            </div>

            {/* Title & Price */}
            <div className="flex-1">
              <div className="text-sm text-amber-400 font-semibold mb-2">{bag.brand}</div>
              <h2 className="text-3xl font-bold mb-3">{bag.model}</h2>
              <p className="text-gray-400 mb-4">{bag.material} • {bag.hardware} • {bag.color}</p>

              <div className="flex items-center gap-6 mb-4">
                <div>
                  <div className="text-sm text-gray-400">Total Value</div>
                  <div className="text-3xl font-bold text-amber-400">${bag.totalValue.toLocaleString()}</div>
                </div>
                <div>
                  <div className="text-sm text-gray-400">Price per Share</div>
                  <div className="text-2xl font-bold">${bag.pricePerShare}</div>
                </div>
                <div>
                  <div className="text-sm text-gray-400">Appreciation</div>
                  <div className="text-2xl font-bold text-green-400">+{bag.appreciation}%</div>
                </div>
              </div>

              {/* Live Link to Last Sale */}
              {bag.productUrl && (
                <a
                  href={bag.productUrl}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 rounded-lg text-white font-semibold transition-colors"
                >
                  <span>🔗</span>
                  View Original Listing on Yahoo Japan
                  <span className="text-xs opacity-75">↗</span>
                </a>
              )}
            </div>
          </div>
        </div>

        {/* Tabs */}
        <div className="flex gap-1 px-8 pt-6 border-b border-white/10">
          <button
            onClick={() => setSelectedTab('overview')}
            className={`px-6 py-3 font-semibold transition-all ${
              selectedTab === 'overview'
                ? 'text-amber-400 border-b-2 border-amber-400'
                : 'text-gray-400 hover:text-white'
            }`}
          >
            Overview
          </button>
          <button
            onClick={() => setSelectedTab('chart')}
            className={`px-6 py-3 font-semibold transition-all ${
              selectedTab === 'chart'
                ? 'text-amber-400 border-b-2 border-amber-400'
                : 'text-gray-400 hover:text-white'
            }`}
          >
            Price Chart
          </button>
          <button
            onClick={() => setSelectedTab('details')}
            className={`px-6 py-3 font-semibold transition-all ${
              selectedTab === 'details'
                ? 'text-amber-400 border-b-2 border-amber-400'
                : 'text-gray-400 hover:text-white'
            }`}
          >
            Data Source
          </button>
        </div>

        {/* Content */}
        <div className="p-8">
          {/* Overview Tab */}
          {selectedTab === 'overview' && (
            <div className="space-y-6">
              {/* Last Sale Info */}
              {bag.lastSale && (
                <div className="bg-black/30 rounded-xl p-6 border border-green-500/30">
                  <h3 className="text-xl font-bold mb-4 flex items-center gap-2">
                    <span>💰</span> Last Sale Information
                  </h3>
                  <div className="grid grid-cols-3 gap-4">
                    <div>
                      <div className="text-sm text-gray-400">Date</div>
                      <div className="text-lg font-semibold">
                        {new Date(bag.lastSale.date).toLocaleDateString('en-US', {
                          month: 'short',
                          day: 'numeric',
                          year: 'numeric'
                        })}
                      </div>
                    </div>
                    <div>
                      <div className="text-sm text-gray-400">Price</div>
                      <div className="text-lg font-semibold text-amber-400">
                        ${bag.lastSale.price.toLocaleString()}
                      </div>
                    </div>
                    <div>
                      <div className="text-sm text-gray-400">Source</div>
                      <div className="text-lg font-semibold">{bag.lastSale.source}</div>
                    </div>
                  </div>
                </div>
              )}

              {/* Investment Details */}
              <div className="bg-black/30 rounded-xl p-6 border border-amber-500/30">
                <h3 className="text-xl font-bold mb-4 flex items-center gap-2">
                  <span>📊</span> Investment Details
                </h3>
                <div className="grid grid-cols-2 gap-4">
                  <div className="flex items-center justify-between p-4 bg-white/5 rounded-lg">
                    <span className="text-gray-400">Total Shares</span>
                    <span className="font-bold">{bag.totalShares}</span>
                  </div>
                  <div className="flex items-center justify-between p-4 bg-white/5 rounded-lg">
                    <span className="text-gray-400">Available</span>
                    <span className="font-bold text-green-400">{bag.sharesAvailable}</span>
                  </div>
                  <div className="flex items-center justify-between p-4 bg-white/5 rounded-lg">
                    <span className="text-gray-400">Min Investment</span>
                    <span className="font-bold">${bag.pricePerShare}</span>
                  </div>
                  <div className="flex items-center justify-between p-4 bg-white/5 rounded-lg">
                    <span className="text-gray-400">Total Value</span>
                    <span className="font-bold">${bag.totalValue.toLocaleString()}</span>
                  </div>
                </div>
              </div>
            </div>
          )}

          {/* Chart Tab */}
          {selectedTab === 'chart' && (
            <div className="space-y-6">
              <h3 className="text-2xl font-bold flex items-center gap-2">
                <span>📈</span> Price History (2015-2025)
              </h3>

              {/* Interactive Stock Chart */}
              <div className="bg-black/30 rounded-xl p-6 border border-blue-500/30">
                <svg viewBox={`0 0 ${chartWidth} ${chartHeight}`} className="w-full">
                  {/* Grid lines */}
                  {[0, 0.25, 0.5, 0.75, 1].map((fraction) => {
                    const y = chartHeight - padding - fraction * (chartHeight - padding * 2)
                    const price = minPrice + fraction * priceRange
                    return (
                      <g key={fraction}>
                        <line
                          x1={padding}
                          y1={y}
                          x2={chartWidth - padding}
                          y2={y}
                          stroke="rgba(255,255,255,0.1)"
                          strokeWidth="1"
                        />
                        <text
                          x={padding - 10}
                          y={y + 5}
                          fill="#9ca3af"
                          fontSize="12"
                          textAnchor="end"
                        >
                          ${Math.round(price).toLocaleString()}
                        </text>
                      </g>
                    )
                  })}

                  {/* Area under curve */}
                  <defs>
                    <linearGradient id="chartGradient" x1="0%" y1="0%" x2="0%" y2="100%">
                      <stop offset="0%" stopColor="#f59e0b" stopOpacity="0.3" />
                      <stop offset="100%" stopColor="#f59e0b" stopOpacity="0" />
                    </linearGradient>
                  </defs>
                  <path
                    d={`${pathD} L ${chartWidth - padding} ${chartHeight - padding} L ${padding} ${chartHeight - padding} Z`}
                    fill="url(#chartGradient)"
                  />

                  {/* Price line */}
                  <path
                    d={pathD}
                    fill="none"
                    stroke="#f59e0b"
                    strokeWidth="3"
                    strokeLinecap="round"
                    strokeLinejoin="round"
                  />

                  {/* Data points */}
                  {points.map((point, index) => (
                    <g key={index}>
                      <circle
                        cx={point.x}
                        cy={point.y}
                        r="5"
                        fill="#f59e0b"
                        stroke="#000"
                        strokeWidth="2"
                      />
                      <text
                        x={point.x}
                        y={chartHeight - 10}
                        fill="#9ca3af"
                        fontSize="12"
                        textAnchor="middle"
                      >
                        {point.year}
                      </text>
                    </g>
                  ))}
                </svg>

                {/* Price change summary */}
                <div className="mt-6 grid grid-cols-3 gap-4">
                  <div className="text-center p-4 bg-white/5 rounded-lg">
                    <div className="text-sm text-gray-400">Starting Price (2015)</div>
                    <div className="text-xl font-bold">
                      ${bag.priceHistory[0]?.price.toLocaleString()}
                    </div>
                  </div>
                  <div className="text-center p-4 bg-white/5 rounded-lg">
                    <div className="text-sm text-gray-400">Current Price (2025)</div>
                    <div className="text-xl font-bold text-amber-400">
                      ${bag.priceHistory[bag.priceHistory.length - 1]?.price.toLocaleString()}
                    </div>
                  </div>
                  <div className="text-center p-4 bg-white/5 rounded-lg">
                    <div className="text-sm text-gray-400">Total Growth</div>
                    <div className="text-xl font-bold text-green-400">
                      +{Math.round(
                        ((bag.priceHistory[bag.priceHistory.length - 1]?.price - bag.priceHistory[0]?.price) /
                          bag.priceHistory[0]?.price) *
                          100
                      )}%
                    </div>
                  </div>
                </div>
              </div>
            </div>
          )}

          {/* Data Source Tab */}
          {selectedTab === 'details' && (
            <div className="space-y-6">
              <h3 className="text-2xl font-bold flex items-center gap-2">
                <span>🔍</span> Data Transparency
              </h3>

              {/* Data Source */}
              <div className="bg-green-900/20 rounded-xl p-6 border border-green-500/30">
                <div className="flex items-start gap-3 mb-4">
                  <span className="text-2xl">✅</span>
                  <div className="flex-1">
                    <h4 className="text-lg font-bold text-green-400 mb-2">100% Real Data</h4>
                    <p className="text-gray-300 mb-3">{bag.dataSource}</p>
                    <p className="text-sm text-gray-400">{bag.methodology}</p>
                  </div>
                </div>

                {/* Confidence Score */}
                <div className="mt-4 pt-4 border-t border-green-500/20">
                  <div className="flex items-center justify-between mb-2">
                    <span className="text-sm font-semibold text-gray-300">Data Confidence</span>
                    <span className="text-sm font-bold text-green-400">{bag.confidence}%</span>
                  </div>
                  <div className="w-full h-3 bg-gray-800 rounded-full overflow-hidden">
                    <div
                      className="h-full bg-gradient-to-r from-green-500 to-emerald-500"
                      style={{ width: `${bag.confidence}%` }}
                    />
                  </div>
                </div>
              </div>

              {/* Product URL */}
              {bag.productUrl && (
                <div className="bg-blue-900/20 rounded-xl p-6 border border-blue-500/30">
                  <h4 className="text-lg font-bold mb-3 flex items-center gap-2">
                    <span>🔗</span> Original Listing
                  </h4>
                  <p className="text-sm text-gray-400 mb-3">
                    This bag is currently listed on Yahoo Japan Auctions. Click below to view the original listing with full details and photos.
                  </p>
                  <a
                    href={bag.productUrl}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="inline-flex items-center gap-2 px-6 py-3 bg-blue-600 hover:bg-blue-700 rounded-lg text-white font-semibold transition-all transform hover:scale-105"
                  >
                    <span>🌐</span>
                    Open Yahoo Japan Listing
                    <span className="text-xs opacity-75">↗</span>
                  </a>
                  <p className="text-xs text-gray-500 mt-3">
                    Link: {bag.productUrl.substring(0, 60)}...
                  </p>
                </div>
              )}
            </div>
          )}
        </div>

        {/* Footer CTA */}
        <div className="p-8 border-t border-white/10 bg-gradient-to-r from-amber-900/20 to-orange-900/20">
          <button className="w-full px-6 py-4 bg-gradient-to-r from-yellow-400 to-amber-500 rounded-xl text-black font-bold text-lg hover:shadow-2xl hover:shadow-amber-500/50 transition-all transform hover:scale-105">
            Invest in This Bag - Start from ${bag.pricePerShare}
          </button>
        </div>
      </div>
    </div>
  )
}