← back to Handbag Auth Nextjs

src/components/DataAttribution.tsx

204 lines

import React from 'react'

interface DataAttributionProps {
  sources: {
    type: 'spreadsheet' | 'database' | 'api' | 'hardcoded'
    name: string
    description?: string
  }[]
  lastUpdated?: string
  confidence?: number
  showPremiumUpsell?: boolean
}

export function DataAttribution({
  sources,
  lastUpdated = 'Static data',
  confidence,
  showPremiumUpsell = false
}: DataAttributionProps) {
  const getSourceIcon = (type: string) => {
    switch (type) {
      case 'spreadsheet':
        return '📊'
      case 'database':
        return '🗄️'
      case 'api':
        return '🔌'
      case 'hardcoded':
        return '⚠️'
      default:
        return '📄'
    }
  }

  const getSourceColor = (type: string) => {
    switch (type) {
      case 'spreadsheet':
        return 'text-blue-400'
      case 'database':
        return 'text-green-400'
      case 'api':
        return 'text-purple-400'
      case 'hardcoded':
        return 'text-yellow-400'
      default:
        return 'text-gray-400'
    }
  }

  return (
    <div className="border-t border-white/10 pt-6 mt-8">
      <div className="flex items-center justify-between mb-4">
        <h4 className="text-sm font-semibold text-gray-300">Data Sources</h4>
        {showPremiumUpsell && (
          <a
            href="/pricing"
            className="text-xs px-3 py-1 bg-gradient-to-r from-purple-600 to-pink-600 rounded-full hover:shadow-lg hover:shadow-purple-500/50 transition-all"
          >
            🔓 Unlock Real-Time Data
          </a>
        )}
      </div>

      <div className="space-y-3">
        {sources.map((source, idx) => (
          <div key={idx} className="flex items-start gap-3">
            <span className="text-lg">{getSourceIcon(source.type)}</span>
            <div className="flex-1">
              <p className={`text-sm font-medium ${getSourceColor(source.type)}`}>
                {source.name}
              </p>
              {source.description && (
                <p className="text-xs text-gray-500 mt-1">{source.description}</p>
              )}
            </div>
          </div>
        ))}

        <div className="flex items-center gap-3 pt-3 border-t border-white/5">
          <span className="text-lg">⏰</span>
          <div>
            <p className="text-sm text-gray-400">Last Updated</p>
            <p className="text-xs text-gray-500">{lastUpdated}</p>
          </div>
        </div>

        {confidence !== undefined && (
          <div className="flex items-center gap-3">
            <span className="text-lg">✅</span>
            <div>
              <p className="text-sm text-gray-400">Data Confidence</p>
              <div className="flex items-center gap-2">
                <div className="w-32 h-2 bg-gray-800 rounded-full overflow-hidden">
                  <div
                    className="h-full bg-gradient-to-r from-green-500 to-emerald-500"
                    style={{ width: `${confidence}%` }}
                  />
                </div>
                <span className="text-xs text-gray-500">{confidence}%</span>
              </div>
            </div>
          </div>
        )}

        <div className="flex items-center gap-3 pt-3 border-t border-white/5">
          <span className="text-lg">🤖</span>
          <div>
            <p className="text-sm text-gray-400">AI Analysis</p>
            <p className="text-xs text-gray-500">Claude (Anthropic) - Deal Detection & Insights</p>
          </div>
        </div>
      </div>

      {showPremiumUpsell && (
        <div className="mt-6 p-4 bg-gradient-to-r from-purple-600/10 to-pink-600/10 border border-purple-500/20 rounded-xl">
          <p className="text-sm text-gray-300 mb-2">
            <span className="font-bold">Upgrade to Premium</span> for:
          </p>
          <ul className="text-xs text-gray-400 space-y-1">
            <li>• Real-time pricing from 1stDibs, Vestiaire Collective & more</li>
            <li>• Live market data updated every 60 seconds</li>
            <li>• Historical price charts with actual transaction data</li>
            <li>• AI-powered deal alerts</li>
          </ul>
        </div>
      )}
    </div>
  )
}

// Preset configurations for different pages
export const DataAttributionPresets = {
  homepage: {
    sources: [
      {
        type: 'hardcoded' as const,
        name: 'Internal Curation',
        description: 'Hand-selected featured bags from our editorial team'
      },
      {
        type: 'spreadsheet' as const,
        name: 'LUXVAULT Research Database',
        description: 'Curated pricing data from industry reports'
      }
    ],
    lastUpdated: 'Static content (updated manually)',
    showPremiumUpsell: true
  },

  marketplace: {
    sources: [
      {
        type: 'hardcoded' as const,
        name: 'Sample Investment Opportunities',
        description: 'Representative examples - not live inventory'
      },
      {
        type: 'spreadsheet' as const,
        name: 'LUXVAULT Pricing Spreadsheet',
        description: 'Estimated values based on market research'
      }
    ],
    lastUpdated: 'Static content (updated weekly)',
    confidence: 75,
    showPremiumUpsell: true
  },

  museum: {
    sources: [
      {
        type: 'spreadsheet' as const,
        name: 'LUXVAULT Historical Archives',
        description: 'Compiled from Christie\'s, Sotheby\'s auction results & industry publications'
      },
      {
        type: 'hardcoded' as const,
        name: 'Estimated Price Trajectories',
        description: 'Based on known retail price increases and market trends'
      }
    ],
    lastUpdated: 'Historical data (2015-2025 estimates)',
    confidence: 60,
    showPremiumUpsell: true
  },

  admin: {
    sources: [
      {
        type: 'database' as const,
        name: 'Live LUXVAULT Database',
        description: 'Real-time data from crawler agents'
      },
      {
        type: 'api' as const,
        name: 'Web Scraping APIs',
        description: 'Automated collection from luxury resale sites'
      }
    ],
    lastUpdated: 'Real-time (updated every 0.9 seconds)',
    confidence: 95,
    showPremiumUpsell: false
  }
}