102 lines
3.2 KiB
TypeScript
102 lines
3.2 KiB
TypeScript
import React from 'react';
|
|
import { Card } from '@/components/ui/card';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Download, FileText, RefreshCcw } from 'lucide-react';
|
|
import type { Purchase } from '@/types';
|
|
|
|
interface PurchasesViewItemProps {
|
|
purchase: Purchase;
|
|
isDownloadOpen: boolean;
|
|
onToggleDownload: () => void;
|
|
onDownloadFormat: (format: string) => void;
|
|
onLicense: () => void;
|
|
onRefund: () => void;
|
|
}
|
|
|
|
const DOWNLOAD_FORMATS = ['WAV (24-bit)', 'MP3 (320kbps)', 'Stems (ZIP)'];
|
|
|
|
export function PurchasesViewItem({
|
|
purchase,
|
|
isDownloadOpen,
|
|
onToggleDownload,
|
|
onDownloadFormat,
|
|
onLicense,
|
|
onRefund,
|
|
}: PurchasesViewItemProps) {
|
|
const product = purchase.product as { title: string; coverUrl?: string; type?: string };
|
|
return (
|
|
<Card
|
|
variant="default"
|
|
className="flex flex-col md:flex-row items-center gap-8 p-4"
|
|
>
|
|
<div className="w-20 h-20 rounded-lg overflow-hidden flex-shrink-0 bg-muted">
|
|
<img
|
|
src={product.coverUrl}
|
|
alt=""
|
|
className="w-full h-full object-cover"
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex-1 w-full text-center md:text-left">
|
|
<h3 className="font-bold text-foreground text-lg mb-1 tracking-tight">{product.title}</h3>
|
|
<div className="flex flex-wrap items-center justify-center md:justify-start gap-4 text-xs text-muted-foreground">
|
|
<span className="bg-card px-2 py-1 rounded border border-border text-muted-foreground">
|
|
{product.type ?? 'pack'}
|
|
</span>
|
|
<span>Order #{purchase.orderId}</span>
|
|
<span>•</span>
|
|
<span>{purchase.date}</span>
|
|
<span>•</span>
|
|
<span className="text-foreground">${purchase.price}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex flex-col sm:flex-row gap-4 w-full md:w-auto">
|
|
<div className="relative">
|
|
<Button
|
|
variant="primary"
|
|
size="sm"
|
|
icon={<Download className="w-4 h-4" />}
|
|
onClick={onToggleDownload}
|
|
>
|
|
Download
|
|
</Button>
|
|
{isDownloadOpen && (
|
|
<div className="absolute top-full right-0 mt-2 w-40 bg-card border border-border rounded-lg shadow-xl z-20 overflow-hidden animate-fadeIn">
|
|
{DOWNLOAD_FORMATS.map((fmt) => (
|
|
<button
|
|
key={fmt}
|
|
type="button"
|
|
className="w-full text-left px-4 py-2 text-xs text-white hover:bg-white/10"
|
|
onClick={() => onDownloadFormat(fmt)}
|
|
>
|
|
{fmt}
|
|
</button>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<Button
|
|
variant="ghost"
|
|
size="sm"
|
|
className="border border-border"
|
|
icon={<FileText className="w-4 h-4" />}
|
|
onClick={onLicense}
|
|
>
|
|
License
|
|
</Button>
|
|
|
|
<Button
|
|
variant="ghost"
|
|
size="sm"
|
|
className="text-muted-foreground hover:text-foreground"
|
|
title="Request Refund"
|
|
onClick={onRefund}
|
|
>
|
|
<RefreshCcw className="w-4 h-4" />
|
|
</Button>
|
|
</div>
|
|
</Card>
|
|
);
|
|
}
|