168 lines
5.6 KiB
TypeScript
168 lines
5.6 KiB
TypeScript
'use client';
|
|
|
|
import { useState, useEffect } from 'react';
|
|
import Header from '@/components/Header';
|
|
import Biography from '@/components/Biography';
|
|
import AlbumShowcase from '@/components/AlbumShowcase';
|
|
import MusicPlayer from '@/components/MusicPlayer';
|
|
import PaymentModal from '@/components/PaymentModal';
|
|
import PurchaseSuccessModal from '@/components/PurchaseSuccessModal';
|
|
import CartSidebar from '@/components/CartSidebar';
|
|
import { Album, Purchase } from '@/lib/types';
|
|
|
|
export default function Home() {
|
|
const [purchasedAlbums, setPurchasedAlbums] = useState<string[]>([]);
|
|
const [purchases, setPurchases] = useState<Purchase[]>([]);
|
|
const [currentAlbum, setCurrentAlbum] = useState<Album | null>(null);
|
|
const [albumToPurchase, setAlbumToPurchase] = useState<Album | null>(null);
|
|
const [showSuccessModal, setShowSuccessModal] = useState(false);
|
|
const [latestPurchase, setLatestPurchase] = useState<Purchase | null>(null);
|
|
const [cartOpen, setCartOpen] = useState(false);
|
|
|
|
// Load purchases from localStorage and API on mount
|
|
useEffect(() => {
|
|
const savedPurchases = localStorage.getItem('purchases');
|
|
if (savedPurchases) {
|
|
const parsedPurchases = JSON.parse(savedPurchases);
|
|
setPurchases(parsedPurchases);
|
|
}
|
|
|
|
// Fetch approved purchases from API
|
|
const fetchPurchases = async () => {
|
|
try {
|
|
const response = await fetch('/api/purchases');
|
|
if (response.ok) {
|
|
const apiPurchases = await response.json();
|
|
// Only include approved purchases for determining access
|
|
const approvedPurchases = apiPurchases.filter((p: Purchase) => p.approvalStatus === 'approved');
|
|
setPurchasedAlbums(approvedPurchases.map((p: Purchase) => p.albumId));
|
|
}
|
|
} catch (error) {
|
|
console.error('Error fetching purchases:', error);
|
|
}
|
|
};
|
|
|
|
fetchPurchases();
|
|
}, []);
|
|
|
|
const handlePlayAlbum = (album: Album) => {
|
|
setCurrentAlbum(album);
|
|
};
|
|
|
|
const handlePurchaseClick = (album: Album) => {
|
|
setAlbumToPurchase(album);
|
|
};
|
|
|
|
const handlePurchaseSuccess = (albumId: string, transactionId: string) => {
|
|
const purchase: Purchase = {
|
|
albumId,
|
|
transactionId,
|
|
purchaseDate: new Date(),
|
|
approvalStatus: 'pending',
|
|
};
|
|
|
|
const updatedPurchases = [...purchases, purchase];
|
|
setPurchases(updatedPurchases);
|
|
// Don't add to purchasedAlbums yet - wait for approval
|
|
setLatestPurchase(purchase);
|
|
|
|
// Save to localStorage
|
|
localStorage.setItem('purchases', JSON.stringify(updatedPurchases));
|
|
|
|
// Close payment modal and show success modal
|
|
setAlbumToPurchase(null);
|
|
setShowSuccessModal(true);
|
|
};
|
|
|
|
const handleCloseSuccessModal = () => {
|
|
setShowSuccessModal(false);
|
|
// Automatically open the player with the purchased album
|
|
if (albumToPurchase) {
|
|
setCurrentAlbum(albumToPurchase);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<Header onCartClick={() => setCartOpen(true)} />
|
|
|
|
<main className="pt-20">
|
|
{/* Hero Section */}
|
|
<section className="min-h-[60vh] flex items-center justify-center px-4 md:px-8 relative">
|
|
<div className="relative z-10 text-center max-w-4xl mx-auto">
|
|
<div className="paper-card-dark p-8 md:p-12 cardboard-texture">
|
|
<h1 className="text-5xl md:text-7xl font-bold text-paper-light mb-6 tracking-tight">
|
|
Progressive Rock
|
|
<br />
|
|
Reimagined
|
|
</h1>
|
|
<p className="text-xl md:text-2xl text-paper-sand mb-8">
|
|
Explore intricate compositions and sonic landscapes
|
|
</p>
|
|
<button
|
|
onClick={() => {
|
|
const element = document.getElementById('albums');
|
|
element?.scrollIntoView({ behavior: 'smooth' });
|
|
}}
|
|
className="px-8 py-4 bg-paper-sand border-2 border-paper-dark hover:bg-paper-gray font-semibold text-paper-dark transition-all shadow-paper hover:shadow-paper-lg text-lg"
|
|
>
|
|
Explore Albums
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Biography Section */}
|
|
<Biography />
|
|
|
|
{/* Albums Section */}
|
|
<AlbumShowcase
|
|
purchasedAlbums={purchasedAlbums}
|
|
onPlay={handlePlayAlbum}
|
|
onPurchase={handlePurchaseClick}
|
|
/>
|
|
|
|
{/* Footer */}
|
|
<footer className="py-12 px-4 md:px-8 border-t-2 border-paper-brown mt-20">
|
|
<div className="max-w-7xl mx-auto text-center">
|
|
<p className="text-paper-dark font-medium">
|
|
© {new Date().getFullYear()} Parsa. All rights reserved.
|
|
</p>
|
|
<p className="text-sm text-paper-gray mt-2">
|
|
Progressive Rock Composer & Producer
|
|
</p>
|
|
</div>
|
|
</footer>
|
|
</main>
|
|
|
|
{/* Music Player */}
|
|
{currentAlbum && (
|
|
<MusicPlayer
|
|
album={currentAlbum}
|
|
isPurchased={purchasedAlbums.includes(currentAlbum.id)}
|
|
onClose={() => setCurrentAlbum(null)}
|
|
onPurchase={handlePurchaseClick}
|
|
/>
|
|
)}
|
|
|
|
{/* Payment Modal */}
|
|
<PaymentModal
|
|
album={albumToPurchase}
|
|
onClose={() => setAlbumToPurchase(null)}
|
|
onSuccess={handlePurchaseSuccess}
|
|
/>
|
|
|
|
{/* Purchase Success Modal */}
|
|
<PurchaseSuccessModal
|
|
show={showSuccessModal}
|
|
album={albumToPurchase}
|
|
purchase={latestPurchase}
|
|
onClose={handleCloseSuccessModal}
|
|
/>
|
|
|
|
{/* Cart Sidebar */}
|
|
<CartSidebar isOpen={cartOpen} onClose={() => setCartOpen(false)} />
|
|
</>
|
|
);
|
|
}
|