← back to Watches
src/components/MarketPrice.jsx
86 lines
import React from 'react';
import { motion } from 'framer-motion';
/**
* Format price with currency symbol and thousands separator
*/
function formatPrice(price, currency = 'USD') {
if (price === null || price === undefined) return null;
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency,
minimumFractionDigits: 0,
maximumFractionDigits: 0
}).format(price);
}
/**
* MarketPrice - Displays current market price range
* @param {Object} priceData - { low, high, currency, source }
* @param {boolean} compact - Compact mode for cards
* @param {string} className - Additional CSS classes
*/
export default function MarketPrice({ priceData, compact = false, className = '' }) {
// Handle missing data
if (!priceData || (priceData.low === undefined && priceData.high === undefined)) {
return (
<div className={`text-gray-500 ${className}`}>
<span className="text-sm">Price unavailable</span>
</div>
);
}
const { low, high, currency = 'USD', source } = priceData;
const lowFormatted = formatPrice(low, currency);
const highFormatted = formatPrice(high, currency);
// Single price or range
const priceDisplay = low === high || !high
? lowFormatted
: `${lowFormatted} - ${highFormatted}`;
if (compact) {
return (
<motion.div
className={`${className}`}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.3 }}
>
<span className="text-amber-400 font-semibold text-sm">
{priceDisplay}
</span>
</motion.div>
);
}
return (
<motion.div
className={`${className}`}
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.4 }}
>
<div className="flex flex-col gap-1">
<div className="flex items-baseline gap-2">
<span className="text-gray-400 text-sm">Market Price:</span>
<motion.span
className="text-amber-400 font-bold text-lg"
initial={{ scale: 0.9 }}
animate={{ scale: 1 }}
transition={{ type: 'spring', stiffness: 300, damping: 20 }}
>
{priceDisplay}
</motion.span>
</div>
{source && (
<span className="text-gray-500 text-xs">
via {source}
</span>
)}
</div>
</motion.div>
);
}