main: added inital version of music shop
Signed-off-by: nfel <nfilsaraee@gmail.com>
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
'use client';
|
||||
|
||||
import { motion } from 'framer-motion';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { FaPlay, FaShoppingCart, FaInfoCircle } from 'react-icons/fa';
|
||||
import { Album } from '@/lib/types';
|
||||
import { useCart } from '@/lib/CartContext';
|
||||
|
||||
interface AlbumCardProps {
|
||||
album: Album;
|
||||
isPurchased: boolean;
|
||||
onPlay: (album: Album) => void;
|
||||
onPurchase: (album: Album) => void;
|
||||
}
|
||||
|
||||
export default function AlbumCard({ album, isPurchased, onPlay, onPurchase }: AlbumCardProps) {
|
||||
const router = useRouter();
|
||||
const { addToCart, isInCart } = useCart();
|
||||
|
||||
const handleAddToCart = (e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
if (!isInCart(album.id) && !isPurchased) {
|
||||
addToCart(album);
|
||||
}
|
||||
};
|
||||
|
||||
const handleViewDetails = (e?: React.MouseEvent) => {
|
||||
if (e) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
router.push(`/album/${album.id}`);
|
||||
};
|
||||
|
||||
const handleCardClick = () => {
|
||||
router.push(`/album/${album.id}`);
|
||||
};
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
viewport={{ once: true }}
|
||||
whileHover={{ y: -10 }}
|
||||
onClick={handleCardClick}
|
||||
className="glass-effect rounded-xl overflow-hidden group cursor-pointer"
|
||||
>
|
||||
{/* Album Cover */}
|
||||
<div className="relative aspect-square bg-gradient-to-br from-primary-600/50 to-primary-800/50 flex items-center justify-center overflow-hidden">
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-accent-cyan/20 to-accent-orange/20"></div>
|
||||
<div className="relative z-10 text-6xl font-bold text-white/20 p-8 text-center">
|
||||
{album.title}
|
||||
</div>
|
||||
|
||||
{/* Overlay on hover */}
|
||||
<div className="absolute inset-0 bg-black/60 opacity-0 group-hover:opacity-100 transition-all duration-300 flex items-center justify-center gap-3">
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onPlay(album);
|
||||
}}
|
||||
className="p-4 bg-accent-cyan hover:bg-accent-cyan/80 rounded-full transition-all glow-cyan"
|
||||
aria-label="Play preview"
|
||||
>
|
||||
<FaPlay className="text-2xl text-white" />
|
||||
</button>
|
||||
<button
|
||||
onClick={(e) => handleViewDetails(e)}
|
||||
className="p-4 bg-white/20 hover:bg-white/30 rounded-full transition-all"
|
||||
aria-label="View details"
|
||||
>
|
||||
<FaInfoCircle className="text-2xl text-white" />
|
||||
</button>
|
||||
{!isPurchased && (
|
||||
<button
|
||||
onClick={handleAddToCart}
|
||||
disabled={isInCart(album.id)}
|
||||
className={`p-4 ${
|
||||
isInCart(album.id)
|
||||
? 'bg-gray-700 cursor-not-allowed'
|
||||
: 'bg-accent-orange hover:bg-accent-orange/80 glow-orange'
|
||||
} rounded-full transition-all`}
|
||||
aria-label="Add to cart"
|
||||
>
|
||||
<FaShoppingCart className="text-2xl text-white" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Purchased Badge */}
|
||||
{isPurchased && (
|
||||
<div className="absolute top-4 right-4 bg-accent-cyan text-white px-3 py-1 rounded-full text-sm font-semibold">
|
||||
Owned
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Album Info */}
|
||||
<div className="p-6 space-y-3">
|
||||
<div>
|
||||
<h3 className="text-xl font-bold text-white group-hover:text-accent-cyan transition-colors">
|
||||
{album.title}
|
||||
</h3>
|
||||
<p className="text-sm text-gray-400">{album.year} • {album.genre}</p>
|
||||
</div>
|
||||
|
||||
<p className="text-gray-300 text-sm line-clamp-2">{album.description}</p>
|
||||
|
||||
<div className="flex items-center justify-between pt-2">
|
||||
<span className="text-sm text-gray-400">{album.songs.length} tracks</span>
|
||||
{!isPurchased && (
|
||||
<span className="text-lg font-bold text-accent-orange">${album.price}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user