mirror of
https://github.com/M4X809/list-of-lp.git
synced 2025-12-25 19:12:48 +00:00
Refactor TrackCard and TrackModal components for improved functionality and styling
- Replaced hash-based modal opening in TrackCard with state management for better control. - Integrated TrackModal into TrackCard, allowing for direct interaction and improved user experience. - Updated TrackModal to accept props for track data and theme, enhancing its reusability. - Refined styling in both components to maintain visual consistency with dynamic theming.
This commit is contained in:
parent
b93b0c2160
commit
9fad47fc65
4 changed files with 155 additions and 161 deletions
|
|
@ -4,7 +4,7 @@ import { Card, Group, Text, Badge, Box } from "@mantine/core";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import type { AlbumTheme } from "@/lib/themes";
|
import type { AlbumTheme } from "@/lib/themes";
|
||||||
import type { Track } from "@/lib/ListTypes";
|
import type { Track } from "@/lib/ListTypes";
|
||||||
import { useHash } from "@mantine/hooks";
|
import TrackModal from "./TrackModal";
|
||||||
|
|
||||||
interface TrackCardProps {
|
interface TrackCardProps {
|
||||||
track: Track;
|
track: Track;
|
||||||
|
|
@ -14,11 +14,12 @@ interface TrackCardProps {
|
||||||
|
|
||||||
export default function TrackCard({ track, index, theme }: TrackCardProps) {
|
export default function TrackCard({ track, index, theme }: TrackCardProps) {
|
||||||
const [isHovered, setIsHovered] = useState(false);
|
const [isHovered, setIsHovered] = useState(false);
|
||||||
const [_hash, setHash] = useHash();
|
const [modalOpened, setModalOpened] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<Card
|
<Card
|
||||||
onClick={() => setHash(`trackModal_${track.id}`)}
|
onClick={() => setModalOpened(true)}
|
||||||
className="backdrop-blur-sm transition-all duration-300"
|
className="backdrop-blur-sm transition-all duration-300"
|
||||||
style={{
|
style={{
|
||||||
background: isHovered ? theme.card.backgroundHover : theme.card.background,
|
background: isHovered ? theme.card.backgroundHover : theme.card.background,
|
||||||
|
|
@ -109,5 +110,7 @@ export default function TrackCard({ track, index, theme }: TrackCardProps) {
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</Card>
|
</Card>
|
||||||
|
<TrackModal opened={modalOpened} onClose={() => setModalOpened(false)} track={track} theme={theme} />
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,72 +1,53 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { albums } from "@/lib/list";
|
|
||||||
import { getSongLink } from "@/lib/songLinks";
|
import { getSongLink } from "@/lib/songLinks";
|
||||||
import { getThemeColors } from "@/lib/themes";
|
import type { AlbumTheme } from "@/lib/themes";
|
||||||
import { faApple, faSpotify, faYoutube, faYoutubeSquare, IconDefinition } from "@fortawesome/free-brands-svg-icons";
|
import type { Track } from "@/lib/ListTypes";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
faApple,
|
||||||
Anchor,
|
faSpotify,
|
||||||
Box,
|
faYoutube,
|
||||||
Divider,
|
faYoutubeSquare,
|
||||||
Grid,
|
type IconDefinition,
|
||||||
GridCol,
|
} from "@fortawesome/free-brands-svg-icons";
|
||||||
Group,
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
Modal,
|
import { ActionIcon, Box, Divider, Grid, GridCol, Group, Modal, Stack, Text, Title, Tooltip } from "@mantine/core";
|
||||||
Stack,
|
|
||||||
Text,
|
|
||||||
Title,
|
|
||||||
Tooltip,
|
|
||||||
} from "@mantine/core";
|
|
||||||
import { useDisclosure, useHash } from "@mantine/hooks";
|
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
||||||
export default function TrackModal() {
|
interface TrackModalProps {
|
||||||
const [hash, setHash] = useHash();
|
opened: boolean;
|
||||||
console.log("🚀 ~ TrackModal.tsx:8 ~ TrackModal ~ hash:", hash);
|
onClose: () => void;
|
||||||
const close = () => {
|
track: Track;
|
||||||
setHash("");
|
theme: AlbumTheme;
|
||||||
};
|
}
|
||||||
|
|
||||||
const album = albums.find((album) => {
|
export default function TrackModal({ opened, onClose, track, theme }: TrackModalProps) {
|
||||||
return album.id === hash.split("_")[1];
|
const songLink = getSongLink(track.id);
|
||||||
});
|
|
||||||
const track = album?.tracks.find((track) => {
|
|
||||||
return track.id === `${hash.split("_")[1]}_${hash.split("_")[2]}`;
|
|
||||||
});
|
|
||||||
|
|
||||||
const songLink = getSongLink(track?.id || "");
|
|
||||||
console.log("🚀 ~ TrackModal.tsx:25 ~ TrackModal ~ songLink:", songLink);
|
|
||||||
|
|
||||||
const theme = getThemeColors(album?.id || "");
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
opened={hash.startsWith("#trackModal_")}
|
centered
|
||||||
onClose={close}
|
opened={opened}
|
||||||
|
onClose={onClose}
|
||||||
withCloseButton={false}
|
withCloseButton={false}
|
||||||
|
transitionProps={{ duration: 150, transition: "fade" }}
|
||||||
styles={{
|
styles={{
|
||||||
// content: {
|
|
||||||
// background: theme.background.gradient,
|
|
||||||
// border: `2px solid ${theme.border.light}`,
|
|
||||||
// boxShadow: "none",
|
|
||||||
// },
|
|
||||||
// header: {
|
|
||||||
// background: theme.background.gradient,
|
|
||||||
// border: `2px solid ${theme.border.light}`,
|
|
||||||
// boxShadow: "none",
|
|
||||||
// },
|
|
||||||
body: {
|
body: {
|
||||||
background: theme.background.gradient,
|
background: theme.background.gradient,
|
||||||
// border: `2px solid ${theme.border.light}`,
|
|
||||||
|
|
||||||
boxShadow: "none",
|
boxShadow: "none",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Title order={1}>{track?.label}</Title>
|
<Title order={1}>{track.label}</Title>
|
||||||
<Divider size={"lg"} label={<Title order={3}>Studio Version</Title>} />
|
<Divider
|
||||||
|
color={theme.accent.DEFAULT}
|
||||||
|
size={"lg"}
|
||||||
|
label={
|
||||||
|
<Title c={theme.accent.DEFAULT} order={3}>
|
||||||
|
Studio Version
|
||||||
|
</Title>
|
||||||
|
}
|
||||||
|
/>
|
||||||
<Grid columns={songLink && Object.keys(songLink).length > 0 ? Object.keys(songLink).length : 4}>
|
<Grid columns={songLink && Object.keys(songLink).length > 0 ? Object.keys(songLink).length : 4}>
|
||||||
{songLink &&
|
{songLink &&
|
||||||
Object.entries(songLink).map(([key, value]) => {
|
Object.entries(songLink).map(([key, value]) => {
|
||||||
|
|
@ -113,11 +94,12 @@ export default function TrackModal() {
|
||||||
return (
|
return (
|
||||||
<GridCol
|
<GridCol
|
||||||
span={1}
|
span={1}
|
||||||
key={`${track?.id}_${key}`}
|
key={`${track.id}_${key}`}
|
||||||
style={{ display: "flex", alignItems: "center", justifyContent: "center" }}
|
style={{ display: "flex", alignItems: "center", justifyContent: "center" }}
|
||||||
>
|
>
|
||||||
<Tooltip label={themeColor.tooltip}>
|
<Tooltip label={themeColor.tooltip}>
|
||||||
<ActionIcon
|
<ActionIcon
|
||||||
|
tabIndex={-1}
|
||||||
variant="filled"
|
variant="filled"
|
||||||
color={themeColor.color}
|
color={themeColor.color}
|
||||||
size="lg"
|
size="lg"
|
||||||
|
|
@ -133,11 +115,19 @@ export default function TrackModal() {
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</Grid>
|
</Grid>
|
||||||
{Array.isArray(track?.emilyLive) && (
|
{Array.isArray(track.emilyLive) && (
|
||||||
<>
|
<>
|
||||||
<Divider size={"lg"} label={<Title order={3}>Fan Live Versions</Title>} />
|
<Divider
|
||||||
|
color={theme.accent.DEFAULT}
|
||||||
|
size={"lg"}
|
||||||
|
label={
|
||||||
|
<Title c={theme.accent.DEFAULT} order={3}>
|
||||||
|
Fan Live Versions
|
||||||
|
</Title>
|
||||||
|
}
|
||||||
|
/>
|
||||||
<Stack>
|
<Stack>
|
||||||
{track.emilyLive.map((live, idx) => (
|
{track.emilyLive.map((live) => (
|
||||||
<Box style={{ width: "100%" }} key={`emilyLive_${live.url}`}>
|
<Box style={{ width: "100%" }} key={`emilyLive_${live.url}`}>
|
||||||
<Group justify="space-between" align="center">
|
<Group justify="space-between" align="center">
|
||||||
<Box style={{ display: "flex", flexDirection: "column", gap: "4px" }}>
|
<Box style={{ display: "flex", flexDirection: "column", gap: "4px" }}>
|
||||||
|
|
@ -148,6 +138,7 @@ export default function TrackModal() {
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
<ActionIcon
|
<ActionIcon
|
||||||
|
tabIndex={-1}
|
||||||
variant="filled"
|
variant="filled"
|
||||||
color={"#FF0000"}
|
color={"#FF0000"}
|
||||||
size="lg"
|
size="lg"
|
||||||
|
|
@ -165,26 +156,35 @@ export default function TrackModal() {
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{track?.lpLive && (
|
{track.lpLive && (
|
||||||
<>
|
<>
|
||||||
<Divider size={"lg"} label={<Title order={3}>Linkin Park Live Versions</Title>} />
|
<Divider
|
||||||
|
color={theme.accent.DEFAULT}
|
||||||
|
size={"lg"}
|
||||||
|
label={
|
||||||
|
<Title c={theme.accent.DEFAULT} order={3}>
|
||||||
|
Linkin Park Live Versions
|
||||||
|
</Title>
|
||||||
|
}
|
||||||
|
/>
|
||||||
<Group justify="space-between" align="center">
|
<Group justify="space-between" align="center">
|
||||||
<Box style={{ display: "flex", flexDirection: "column", gap: "4px" }}>
|
<Box style={{ display: "flex", flexDirection: "column", gap: "4px" }}>
|
||||||
<Text>
|
<Text>
|
||||||
{new Date(track?.lpLive.date).toLocaleDateString("en-US", {
|
{new Date(track.lpLive.date).toLocaleDateString("en-US", {
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
month: "long",
|
month: "long",
|
||||||
day: "numeric",
|
day: "numeric",
|
||||||
})}
|
})}
|
||||||
</Text>
|
</Text>
|
||||||
<Text>{track?.lpLive.location}</Text>
|
<Text>{track.lpLive.location}</Text>
|
||||||
</Box>
|
</Box>
|
||||||
<ActionIcon
|
<ActionIcon
|
||||||
|
tabIndex={-1}
|
||||||
variant="filled"
|
variant="filled"
|
||||||
color={"#FF0000"}
|
color={"#FF0000"}
|
||||||
size="lg"
|
size="lg"
|
||||||
component={Link}
|
component={Link}
|
||||||
href={track?.lpLive.url}
|
href={track.lpLive.url}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import { albums } from "../../../lib/list";
|
||||||
import BackButton from "../../../Components/BackButton";
|
import BackButton from "../../../Components/BackButton";
|
||||||
import { getThemeColors } from "@/lib/themes";
|
import { getThemeColors } from "@/lib/themes";
|
||||||
import TrackCard from "@/Components/TrackCard";
|
import TrackCard from "@/Components/TrackCard";
|
||||||
import TrackModal from "@/Components/TrackModal";
|
|
||||||
|
|
||||||
export function generateStaticParams() {
|
export function generateStaticParams() {
|
||||||
return albums.map((album) => ({
|
return albums.map((album) => ({
|
||||||
|
|
@ -46,7 +45,6 @@ export default async function AlbumDetail({ params }: { params: Promise<{ albumI
|
||||||
viewTransitionName: `album-card-background-${album.id}`,
|
viewTransitionName: `album-card-background-${album.id}`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TrackModal />
|
|
||||||
<Container size="xl" className="py-12">
|
<Container size="xl" className="py-12">
|
||||||
{/* Back Button */}
|
{/* Back Button */}
|
||||||
<BackButton theme={theme} />
|
<BackButton theme={theme} />
|
||||||
|
|
@ -57,7 +55,6 @@ export default async function AlbumDetail({ params }: { params: Promise<{ albumI
|
||||||
style={{
|
style={{
|
||||||
border: `3px solid ${theme.border.light}`,
|
border: `3px solid ${theme.border.light}`,
|
||||||
borderRadius: "8px",
|
borderRadius: "8px",
|
||||||
padding: "4px",
|
|
||||||
background: theme.background.secondary,
|
background: theme.background.secondary,
|
||||||
boxShadow: `0 8px 32px ${theme.primary.DEFAULT}40`,
|
boxShadow: `0 8px 32px ${theme.primary.DEFAULT}40`,
|
||||||
viewTransitionName: `album-card-image-${album.id}`,
|
viewTransitionName: `album-card-image-${album.id}`,
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,6 @@ export const albums: Album[] = [
|
||||||
location: "Austin, Texas, USA",
|
location: "Austin, Texas, USA",
|
||||||
author: "Erynn Halvorson",
|
author: "Erynn Halvorson",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
url: "https://youtu.be/miQ9Y5UW08dasdasdg",
|
|
||||||
date: "2025-04-26",
|
|
||||||
location: "Austin, Texas, USdasdsaA",
|
|
||||||
author: "Erynn Halvorson",
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
lpLive: {
|
lpLive: {
|
||||||
url: "https://www.youtube.com/watch?v=DOKcCl6iKaA",
|
url: "https://www.youtube.com/watch?v=DOKcCl6iKaA",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue