← 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
}
}