Enhance TrackCard, TrackModal, and AlbumDetail components for improved layout and styling

- Updated TrackCard to use responsive flexbox layout and adjusted sizes for track number and title.
- Enhanced TrackModal with improved text sizes and responsive design for better readability.
- Refined AlbumDetail layout with responsive grid settings and adjusted text alignment for better presentation.
- Improved styling consistency across components, including padding and text sizes.
This commit is contained in:
m4x809 2025-10-25 21:06:30 +02:00
parent df0201be28
commit e7b343ed83
Signed by: m4x809
SSH key fingerprint: SHA256:YCoFF78p2DUP94EnCScqLwldjkKDwdKSZq3r8p/6EiU
3 changed files with 65 additions and 45 deletions

View file

@ -27,33 +27,38 @@ export default function TrackCard({ track, index, theme }: TrackCardProps) {
theme.card.border,
)}
style={{}}
p="sm"
>
<Group justify="space-between" align="center">
<Group gap="md">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
{/* Track Number and Title */}
<Group gap="xs" wrap="nowrap" className="min-w-0 flex-1">
<Box
style={{
minWidth: "40px",
height: "40px",
minWidth: "32px",
width: "32px",
height: "32px",
display: "flex",
alignItems: "center",
justifyContent: "center",
background: theme.primary.DEFAULT,
borderRadius: "8px",
fontWeight: 700,
fontSize: "18px",
fontSize: "16px",
color: theme.text.contrast,
boxShadow: `0 4px 12px ${theme.primary.DEFAULT}60`,
}}
className="sm:h-[40px] sm:w-[40px] sm:min-w-[40px] sm:text-lg"
>
{index + 1}
</Box>
<Text size="lg" fw={500} style={{ color: theme.text.primary }}>
<Text size="md" fw={500} style={{ color: theme.text.primary }} className="truncate sm:text-lg">
{track.label}
</Text>
</Group>
<Group gap="md">
<Group gap="xs">
{/* Badges and Duration */}
<div className="flex flex-wrap items-center justify-between gap-2 sm:justify-end">
<Group gap="xs" wrap="wrap">
{track.__SPOTIFY_URL__ && (
<Badge
size="sm"
@ -106,20 +111,21 @@ export default function TrackCard({ track, index, theme }: TrackCardProps) {
)}
</Group>
<Text
size="sm"
size="xs"
fw={500}
style={{
color: theme.text.muted,
fontFamily: "monospace",
background: theme.background.tertiary,
padding: "4px 12px",
padding: "4px 8px",
borderRadius: "6px",
}}
className="sm:px-3 sm:text-sm"
>
{track.duration}
</Text>
</Group>
</Group>
</div>
</div>
</Card>
<TrackModal opened={modalOpened} onClose={() => setModalOpened(false)} track={track} theme={theme} />
</>

View file

@ -36,19 +36,23 @@ export default function TrackModal({ opened, onClose, track, theme }: TrackModal
boxShadow: "none",
},
}}
size="lg"
padding="md"
>
<Stack>
<Title order={1}>{track.label}</Title>
<Stack gap="md">
<Title order={1} className="text-2xl sm:text-3xl md:text-4xl">
{track.label}
</Title>
<Divider
color={theme.accent.DEFAULT}
size={"lg"}
label={
<Title c={theme.accent.DEFAULT} order={3}>
<Title c={theme.accent.DEFAULT} order={3} className="text-lg sm:text-xl">
Studio Version
</Title>
}
/>
<Grid columns={songLink && Object.keys(songLink).length > 0 ? Object.keys(songLink).length : 4}>
<Grid gutter="sm">
{songLink &&
Object.entries(songLink).map(([key, value]) => {
let themeColor: {
@ -93,7 +97,7 @@ export default function TrackModal({ opened, onClose, track, theme }: TrackModal
return (
<GridCol
span={1}
span={{ base: 6, xs: 4, sm: 3 }}
key={`${track.id}_${key}`}
style={{ display: "flex", alignItems: "center", justifyContent: "center" }}
>
@ -121,19 +125,23 @@ export default function TrackModal({ opened, onClose, track, theme }: TrackModal
color={theme.accent.DEFAULT}
size={"lg"}
label={
<Title c={theme.accent.DEFAULT} order={3}>
<Title c={theme.accent.DEFAULT} order={3} className="text-lg sm:text-xl">
Fan Live Versions
</Title>
}
/>
<Stack>
<Stack gap="sm">
{track.emilyLive.map((live) => (
<Box style={{ width: "100%" }} key={`emilyLive_${live.url}`}>
<Group justify="space-between" align="center">
<Box style={{ display: "flex", flexDirection: "column", gap: "4px" }}>
<Text>By: {live.author}</Text>
<Text>{live.location}</Text>
<Text>
<Group justify="space-between" align="center" wrap="nowrap" gap="xs">
<Box style={{ display: "flex", flexDirection: "column", gap: "4px" }} className="min-w-0 flex-1">
<Text size="sm" className="truncate sm:text-base">
By: {live.author}
</Text>
<Text size="sm" className="truncate sm:text-base">
{live.location}
</Text>
<Text size="xs" className="sm:text-sm">
{new Date(live.date).toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" })}
</Text>
</Box>
@ -146,6 +154,7 @@ export default function TrackModal({ opened, onClose, track, theme }: TrackModal
href={live.url}
target="_blank"
rel="noopener noreferrer"
className="shrink-0"
>
<FontAwesomeIcon icon={faYoutube} />
</ActionIcon>
@ -162,22 +171,24 @@ export default function TrackModal({ opened, onClose, track, theme }: TrackModal
color={theme.accent.DEFAULT}
size={"lg"}
label={
<Title c={theme.accent.DEFAULT} order={3}>
<Title c={theme.accent.DEFAULT} order={3} className="text-lg sm:text-xl">
Linkin Park Live Versions
</Title>
}
/>
<Group justify="space-between" align="center">
<Box style={{ display: "flex", flexDirection: "column", gap: "4px" }}>
<Text>
<Group justify="space-between" align="center" wrap="nowrap" gap="xs">
<Box style={{ display: "flex", flexDirection: "column", gap: "4px" }} className="min-w-0 flex-1">
<Text size="sm" className="sm:text-base">
{new Date(track.lpLive.date).toLocaleDateString("en-US", {
year: "numeric",
month: "long",
day: "numeric",
})}
</Text>
<Text>{track.lpLive.location}</Text>
<Text size="sm" c={theme.accent.DEFAULT}>
<Text size="sm" className="truncate sm:text-base">
{track.lpLive.location}
</Text>
<Text size="xs" c={theme.accent.DEFAULT} className="sm:text-sm">
{track.lpLive.disclaimer}
</Text>
</Box>
@ -190,6 +201,7 @@ export default function TrackModal({ opened, onClose, track, theme }: TrackModal
href={track.lpLive.url}
target="_blank"
rel="noopener noreferrer"
className="shrink-0"
>
<FontAwesomeIcon icon={faYoutube} />
</ActionIcon>
@ -203,14 +215,14 @@ export default function TrackModal({ opened, onClose, track, theme }: TrackModal
color={theme.accent.DEFAULT}
size={"lg"}
label={
<Title c={theme.accent.DEFAULT} order={3}>
<Title c={theme.accent.DEFAULT} order={3} className="text-lg sm:text-xl">
LP TV
</Title>
}
/>
<Group justify="space-between" align="center">
<Box style={{ display: "flex", flexDirection: "column", gap: "4px" }}>
<Text>
<Group justify="space-between" align="center" wrap="nowrap" gap="xs">
<Box style={{ display: "flex", flexDirection: "column", gap: "4px" }} className="min-w-0 flex-1">
<Text size="sm" className="sm:text-base">
{new Date(track.lpTV.date).toLocaleDateString("en-US", {
year: "numeric",
month: "long",
@ -227,6 +239,7 @@ export default function TrackModal({ opened, onClose, track, theme }: TrackModal
href={track.lpTV.url}
target="_blank"
rel="noopener noreferrer"
className="shrink-0"
>
<FontAwesomeIcon icon={faYoutube} />
</ActionIcon>

View file

@ -46,12 +46,12 @@ export default async function AlbumDetail({ params }: { params: Promise<{ albumI
viewTransitionName: `album-card-background-${album.id}`,
}}
>
<Container size="xl" className="py-12">
<Container size="xl" className="px-4 py-6 sm:py-12">
{/* Back Button */}
<BackButton theme={theme} />
<Grid columns={5} gutter={"xl"} className="mb-12">
<GridCol span={"content"}>
<Grid gutter={{ base: "md", sm: "xl" }} className="mb-8 sm:mb-12">
<GridCol span={{ base: 12, sm: "content" }}>
<Box
style={{
border: `3px solid ${theme.border.light}`,
@ -60,6 +60,7 @@ export default async function AlbumDetail({ params }: { params: Promise<{ albumI
boxShadow: `0 8px 32px ${theme.primary.DEFAULT}40`,
viewTransitionName: `album-card-image-${album.id}`,
}}
className="mx-auto max-w-[200px] sm:mx-0"
>
<Image
src={album.image}
@ -71,10 +72,10 @@ export default async function AlbumDetail({ params }: { params: Promise<{ albumI
</Box>
</GridCol>
<GridCol span={"auto"}>
<GridCol span={{ base: 12, sm: "auto" }}>
<Title
order={1}
className="mb-3 text-6xl font-bold"
className="mb-3 text-center text-3xl font-bold sm:text-left sm:text-4xl md:text-5xl lg:text-6xl"
style={{
color: theme.text.primary,
textShadow: `0 0 20px ${theme.primary.DEFAULT}80`,
@ -83,8 +84,8 @@ export default async function AlbumDetail({ params }: { params: Promise<{ albumI
<span style={{ viewTransitionName: `album-card-title-${album.id}` }}>{album.label}</span>
</Title>
<Text
size="xl"
className="mb-4"
size="lg"
className="mb-4 text-center sm:text-left"
style={{
color: theme.text.secondary,
}}
@ -98,7 +99,7 @@ export default async function AlbumDetail({ params }: { params: Promise<{ albumI
})}
</span>
</Text>
<Text size="md" style={{ color: theme.text.muted, lineHeight: 1.6 }}>
<Text size="md" style={{ color: theme.text.muted, lineHeight: 1.6 }} className="text-center sm:text-left">
{album.description}
</Text>
</GridCol>
@ -109,17 +110,17 @@ export default async function AlbumDetail({ params }: { params: Promise<{ albumI
<Box>
<Title
order={2}
className="mb-6 text-3xl font-bold"
className="mb-4 text-2xl font-bold sm:mb-6 sm:text-3xl"
style={{
color: theme.text.primary,
borderBottom: `2px solid ${theme.border.light}`,
paddingBottom: "12px",
paddingBottom: "8px",
}}
>
Track List
</Title>
<Stack gap="xs" pt={"md"} pb={50}>
<Stack gap="xs" pt={{ base: "sm", sm: "md" }} pb={{ base: 25, sm: 50 }}>
{album.tracks.map((track, index) => (
<TrackCard key={track.id} track={track} index={index} theme={theme} />
))}