38 lines
1.4 KiB
TypeScript
38 lines
1.4 KiB
TypeScript
import Link from 'next/link'
|
|
import { Sparkline } from './Sparkline'
|
|
|
|
interface Props {
|
|
id: string
|
|
name: string
|
|
shop: string
|
|
imageUrl: string | null
|
|
lastPrice: string | null
|
|
minPrice: string | null
|
|
sparkline: Array<{ price: number; t: string }>
|
|
}
|
|
|
|
export function ProductCard(p: Props) {
|
|
const last = p.lastPrice ? Number(p.lastPrice) : null
|
|
const min = p.minPrice ? Number(p.minPrice) : null
|
|
const deltaFromMin = last !== null && min !== null ? (last - min).toFixed(2) : null
|
|
|
|
return (
|
|
<Link href={`/products/${p.id}`} className="block rounded-lg border border-zinc-800 bg-zinc-900 p-4 hover:border-zinc-700 transition">
|
|
<div className="flex gap-3">
|
|
{p.imageUrl && <img src={p.imageUrl} alt="" className="h-16 w-16 object-contain rounded bg-white" />}
|
|
<div className="flex-1 min-w-0">
|
|
<div className="text-xs uppercase tracking-wide text-zinc-500">{p.shop}</div>
|
|
<div className="truncate text-sm font-medium">{p.name}</div>
|
|
<div className="mt-1 flex items-baseline gap-2">
|
|
<span className="text-lg font-semibold">{last !== null ? `${last.toFixed(2)} €` : '—'}</span>
|
|
{deltaFromMin !== null && (
|
|
<span className="text-xs text-zinc-400">+{deltaFromMin} € vom Tief</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="mt-2"><Sparkline data={p.sparkline} /></div>
|
|
</Link>
|
|
)
|
|
}
|