main: added inital version of music shop
Signed-off-by: nfel <nfilsaraee@gmail.com>
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
'use client';
|
||||
|
||||
import { createContext, useContext, useState, useEffect, ReactNode } from 'react';
|
||||
import { Album } from './types';
|
||||
|
||||
interface CartItem {
|
||||
album: Album;
|
||||
quantity: number;
|
||||
}
|
||||
|
||||
interface CartContextType {
|
||||
cartItems: CartItem[];
|
||||
addToCart: (album: Album) => void;
|
||||
removeFromCart: (albumId: string) => void;
|
||||
clearCart: () => void;
|
||||
getCartTotal: () => number;
|
||||
getCartCount: () => number;
|
||||
isInCart: (albumId: string) => boolean;
|
||||
}
|
||||
|
||||
const CartContext = createContext<CartContextType | undefined>(undefined);
|
||||
|
||||
export function CartProvider({ children }: { children: ReactNode }) {
|
||||
const [cartItems, setCartItems] = useState<CartItem[]>([]);
|
||||
|
||||
// Load cart from localStorage on mount
|
||||
useEffect(() => {
|
||||
const savedCart = localStorage.getItem('cart');
|
||||
if (savedCart) {
|
||||
setCartItems(JSON.parse(savedCart));
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Save cart to localStorage whenever it changes
|
||||
useEffect(() => {
|
||||
localStorage.setItem('cart', JSON.stringify(cartItems));
|
||||
}, [cartItems]);
|
||||
|
||||
const addToCart = (album: Album) => {
|
||||
setCartItems((prev) => {
|
||||
const existingItem = prev.find((item) => item.album.id === album.id);
|
||||
if (existingItem) {
|
||||
// Already in cart, don't add again
|
||||
return prev;
|
||||
}
|
||||
return [...prev, { album, quantity: 1 }];
|
||||
});
|
||||
};
|
||||
|
||||
const removeFromCart = (albumId: string) => {
|
||||
setCartItems((prev) => prev.filter((item) => item.album.id !== albumId));
|
||||
};
|
||||
|
||||
const clearCart = () => {
|
||||
setCartItems([]);
|
||||
};
|
||||
|
||||
const getCartTotal = () => {
|
||||
return cartItems.reduce((total, item) => total + item.album.price * item.quantity, 0);
|
||||
};
|
||||
|
||||
const getCartCount = () => {
|
||||
return cartItems.reduce((count, item) => count + item.quantity, 0);
|
||||
};
|
||||
|
||||
const isInCart = (albumId: string) => {
|
||||
return cartItems.some((item) => item.album.id === albumId);
|
||||
};
|
||||
|
||||
return (
|
||||
<CartContext.Provider
|
||||
value={{
|
||||
cartItems,
|
||||
addToCart,
|
||||
removeFromCart,
|
||||
clearCart,
|
||||
getCartTotal,
|
||||
getCartCount,
|
||||
isInCart,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</CartContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useCart() {
|
||||
const context = useContext(CartContext);
|
||||
if (context === undefined) {
|
||||
throw new Error('useCart must be used within a CartProvider');
|
||||
}
|
||||
return context;
|
||||
}
|
||||
+245
@@ -0,0 +1,245 @@
|
||||
import { Album } from './types';
|
||||
|
||||
export const artistBio = {
|
||||
name: "Parsa",
|
||||
title: "Progressive Rock Composer & Producer",
|
||||
bio: `A visionary composer and producer specializing in progressive rock and rock music. With a career spanning over a decade, Parsa has crafted intricate soundscapes that blend complex time signatures, soaring melodies, and powerful instrumentation. His work pushes the boundaries of rock music, drawing inspiration from classic prog rock pioneers while incorporating modern production techniques.
|
||||
|
||||
Each album is a journey through sonic landscapes, featuring elaborate compositions that challenge and reward the listener. From epic 20-minute suites to more concise rock anthems, every piece is meticulously crafted with attention to detail and emotional depth.`,
|
||||
image: "/artist-photo.jpg", // Placeholder
|
||||
socialLinks: {
|
||||
spotify: "#",
|
||||
bandcamp: "#",
|
||||
youtube: "#",
|
||||
instagram: "#"
|
||||
}
|
||||
};
|
||||
|
||||
export const albums: Album[] = [
|
||||
{
|
||||
id: "echoes-of-time",
|
||||
title: "Echoes of Time",
|
||||
coverImage: "/albums/echoes-of-time.jpg",
|
||||
year: 2024,
|
||||
genre: "Progressive Rock",
|
||||
price: 12.99,
|
||||
description: "An epic journey through time and space, featuring complex polyrhythms, atmospheric keyboards, and powerful guitar solos. This concept album tells the story of humanity's relationship with time.",
|
||||
songs: [
|
||||
{
|
||||
id: "echoes-1",
|
||||
title: "Temporal Flux",
|
||||
duration: "8:45",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/echoes-1-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "echoes-2",
|
||||
title: "Clockwork Dreams",
|
||||
duration: "6:23",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/echoes-2-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "echoes-3",
|
||||
title: "The Eternal Now",
|
||||
duration: "12:17",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/echoes-3-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "echoes-4",
|
||||
title: "Yesterday's Tomorrow",
|
||||
duration: "7:56",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/echoes-4-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "echoes-5",
|
||||
title: "Echoes Fade",
|
||||
duration: "15:32",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/echoes-5-full.mp3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "crimson-horizons",
|
||||
title: "Crimson Horizons",
|
||||
coverImage: "/albums/crimson-horizons.jpg",
|
||||
year: 2023,
|
||||
genre: "Progressive Rock",
|
||||
price: 10.99,
|
||||
description: "A darker, heavier exploration of prog rock with crushing riffs and intricate instrumental passages. Features extended improvisational sections and powerful vocals.",
|
||||
songs: [
|
||||
{
|
||||
id: "crimson-1",
|
||||
title: "Red Dawn",
|
||||
duration: "9:12",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/crimson-1-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "crimson-2",
|
||||
title: "Horizon's Edge",
|
||||
duration: "7:45",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/crimson-2-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "crimson-3",
|
||||
title: "Scarlet Skies",
|
||||
duration: "11:03",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/crimson-3-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "crimson-4",
|
||||
title: "Blood Moon Rising",
|
||||
duration: "8:34",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/crimson-4-full.mp3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "synthetic-dreams",
|
||||
title: "Synthetic Dreams",
|
||||
coverImage: "/albums/synthetic-dreams.jpg",
|
||||
year: 2022,
|
||||
genre: "Progressive Rock / Electronic",
|
||||
price: 9.99,
|
||||
description: "A fusion of progressive rock and electronic elements, exploring the intersection of organic and synthetic sounds. Features vintage synthesizers and modern production.",
|
||||
songs: [
|
||||
{
|
||||
id: "synthetic-1",
|
||||
title: "Digital Awakening",
|
||||
duration: "6:54",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/synthetic-1-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "synthetic-2",
|
||||
title: "Neon Pulse",
|
||||
duration: "5:32",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/synthetic-2-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "synthetic-3",
|
||||
title: "Circuit Breaker",
|
||||
duration: "10:21",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/synthetic-3-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "synthetic-4",
|
||||
title: "Ghost in the Machine",
|
||||
duration: "8:47",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/synthetic-4-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "synthetic-5",
|
||||
title: "Synthetic Dreams",
|
||||
duration: "13:29",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/synthetic-5-full.mp3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "showbiz",
|
||||
title: "Showbiz",
|
||||
coverImage: "/albums/showbiz.jpg",
|
||||
year: 1999,
|
||||
genre: "Alternative Rock / Progressive Rock",
|
||||
price: 11.99,
|
||||
description: "A powerful debut album blending alternative rock with progressive elements. Features raw energy, soaring vocals, and guitar-driven anthems that established a unique sound in the late 90s rock scene.",
|
||||
songs: [
|
||||
{
|
||||
id: "showbiz-1",
|
||||
title: "Sunburn",
|
||||
duration: "3:54",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/showbiz-1-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "showbiz-2",
|
||||
title: "Muscle Museum",
|
||||
duration: "4:23",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/showbiz-2-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "showbiz-3",
|
||||
title: "Fillip",
|
||||
duration: "4:02",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/showbiz-3-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "showbiz-4",
|
||||
title: "Falling Down",
|
||||
duration: "4:34",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/showbiz-4-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "showbiz-5",
|
||||
title: "Cave",
|
||||
duration: "4:47",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/showbiz-5-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "showbiz-6",
|
||||
title: "Showbiz",
|
||||
duration: "5:17",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/showbiz-6-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "showbiz-7",
|
||||
title: "Unintended",
|
||||
duration: "3:58",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/showbiz-7-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "showbiz-8",
|
||||
title: "Uno",
|
||||
duration: "3:38",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/showbiz-8-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "showbiz-9",
|
||||
title: "Sober",
|
||||
duration: "4:04",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/showbiz-9-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "showbiz-10",
|
||||
title: "Escape",
|
||||
duration: "3:32",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/showbiz-10-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "showbiz-11",
|
||||
title: "Overdue",
|
||||
duration: "2:27",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/showbiz-11-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "showbiz-12",
|
||||
title: "Hate This & I'll Love You",
|
||||
duration: "5:09",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/showbiz-12-full.mp3"
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
@@ -0,0 +1,24 @@
|
||||
export interface Song {
|
||||
id: string;
|
||||
title: string;
|
||||
duration: string;
|
||||
previewUrl: string; // URL to 30-second preview
|
||||
fullUrl: string; // URL to full song (locked until purchase)
|
||||
}
|
||||
|
||||
export interface Album {
|
||||
id: string;
|
||||
title: string;
|
||||
coverImage: string;
|
||||
year: number;
|
||||
genre: string;
|
||||
price: number;
|
||||
description: string;
|
||||
songs: Song[];
|
||||
}
|
||||
|
||||
export interface Purchase {
|
||||
albumId: string;
|
||||
transactionId: string;
|
||||
purchaseDate: Date;
|
||||
}
|
||||
Reference in New Issue
Block a user