mirror of
https://github.com/M4X809/list-of-lp.git
synced 2025-12-25 19:12:48 +00:00
Refactor AlbumCard and BackButton components for improved theming and styling
- Updated AlbumCard to use a div wrapper instead of Card for layout, enhancing styling with dynamic theme colors. - Improved BackButton to accept a theme prop, allowing for dynamic styling on hover. - Adjusted layout.tsx to remove unnecessary imports and streamline the MantineProvider usage. - Enhanced album detail page with new theming and styling for better visual consistency. - Added Spotify URLs for tracks in the album list for better integration with music services.
This commit is contained in:
parent
a8097d84fc
commit
6ce4950d54
7 changed files with 620 additions and 240 deletions
|
|
@ -23,60 +23,108 @@ export default function AlbumCard({ album }: { album: Album }) {
|
|||
const theme = getThemeColors(album.id);
|
||||
|
||||
return (
|
||||
<Card
|
||||
component={Link}
|
||||
href={`/album/${album.id}`}
|
||||
className="group col-span-1 cursor-pointer border border-gray-700 backdrop-blur-sm transition-all duration-300 hover:scale-105 hover:bg-gray-800/70 hover:shadow-2xl hover:shadow-black/20"
|
||||
<div
|
||||
style={{
|
||||
background: `linear-gradient(to bottom, ${theme.bg})`,
|
||||
border: `1px solid ${theme.border.DEFAULT}`,
|
||||
boxShadow: `0 4px 20px ${theme.primary.DEFAULT}20`,
|
||||
overflow: "hidden",
|
||||
borderRadius: "8px",
|
||||
}}
|
||||
className="group relative col-span-1 cursor-pointer rounded-lg transition-all duration-300 hover:scale-105 hover:shadow-2xl"
|
||||
>
|
||||
<Box className="relative overflow-hidden rounded-lg">
|
||||
<Image
|
||||
src={image}
|
||||
alt={label}
|
||||
radius="md"
|
||||
className="aspect-square w-full object-cover transition-transform duration-500 group-hover:scale-110"
|
||||
style={{ viewTransitionName: `album-card-image-${album.id}` }}
|
||||
/>
|
||||
<Box className="absolute inset-0 bg-linear-to-t from-black/80 via-transparent to-transparent opacity-0 transition-opacity duration-300 group-hover:opacity-100" />
|
||||
</Box>
|
||||
|
||||
<Box className="space-y-3 p-4">
|
||||
<Text
|
||||
size="xl"
|
||||
fw={700}
|
||||
className="text-white transition-colors group-hover:text-purple-300"
|
||||
style={{ viewTransitionName: `album-card-title-${album.id}` }}
|
||||
<Card
|
||||
component={Link}
|
||||
href={`/album/${album.id}`}
|
||||
style={{
|
||||
background: theme.background.gradient,
|
||||
viewTransitionName: `album-card-background-${album.id}`,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
className="relative overflow-hidden rounded-lg"
|
||||
style={{
|
||||
border: `2px solid ${theme.border.light}`,
|
||||
borderRadius: "8px",
|
||||
padding: "2px",
|
||||
background: theme.background.secondary,
|
||||
viewTransitionName: `album-card-image-${album.id}`,
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</Text>
|
||||
<Box>
|
||||
<Image
|
||||
src={image}
|
||||
alt={label}
|
||||
radius="md"
|
||||
className="aspect-square w-full object-cover transition-transform duration-500 group-hover:scale-110"
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box className="space-y-3 p-4">
|
||||
<Text
|
||||
size="xl"
|
||||
fw={700}
|
||||
className="transition-colors"
|
||||
style={{
|
||||
viewTransitionName: `album-card-title-${album.id}`,
|
||||
color: theme.text.primary,
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</Text>
|
||||
|
||||
<Text size="sm" className="text-gray-400" style={{ viewTransitionName: `album-card-release-date-${album.id}` }}>
|
||||
Released:{" "}
|
||||
{new Date(releaseDate).toLocaleDateString("en-US", {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
})}
|
||||
</Text>
|
||||
<Text
|
||||
size="sm"
|
||||
style={{
|
||||
viewTransitionName: `album-card-release-date-${album.id}`,
|
||||
color: theme.text.secondary,
|
||||
}}
|
||||
>
|
||||
<span style={{ color: theme.accent.DEFAULT, fontWeight: 600 }}>Released: </span>
|
||||
{new Date(releaseDate).toLocaleDateString("en-US", {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
})}
|
||||
</Text>
|
||||
|
||||
<Group gap="xs">
|
||||
<Badge color="purple" variant="light" size="sm" className="bg-purple-500/20 text-purple-300">
|
||||
{songs.count} Songs
|
||||
</Badge>
|
||||
{songs.emilyLiveSongs > 0 && (
|
||||
<Badge color="pink" variant="light" size="sm" className="bg-pink-500/20 text-pink-300">
|
||||
{songs.emilyLiveSongs} Emily Live
|
||||
<Group gap="xs">
|
||||
<Badge
|
||||
size="sm"
|
||||
variant="filled"
|
||||
style={{
|
||||
background: theme.primary.DEFAULT,
|
||||
color: theme.text.contrast,
|
||||
}}
|
||||
>
|
||||
{songs.count} Songs
|
||||
</Badge>
|
||||
)}
|
||||
{songs.lpLiveSongs > 0 && (
|
||||
<Badge color="blue" variant="light" size="sm" className="bg-blue-500/20 text-blue-300">
|
||||
{songs.lpLiveSongs} LP Live
|
||||
</Badge>
|
||||
)}
|
||||
</Group>
|
||||
</Box>
|
||||
</Card>
|
||||
{songs.emilyLiveSongs > 0 && (
|
||||
<Badge
|
||||
size="sm"
|
||||
variant="filled"
|
||||
style={{
|
||||
background: theme.badges.liveEmily,
|
||||
color: theme.text.contrast,
|
||||
}}
|
||||
>
|
||||
{songs.emilyLiveSongs} Emily Live
|
||||
</Badge>
|
||||
)}
|
||||
{songs.lpLiveSongs > 0 && (
|
||||
<Badge
|
||||
size="sm"
|
||||
variant="filled"
|
||||
style={{
|
||||
background: theme.badges.liveLP,
|
||||
color: theme.text.contrast,
|
||||
}}
|
||||
>
|
||||
{songs.lpLiveSongs} LP Live
|
||||
</Badge>
|
||||
)}
|
||||
</Group>
|
||||
</Box>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,31 @@
|
|||
|
||||
import { Button } from "@mantine/core";
|
||||
import { Link } from "next-view-transitions";
|
||||
import type { AlbumTheme } from "@/lib/themes";
|
||||
|
||||
export default function BackButton() {
|
||||
interface BackButtonProps {
|
||||
theme?: AlbumTheme;
|
||||
}
|
||||
|
||||
export default function BackButton({ theme }: BackButtonProps) {
|
||||
return (
|
||||
<Button
|
||||
component={Link}
|
||||
href="/"
|
||||
variant="subtle"
|
||||
color="gray"
|
||||
className="mb-8 text-gray-300 hover:bg-gray-800 hover:text-white"
|
||||
className="mb-8 transition-all duration-200"
|
||||
style={{
|
||||
color: theme?.text.secondary || "#d1d5db",
|
||||
backgroundColor: "transparent",
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
e.currentTarget.style.backgroundColor = theme?.card.background || "rgba(31, 41, 55, 0.5)";
|
||||
e.currentTarget.style.color = theme?.text.primary || "#ffffff";
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
e.currentTarget.style.backgroundColor = "transparent";
|
||||
e.currentTarget.style.color = theme?.text.secondary || "#d1d5db";
|
||||
}}
|
||||
>
|
||||
← Back to Albums
|
||||
</Button>
|
||||
|
|
|
|||
110
src/Components/TrackCard.tsx
Normal file
110
src/Components/TrackCard.tsx
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
"use client";
|
||||
|
||||
import { Card, Group, Text, Badge, Box } from "@mantine/core";
|
||||
import { useState } from "react";
|
||||
import type { AlbumTheme } from "@/lib/themes";
|
||||
import type { Track } from "@/lib/ListTypes";
|
||||
|
||||
interface TrackCardProps {
|
||||
track: Track;
|
||||
index: number;
|
||||
theme: AlbumTheme;
|
||||
}
|
||||
|
||||
export default function TrackCard({ track, index, theme }: TrackCardProps) {
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
|
||||
return (
|
||||
<Card
|
||||
className="backdrop-blur-sm transition-all duration-300"
|
||||
style={{
|
||||
background: isHovered ? theme.card.backgroundHover : theme.card.background,
|
||||
border: `1px solid ${isHovered ? theme.border.light : theme.card.border}`,
|
||||
cursor: "pointer",
|
||||
// transform: isHovered ? "translateY(-2px)" : "translateY(0)",
|
||||
boxShadow: isHovered ? `0 8px 24px ${theme.primary.DEFAULT}30` : "none",
|
||||
}}
|
||||
onMouseEnter={() => setIsHovered(true)}
|
||||
onMouseLeave={() => setIsHovered(false)}
|
||||
>
|
||||
<Group justify="space-between" align="center">
|
||||
<Group gap="md">
|
||||
<Box
|
||||
style={{
|
||||
minWidth: "40px",
|
||||
height: "40px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
background: theme.primary.DEFAULT,
|
||||
borderRadius: "8px",
|
||||
fontWeight: 700,
|
||||
fontSize: "18px",
|
||||
color: theme.text.contrast,
|
||||
boxShadow: `0 4px 12px ${theme.primary.DEFAULT}60`,
|
||||
}}
|
||||
>
|
||||
{index + 1}
|
||||
</Box>
|
||||
<Text size="lg" fw={500} style={{ color: theme.text.primary }}>
|
||||
{track.label}
|
||||
</Text>
|
||||
</Group>
|
||||
|
||||
<Group gap="md">
|
||||
<Text
|
||||
size="sm"
|
||||
fw={500}
|
||||
style={{
|
||||
color: theme.text.muted,
|
||||
fontFamily: "monospace",
|
||||
background: theme.background.tertiary,
|
||||
padding: "4px 12px",
|
||||
borderRadius: "6px",
|
||||
}}
|
||||
>
|
||||
{track.duration}
|
||||
</Text>
|
||||
<Group gap="xs">
|
||||
{track.studioUrl && (
|
||||
<Badge
|
||||
size="sm"
|
||||
variant="filled"
|
||||
style={{
|
||||
background: theme.badges.studio,
|
||||
color: theme.text.contrast,
|
||||
}}
|
||||
>
|
||||
Studio
|
||||
</Badge>
|
||||
)}
|
||||
{track.emilyLiveUrl && (
|
||||
<Badge
|
||||
size="sm"
|
||||
variant="filled"
|
||||
style={{
|
||||
background: theme.badges.liveEmily,
|
||||
color: theme.text.contrast,
|
||||
}}
|
||||
>
|
||||
Emily Live
|
||||
</Badge>
|
||||
)}
|
||||
{track.lpLiveUrl && (
|
||||
<Badge
|
||||
size="sm"
|
||||
variant="filled"
|
||||
style={{
|
||||
background: theme.badges.liveLP,
|
||||
color: theme.text.contrast,
|
||||
}}
|
||||
>
|
||||
LP Live
|
||||
</Badge>
|
||||
)}
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
import { notFound } from "next/navigation";
|
||||
import { Box, Container, Title, Text, Group, Badge, Card, Image, Stack, Grid, GridCol } from "@mantine/core";
|
||||
import { Box, Container, Title, Text, Image, Stack, Grid, GridCol } from "@mantine/core";
|
||||
import { albums } from "../../../lib/list";
|
||||
import BackButton from "../../../Components/BackButton";
|
||||
import { getThemeColors } from "@/lib/themes";
|
||||
import TrackCard from "@/Components/TrackCard";
|
||||
|
||||
export function generateStaticParams() {
|
||||
return albums.map((album) => ({
|
||||
|
|
@ -34,95 +35,96 @@ export default async function AlbumDetail({ params }: { params: Promise<{ albumI
|
|||
notFound();
|
||||
}
|
||||
|
||||
// Theme colors based on album
|
||||
|
||||
const theme = getThemeColors(albumId);
|
||||
|
||||
return (
|
||||
<Box className="min-h-screen">
|
||||
<Box
|
||||
className="min-h-screen"
|
||||
style={{
|
||||
background: theme.background.gradient,
|
||||
viewTransitionName: `album-card-background-${album.id}`,
|
||||
}}
|
||||
>
|
||||
<Container size="xl" className="py-12">
|
||||
{/* Back Button */}
|
||||
<BackButton />
|
||||
<BackButton theme={theme} />
|
||||
|
||||
<Grid columns={5} gutter={"xl"}>
|
||||
<Grid columns={5} gutter={"xl"} className="mb-12">
|
||||
<GridCol span={"content"}>
|
||||
<Image
|
||||
src={album.image}
|
||||
alt={album.label}
|
||||
h={200}
|
||||
w={200}
|
||||
className="aspect-square!"
|
||||
style={{ viewTransitionName: `album-card-image-${album.id}` }}
|
||||
/>
|
||||
<Box
|
||||
style={{
|
||||
border: `3px solid ${theme.border.light}`,
|
||||
borderRadius: "8px",
|
||||
padding: "4px",
|
||||
background: theme.background.secondary,
|
||||
boxShadow: `0 8px 32px ${theme.primary.DEFAULT}40`,
|
||||
viewTransitionName: `album-card-image-${album.id}`,
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
src={album.image}
|
||||
alt={album.label}
|
||||
h={200}
|
||||
w={200}
|
||||
className="aspect-square!"
|
||||
style={{
|
||||
borderRadius: "4px",
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</GridCol>
|
||||
|
||||
<GridCol span={"auto"}>
|
||||
<Title
|
||||
order={1}
|
||||
className="text-6xl font-bold text-white"
|
||||
style={{ viewTransitionName: `album-card-title-${album.id}` }}
|
||||
className="mb-3 text-6xl font-bold"
|
||||
style={{
|
||||
viewTransitionName: `album-card-title-${album.id}`,
|
||||
color: theme.text.primary,
|
||||
textShadow: `0 0 20px ${theme.primary.DEFAULT}80`,
|
||||
}}
|
||||
>
|
||||
{album.label}
|
||||
</Title>
|
||||
<Text size="xl" className="text-gray-400" style={{ viewTransitionName: `album-card-release-date-${album.id}` }}>
|
||||
Released:{" "}
|
||||
<Text
|
||||
size="xl"
|
||||
className="mb-4"
|
||||
style={{
|
||||
viewTransitionName: `album-card-release-date-${album.id}`,
|
||||
color: theme.text.secondary,
|
||||
}}
|
||||
>
|
||||
<span style={{ color: theme.accent.DEFAULT, fontWeight: 600 }}>Released: </span>
|
||||
{new Date(album.releaseDate).toLocaleDateString("en-US", {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
})}
|
||||
</Text>
|
||||
<Text className="text-gray-400">{album.description}</Text>
|
||||
<Text size="md" style={{ color: theme.text.muted, lineHeight: 1.6 }}>
|
||||
{album.description}
|
||||
</Text>
|
||||
</GridCol>
|
||||
</Grid>
|
||||
|
||||
{/* Track List */}
|
||||
{album.tracks.length > 0 && (
|
||||
<Box>
|
||||
<Title order={2} className="mb-6 text-3xl font-bold text-white">
|
||||
<Title
|
||||
order={2}
|
||||
className="mb-6 text-3xl font-bold"
|
||||
style={{
|
||||
color: theme.text.primary,
|
||||
borderBottom: `2px solid ${theme.border.light}`,
|
||||
paddingBottom: "12px",
|
||||
}}
|
||||
>
|
||||
Track List
|
||||
</Title>
|
||||
|
||||
<Stack gap="sm">
|
||||
<Stack gap="xs" pt={"md"} pb={50}>
|
||||
{album.tracks.map((track, index) => (
|
||||
<Card
|
||||
key={track.id}
|
||||
className="border border-gray-700 bg-gray-800/30 backdrop-blur-sm transition-all duration-200 hover:bg-gray-800/50"
|
||||
>
|
||||
<Group justify="space-between" align="center">
|
||||
<Group gap="md">
|
||||
<Text size="lg" fw={600} style={{ color: theme.primary }} className="min-w-8">
|
||||
{index + 1}
|
||||
</Text>
|
||||
<Text size="lg" className="text-white">
|
||||
{track.label}
|
||||
</Text>
|
||||
</Group>
|
||||
|
||||
<Group gap="md">
|
||||
<Text size="sm" className="text-gray-400">
|
||||
{track.duration}
|
||||
</Text>
|
||||
<Group gap="xs">
|
||||
{track.studioUrl && (
|
||||
<Badge size="sm" color="green" variant="light">
|
||||
Studio
|
||||
</Badge>
|
||||
)}
|
||||
{track.emilyLiveUrl && (
|
||||
<Badge size="sm" color="pink" variant="light">
|
||||
Emily Live
|
||||
</Badge>
|
||||
)}
|
||||
{track.lpLiveUrl && (
|
||||
<Badge size="sm" color="blue" variant="light">
|
||||
LP Live
|
||||
</Badge>
|
||||
)}
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</Card>
|
||||
<TrackCard key={track.id} track={track} index={index} theme={theme} />
|
||||
))}
|
||||
</Stack>
|
||||
</Box>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import "@mantine/core/styles.css";
|
||||
import "../index.css";
|
||||
import { MantineProvider, ColorSchemeScript } from "@mantine/core";
|
||||
import { MantineProvider } from "@mantine/core";
|
||||
import { ViewTransitions } from "next-view-transitions";
|
||||
import { Nunito } from "next/font/google";
|
||||
|
||||
|
|
|
|||
238
src/lib/list.ts
238
src/lib/list.ts
|
|
@ -273,111 +273,135 @@ export const albums: Album[] = [
|
|||
},
|
||||
],
|
||||
},
|
||||
// {
|
||||
// id: "minutes-to-midnight",
|
||||
// label: "Minutes to Midnight",
|
||||
// releaseDate: "2007-05-14",
|
||||
// image: "/minutes_to_midnight.jpg",
|
||||
// url: "/minutes-to-midnight",
|
||||
// description:
|
||||
// "Minutes to Midnight is the third studio album by American rock band Linkin Park, released on May 14, 2007, by Warner Bros. Records. The album marked a departure from the band's previous nu-metal sound, incorporating more alternative rock and experimental elements.",
|
||||
// tracks: [
|
||||
// {
|
||||
// id: "minutes-to-midnight-1",
|
||||
// label: "Wake",
|
||||
// duration: "01:40",
|
||||
// studioUrl: null,
|
||||
// emilyLiveUrl: null,
|
||||
// lpLiveUrl: null,
|
||||
// },
|
||||
// {
|
||||
// id: "minutes-to-midnight-2",
|
||||
// label: "Given Up",
|
||||
// duration: "03:09",
|
||||
// studioUrl: null,
|
||||
// emilyLiveUrl: null,
|
||||
// lpLiveUrl: null,
|
||||
// },
|
||||
// {
|
||||
// id: "minutes-to-midnight-3",
|
||||
// label: "Leave Out All the Rest",
|
||||
// duration: "03:29",
|
||||
// studioUrl: null,
|
||||
// emilyLiveUrl: null,
|
||||
// lpLiveUrl: null,
|
||||
// },
|
||||
// {
|
||||
// id: "minutes-to-midnight-4",
|
||||
// label: "Bleed It Out",
|
||||
// duration: "02:44",
|
||||
// studioUrl: null,
|
||||
// emilyLiveUrl: null,
|
||||
// lpLiveUrl: null,
|
||||
// },
|
||||
// {
|
||||
// id: "minutes-to-midnight-5",
|
||||
// label: "Shadow of the Day",
|
||||
// duration: "04:49",
|
||||
// studioUrl: null,
|
||||
// emilyLiveUrl: null,
|
||||
// lpLiveUrl: null,
|
||||
// },
|
||||
// {
|
||||
// id: "minutes-to-midnight-6",
|
||||
// label: "What I've Done",
|
||||
// duration: "03:25",
|
||||
// studioUrl: null,
|
||||
// emilyLiveUrl: null,
|
||||
// lpLiveUrl: null,
|
||||
// },
|
||||
// {
|
||||
// id: "minutes-to-midnight-7",
|
||||
// label: "Hands Held High",
|
||||
// duration: "03:53",
|
||||
// studioUrl: null,
|
||||
// emilyLiveUrl: null,
|
||||
// lpLiveUrl: null,
|
||||
// },
|
||||
// {
|
||||
// id: "minutes-to-midnight-8",
|
||||
// label: "No More Sorrow",
|
||||
// duration: "03:41",
|
||||
// studioUrl: null,
|
||||
// emilyLiveUrl: null,
|
||||
// lpLiveUrl: null,
|
||||
// },
|
||||
// {
|
||||
// id: "minutes-to-midnight-9",
|
||||
// label: "Valentine's Day",
|
||||
// duration: "03:16",
|
||||
// studioUrl: null,
|
||||
// emilyLiveUrl: null,
|
||||
// lpLiveUrl: null,
|
||||
// },
|
||||
// {
|
||||
// id: "minutes-to-midnight-10",
|
||||
// label: "In Between",
|
||||
// duration: "03:16",
|
||||
// studioUrl: null,
|
||||
// emilyLiveUrl: null,
|
||||
// lpLiveUrl: null,
|
||||
// },
|
||||
// {
|
||||
// id: "minutes-to-midnight-11",
|
||||
// label: "In Pieces",
|
||||
// duration: "03:38",
|
||||
// studioUrl: null,
|
||||
// emilyLiveUrl: null,
|
||||
// lpLiveUrl: null,
|
||||
// },
|
||||
// {
|
||||
// id: "minutes-to-midnight-12",
|
||||
// label: "The Little Things Give You Away",
|
||||
// duration: "06:23",
|
||||
// studioUrl: null,
|
||||
// emilyLiveUrl: null,
|
||||
// lpLiveUrl: null,
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
{
|
||||
id: "minutes-to-midnight",
|
||||
label: "Minutes to Midnight",
|
||||
releaseDate: "2007-05-14",
|
||||
image: "/minutes_to_midnight.jpg",
|
||||
url: "/minutes-to-midnight",
|
||||
description:
|
||||
"Minutes to Midnight is the third studio album by American rock band Linkin Park, released on May 14, 2007, by Warner Bros. Records. The album marked a departure from the band's previous nu-metal sound, incorporating more alternative rock and experimental elements.",
|
||||
tracks: [
|
||||
{
|
||||
id: "minutes-to-midnight-1",
|
||||
label: "Wake",
|
||||
duration: "01:40",
|
||||
studioUrl: null,
|
||||
emilyLiveUrl: null,
|
||||
lpLiveUrl: null,
|
||||
|
||||
__SPOTIFY_URL__: "https://open.spotify.com/track/0GkuKdv0osuL9QhfnXqVNP?si=0491e2d35b0a4e12",
|
||||
},
|
||||
{
|
||||
id: "minutes-to-midnight-2",
|
||||
label: "Given Up",
|
||||
duration: "03:09",
|
||||
studioUrl: null,
|
||||
emilyLiveUrl: null,
|
||||
lpLiveUrl: null,
|
||||
|
||||
__SPOTIFY_URL__: "https://open.spotify.com/track/1fLlRApgzxWweF1JTf8yM5?si=9b22e697bdd640e8",
|
||||
},
|
||||
{
|
||||
id: "minutes-to-midnight-3",
|
||||
label: "Leave Out All the Rest",
|
||||
duration: "03:29",
|
||||
studioUrl: null,
|
||||
emilyLiveUrl: null,
|
||||
lpLiveUrl: null,
|
||||
|
||||
__SPOTIFY_URL__: "https://open.spotify.com/track/0sp00HSXkQyqTa6QqM0O8V?si=c9ad349e7f164919",
|
||||
},
|
||||
{
|
||||
id: "minutes-to-midnight-4",
|
||||
label: "Bleed It Out",
|
||||
duration: "02:44",
|
||||
studioUrl: null,
|
||||
emilyLiveUrl: null,
|
||||
lpLiveUrl: null,
|
||||
|
||||
__SPOTIFY_URL__: "https://open.spotify.com/track/0UFDKFqW2oGspYeYqo9wjA?si=2f4e310a85674523",
|
||||
},
|
||||
{
|
||||
id: "minutes-to-midnight-5",
|
||||
label: "Shadow of the Day",
|
||||
duration: "04:49",
|
||||
studioUrl: null,
|
||||
emilyLiveUrl: null,
|
||||
lpLiveUrl: null,
|
||||
|
||||
__SPOTIFY_URL__: "https://open.spotify.com/track/0OYcEfskah1egYHjYRvbg1?si=e7fe66722b7544d9",
|
||||
},
|
||||
{
|
||||
id: "minutes-to-midnight-6",
|
||||
label: "What I've Done",
|
||||
duration: "03:25",
|
||||
studioUrl: null,
|
||||
emilyLiveUrl: null,
|
||||
lpLiveUrl: null,
|
||||
|
||||
__SPOTIFY_URL__: "https://open.spotify.com/track/18lR4BzEs7e3qzc0KVkTpU?si=f04a6e933aab4ba0",
|
||||
},
|
||||
{
|
||||
id: "minutes-to-midnight-7",
|
||||
label: "Hands Held High",
|
||||
duration: "03:53",
|
||||
studioUrl: null,
|
||||
emilyLiveUrl: null,
|
||||
lpLiveUrl: null,
|
||||
|
||||
__SPOTIFY_URL__: "https://open.spotify.com/track/0m7mTaFGMiKI3rBJpYknip?si=e382b6252c7c427a",
|
||||
},
|
||||
{
|
||||
id: "minutes-to-midnight-8",
|
||||
label: "No More Sorrow",
|
||||
duration: "03:41",
|
||||
studioUrl: null,
|
||||
emilyLiveUrl: null,
|
||||
lpLiveUrl: null,
|
||||
|
||||
__SPOTIFY_URL__: "https://open.spotify.com/track/4CWhc9FaMMfBTt4ANjfbOf?si=dd3a00c6453c4737",
|
||||
},
|
||||
{
|
||||
id: "minutes-to-midnight-9",
|
||||
label: "Valentine's Day",
|
||||
duration: "03:16",
|
||||
studioUrl: null,
|
||||
emilyLiveUrl: null,
|
||||
lpLiveUrl: null,
|
||||
|
||||
__SPOTIFY_URL__: "https://open.spotify.com/track/2vfshZvISOKy2Je7wQBWOV?si=51d75042da314fa4",
|
||||
},
|
||||
{
|
||||
id: "minutes-to-midnight-10",
|
||||
label: "In Between",
|
||||
duration: "03:16",
|
||||
studioUrl: null,
|
||||
emilyLiveUrl: null,
|
||||
lpLiveUrl: null,
|
||||
|
||||
__SPOTIFY_URL__: "https://open.spotify.com/track/2ysXuQd8uOfSMZcMRR5Ux4?si=3ae5e92155874795",
|
||||
},
|
||||
{
|
||||
id: "minutes-to-midnight-11",
|
||||
label: "In Pieces",
|
||||
duration: "03:38",
|
||||
studioUrl: null,
|
||||
emilyLiveUrl: null,
|
||||
lpLiveUrl: null,
|
||||
|
||||
__SPOTIFY_URL__: "https://open.spotify.com/track/7jeI6EdY0elPSNz80mAKS8?si=983410366a774f68",
|
||||
},
|
||||
{
|
||||
id: "minutes-to-midnight-12",
|
||||
label: "The Little Things Give You Away",
|
||||
duration: "06:23",
|
||||
studioUrl: null,
|
||||
emilyLiveUrl: null,
|
||||
lpLiveUrl: null,
|
||||
|
||||
__SPOTIFY_URL__: "https://open.spotify.com/track/7jeI6EdY0elPSNz80mAKS8?si=679b76c359004769",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,25 +1,205 @@
|
|||
export const getThemeColors = (albumId: string) => {
|
||||
export interface AlbumTheme {
|
||||
// Primary color palette
|
||||
primary: {
|
||||
DEFAULT: string;
|
||||
light: string;
|
||||
dark: string;
|
||||
100: string;
|
||||
500: string;
|
||||
900: string;
|
||||
};
|
||||
// Secondary color palette
|
||||
secondary: {
|
||||
DEFAULT: string;
|
||||
light: string;
|
||||
dark: string;
|
||||
};
|
||||
// Accent colors
|
||||
accent: {
|
||||
DEFAULT: string;
|
||||
light: string;
|
||||
dark: string;
|
||||
};
|
||||
// Background variations
|
||||
background: {
|
||||
primary: string;
|
||||
secondary: string;
|
||||
tertiary: string;
|
||||
gradient: string;
|
||||
};
|
||||
// Text colors
|
||||
text: {
|
||||
primary: string;
|
||||
secondary: string;
|
||||
muted: string;
|
||||
contrast: string;
|
||||
};
|
||||
// Border colors
|
||||
border: {
|
||||
DEFAULT: string;
|
||||
light: string;
|
||||
focus: string;
|
||||
};
|
||||
// Badge colors
|
||||
badges: {
|
||||
studio: string;
|
||||
liveEmily: string;
|
||||
liveLP: string;
|
||||
};
|
||||
// Card styling
|
||||
card: {
|
||||
background: string;
|
||||
backgroundHover: string;
|
||||
border: string;
|
||||
};
|
||||
}
|
||||
|
||||
const themes: Record<string, AlbumTheme> = {
|
||||
"hybrid-theory": {
|
||||
primary: {
|
||||
DEFAULT: "#47090E",
|
||||
light: "#95121d",
|
||||
dark: "#1F0506",
|
||||
100: "#f6b3b8",
|
||||
500: "#47090E",
|
||||
900: "#0f0203",
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: "#8C786C",
|
||||
light: "#bbaea7",
|
||||
dark: "#554841",
|
||||
},
|
||||
accent: {
|
||||
DEFAULT: "#ec6672",
|
||||
light: "#f6b3b8",
|
||||
dark: "#95121d",
|
||||
},
|
||||
background: {
|
||||
primary: "#050404",
|
||||
secondary: "#1F0506",
|
||||
tertiary: "#3D3D39",
|
||||
gradient: "linear-gradient(135deg, #050404 0%, #47090E 50%, #1F0506 100%)",
|
||||
},
|
||||
text: {
|
||||
primary: "#e8e4e2",
|
||||
secondary: "#d2c9c4",
|
||||
muted: "#a49389",
|
||||
contrast: "#ffffff",
|
||||
},
|
||||
border: {
|
||||
DEFAULT: "#3D3D39",
|
||||
light: "#8C786C",
|
||||
focus: "#47090E",
|
||||
},
|
||||
badges: {
|
||||
studio: "#95121d",
|
||||
liveEmily: "#ec6672",
|
||||
liveLP: "#8C786C",
|
||||
},
|
||||
card: {
|
||||
background: "rgba(61, 61, 57, 0.3)",
|
||||
backgroundHover: "rgba(71, 9, 14, 0.4)",
|
||||
border: "#3D3D39",
|
||||
},
|
||||
},
|
||||
meteora: {
|
||||
primary: {
|
||||
DEFAULT: "#8B7B65",
|
||||
light: "#9A8B71",
|
||||
dark: "#55493C",
|
||||
100: "#ebe8e2",
|
||||
500: "#8B7B65",
|
||||
900: "#1c1914",
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: "#9A8B71",
|
||||
light: "#c2b9a9",
|
||||
dark: "#7c6f58",
|
||||
},
|
||||
accent: {
|
||||
DEFAULT: "#bbb0a1",
|
||||
light: "#d6d0c6",
|
||||
dark: "#a4917e",
|
||||
},
|
||||
background: {
|
||||
primary: "#241C16",
|
||||
secondary: "#32271F",
|
||||
tertiary: "#55493C",
|
||||
gradient: "linear-gradient(135deg, #241C16 0%, #32271F 50%, #55493C 100%)",
|
||||
},
|
||||
text: {
|
||||
primary: "#e8e5e0",
|
||||
secondary: "#d2cac0",
|
||||
muted: "#a49682",
|
||||
contrast: "#ffffff",
|
||||
},
|
||||
border: {
|
||||
DEFAULT: "#55493C",
|
||||
light: "#8B7B65",
|
||||
focus: "#9A8B71",
|
||||
},
|
||||
badges: {
|
||||
studio: "#8B7B65",
|
||||
liveEmily: "#bbb0a1",
|
||||
liveLP: "#9A8B71",
|
||||
},
|
||||
card: {
|
||||
background: "rgba(85, 73, 60, 0.3)",
|
||||
backgroundHover: "rgba(139, 123, 101, 0.4)",
|
||||
border: "#55493C",
|
||||
},
|
||||
},
|
||||
"minutes-to-midnight": {
|
||||
primary: {
|
||||
DEFAULT: "#77716F",
|
||||
light: "#A09D9C",
|
||||
dark: "#292527",
|
||||
100: "#fafafa",
|
||||
500: "#77716F",
|
||||
900: "#181716",
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: "#A09D9C",
|
||||
light: "#c6c4c4",
|
||||
dark: "#615e5d",
|
||||
},
|
||||
accent: {
|
||||
DEFAULT: "#928d8b",
|
||||
light: "#b3b1b0",
|
||||
dark: "#5f5a59",
|
||||
},
|
||||
background: {
|
||||
primary: "#292527",
|
||||
secondary: "#2f2d2d",
|
||||
tertiary: "#474443",
|
||||
gradient: "linear-gradient(135deg, #292527 0%, #474443 50%, #5f5a59 100%)",
|
||||
},
|
||||
text: {
|
||||
primary: "#F2F1F0",
|
||||
secondary: "#d9d8d7",
|
||||
muted: "#b3b1b0",
|
||||
contrast: "#FEFFFC",
|
||||
},
|
||||
border: {
|
||||
DEFAULT: "#474443",
|
||||
light: "#77716F",
|
||||
focus: "#A09D9C",
|
||||
},
|
||||
badges: {
|
||||
studio: "#77716F",
|
||||
liveEmily: "#928d8b",
|
||||
liveLP: "#A09D9C",
|
||||
},
|
||||
card: {
|
||||
background: "rgba(71, 68, 67, 0.3)",
|
||||
backgroundHover: "rgba(119, 113, 111, 0.4)",
|
||||
border: "#474443",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const getThemeColors = (albumId: string): AlbumTheme => {
|
||||
return themes[albumId] || themes["hybrid-theory"];
|
||||
};
|
||||
|
||||
const themes: Record<string, { primary: string; secondary: string; accent: string; bg: string }> = {
|
||||
"hybrid-theory": {
|
||||
primary: "#ff6b35",
|
||||
secondary: "#f7931e",
|
||||
accent: "#ff1744",
|
||||
bg: "from-orange-900 via-red-900 to-orange-800",
|
||||
},
|
||||
meteora: {
|
||||
primary: "#8b5cf6",
|
||||
secondary: "#a855f7",
|
||||
accent: "#ec4899",
|
||||
bg: "from-purple-900 via-pink-900 to-purple-800",
|
||||
},
|
||||
"minutes-to-midnight": {
|
||||
primary: "#1e40af",
|
||||
secondary: "#3b82f6",
|
||||
accent: "#06b6d4",
|
||||
bg: "from-slate-900 via-blue-900 to-slate-800",
|
||||
},
|
||||
};
|
||||
export type Theme = (typeof themes)["hybrid-theory"];
|
||||
export type Theme = AlbumTheme;
|
||||
|
|
|
|||
Loading…
Reference in a new issue