'use client'; import { useEffect, useState } from 'react'; import { motion } from 'framer-motion'; import { FaDownload, FaSearch, FaCheck, FaTimes, FaClock } from 'react-icons/fa'; import { useAlbums } from '@/lib/AlbumsContext'; import { Purchase } from '@/lib/types'; import { formatPrice } from '@/lib/utils'; import AdminLayout from '@/components/AdminLayout'; export default function AdminPurchasesPage() { const { albums } = useAlbums(); const [purchases, setPurchases] = useState([]); const [searchTerm, setSearchTerm] = useState(''); const [filterStatus, setFilterStatus] = useState<'all' | 'pending' | 'approved' | 'rejected'>('all'); const [loading, setLoading] = useState(false); const fetchPurchases = async () => { setLoading(true); try { const response = await fetch('/api/purchases'); if (response.ok) { const data = await response.json(); setPurchases(data.reverse()); } } catch (error) { console.error('Error fetching purchases:', error); } finally { setLoading(false); } }; useEffect(() => { fetchPurchases(); }, []); const handleApprove = async (purchaseId: number) => { try { const response = await fetch(`/api/purchases/${purchaseId}/approve`, { method: 'PATCH', }); if (response.ok) { fetchPurchases(); } } catch (error) { console.error('Error approving purchase:', error); alert('Failed to approve purchase'); } }; const handleReject = async (purchaseId: number) => { try { const response = await fetch(`/api/purchases/${purchaseId}/reject`, { method: 'PATCH', }); if (response.ok) { fetchPurchases(); } } catch (error) { console.error('Error rejecting purchase:', error); alert('Failed to reject purchase'); } }; const filteredPurchases = purchases.filter((purchase) => { const album = albums.find((a) => a.id === purchase.albumId); const matchesSearch = album?.title.toLowerCase().includes(searchTerm.toLowerCase()) || purchase.transactionId.toLowerCase().includes(searchTerm.toLowerCase()) || purchase.customerName?.toLowerCase().includes(searchTerm.toLowerCase()) || purchase.email?.toLowerCase().includes(searchTerm.toLowerCase()); const matchesStatus = filterStatus === 'all' || purchase.approvalStatus === filterStatus; return matchesSearch && matchesStatus; }); const pendingPurchases = purchases.filter(p => p.approvalStatus === 'pending'); const approvedPurchases = purchases.filter(p => p.approvalStatus === 'approved'); const totalRevenue = approvedPurchases.reduce((total, purchase) => { const album = albums.find((a) => a.id === purchase.albumId); return total + (album?.price || 0); }, 0); const exportToCSV = () => { const headers = ['Date', 'Time', 'Transaction ID', 'Album', 'Price', 'Customer', 'Email', 'Phone', 'Status', 'Payment Method']; const rows = purchases.map((purchase) => { const album = albums.find((a) => a.id === purchase.albumId); const date = new Date(purchase.purchaseDate); return [ date.toLocaleDateString(), date.toLocaleTimeString(), purchase.transactionId, album?.title || 'Unknown', album?.price || 0, purchase.customerName || '', purchase.email || '', purchase.phoneNumber || '', purchase.approvalStatus || 'pending', purchase.paymentMethod || 'card-to-card', ]; }); const csvContent = [headers, ...rows].map((row) => row.join(',')).join('\n'); const blob = new Blob([csvContent], { type: 'text/csv' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `purchases-${new Date().toISOString().split('T')[0]}.csv`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); }; const getStatusBadge = (status?: string) => { const statusLower = (status || 'pending').toLowerCase(); if (statusLower === 'approved') { return ( Approved ); } else if (statusLower === 'rejected') { return ( Rejected ); } else { return ( Pending ); } }; return (
{/* Header */}

Purchase Management

{purchases.length} total • {pendingPurchases.length} pending • {formatPrice(totalRevenue)} revenue

Export CSV
{/* Filters */}
{(['all', 'pending', 'approved', 'rejected'] as const).map((status) => ( ))}
setSearchTerm(e.target.value)} placeholder="Search by album, transaction ID, customer name, or email..." className="w-full pl-12 pr-4 py-3 bg-paper-light border-2 border-paper-brown focus:border-paper-dark focus:outline-none text-paper-dark placeholder-paper-gray shadow-paper" />
{/* Purchases Table */} {loading ? (

Loading purchases...

) : filteredPurchases.length > 0 ? (
{filteredPurchases.map((purchase, index) => { const album = albums.find((a) => a.id === purchase.albumId); const date = new Date(purchase.purchaseDate); return ( ); })}
Date & Time Transaction ID Customer Album Payment Status Price Actions
{date.toLocaleDateString()}
{date.toLocaleTimeString()}
{purchase.transactionId} {purchase.txReceipt && (
Receipt: {purchase.txReceipt}
)}
{purchase.customerName || 'N/A'}
{purchase.email}
{purchase.phoneNumber}
{album?.title || 'Unknown'}
{album?.songs.length} tracks
{purchase.paymentMethod === 'ipg' ? 'IPG' : 'Card-to-Card'} {getStatusBadge(purchase.approvalStatus)} {formatPrice(album?.price || 0)} {purchase.approvalStatus === 'pending' && (
)}
) : (

{searchTerm || filterStatus !== 'all' ? 'No purchases found matching your filters' : 'No purchases yet'}

)}
); }