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, theme.card.border,
)} )}
style={{}} style={{}}
p="sm"
> >
<Group justify="space-between" align="center"> <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<Group gap="md"> {/* Track Number and Title */}
<Group gap="xs" wrap="nowrap" className="min-w-0 flex-1">
<Box <Box
style={{ style={{
minWidth: "40px", minWidth: "32px",
height: "40px", width: "32px",
height: "32px",
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
justifyContent: "center", justifyContent: "center",
background: theme.primary.DEFAULT, background: theme.primary.DEFAULT,
borderRadius: "8px", borderRadius: "8px",
fontWeight: 700, fontWeight: 700,
fontSize: "18px", fontSize: "16px",
color: theme.text.contrast, color: theme.text.contrast,
boxShadow: `0 4px 12px ${theme.primary.DEFAULT}60`, boxShadow: `0 4px 12px ${theme.primary.DEFAULT}60`,
}} }}
className="sm:h-[40px] sm:w-[40px] sm:min-w-[40px] sm:text-lg"
> >
{index + 1} {index + 1}
</Box> </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} {track.label}
</Text> </Text>
</Group> </Group>
<Group gap="md"> {/* Badges and Duration */}
<Group gap="xs"> <div className="flex flex-wrap items-center justify-between gap-2 sm:justify-end">
<Group gap="xs" wrap="wrap">
{track.__SPOTIFY_URL__ && ( {track.__SPOTIFY_URL__ && (
<Badge <Badge
size="sm" size="sm"
@ -106,20 +111,21 @@ export default function TrackCard({ track, index, theme }: TrackCardProps) {
)} )}
</Group> </Group>
<Text <Text
size="sm" size="xs"
fw={500} fw={500}
style={{ style={{
color: theme.text.muted, color: theme.text.muted,
fontFamily: "monospace", fontFamily: "monospace",
background: theme.background.tertiary, background: theme.background.tertiary,
padding: "4px 12px", padding: "4px 8px",
borderRadius: "6px", borderRadius: "6px",
}} }}
className="sm:px-3 sm:text-sm"
> >
{track.duration} {track.duration}
</Text> </Text>
</Group> </div>
</Group> </div>
</Card> </Card>
<TrackModal opened={modalOpened} onClose={() => setModalOpened(false)} track={track} theme={theme} /> <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", boxShadow: "none",
}, },
}} }}
size="lg"
padding="md"
> >
<Stack> <Stack gap="md">
<Title order={1}>{track.label}</Title> <Title order={1} className="text-2xl sm:text-3xl md:text-4xl">
{track.label}
</Title>
<Divider <Divider
color={theme.accent.DEFAULT} color={theme.accent.DEFAULT}
size={"lg"} size={"lg"}
label={ label={
<Title c={theme.accent.DEFAULT} order={3}> <Title c={theme.accent.DEFAULT} order={3} className="text-lg sm:text-xl">
Studio Version Studio Version
</Title> </Title>
} }
/> />
<Grid columns={songLink && Object.keys(songLink).length > 0 ? Object.keys(songLink).length : 4}> <Grid gutter="sm">
{songLink && {songLink &&
Object.entries(songLink).map(([key, value]) => { Object.entries(songLink).map(([key, value]) => {
let themeColor: { let themeColor: {
@ -93,7 +97,7 @@ export default function TrackModal({ opened, onClose, track, theme }: TrackModal
return ( return (
<GridCol <GridCol
span={1} span={{ base: 6, xs: 4, sm: 3 }}
key={`${track.id}_${key}`} key={`${track.id}_${key}`}
style={{ display: "flex", alignItems: "center", justifyContent: "center" }} style={{ display: "flex", alignItems: "center", justifyContent: "center" }}
> >
@ -121,19 +125,23 @@ export default function TrackModal({ opened, onClose, track, theme }: TrackModal
color={theme.accent.DEFAULT} color={theme.accent.DEFAULT}
size={"lg"} size={"lg"}
label={ label={
<Title c={theme.accent.DEFAULT} order={3}> <Title c={theme.accent.DEFAULT} order={3} className="text-lg sm:text-xl">
Fan Live Versions Fan Live Versions
</Title> </Title>
} }
/> />
<Stack> <Stack gap="sm">
{track.emilyLive.map((live) => ( {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" wrap="nowrap" gap="xs">
<Box style={{ display: "flex", flexDirection: "column", gap: "4px" }}> <Box style={{ display: "flex", flexDirection: "column", gap: "4px" }} className="min-w-0 flex-1">
<Text>By: {live.author}</Text> <Text size="sm" className="truncate sm:text-base">
<Text>{live.location}</Text> By: {live.author}
<Text> </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" })} {new Date(live.date).toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" })}
</Text> </Text>
</Box> </Box>
@ -146,6 +154,7 @@ export default function TrackModal({ opened, onClose, track, theme }: TrackModal
href={live.url} href={live.url}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="shrink-0"
> >
<FontAwesomeIcon icon={faYoutube} /> <FontAwesomeIcon icon={faYoutube} />
</ActionIcon> </ActionIcon>
@ -162,22 +171,24 @@ export default function TrackModal({ opened, onClose, track, theme }: TrackModal
color={theme.accent.DEFAULT} color={theme.accent.DEFAULT}
size={"lg"} size={"lg"}
label={ 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 Linkin Park Live Versions
</Title> </Title>
} }
/> />
<Group justify="space-between" align="center"> <Group justify="space-between" align="center" wrap="nowrap" gap="xs">
<Box style={{ display: "flex", flexDirection: "column", gap: "4px" }}> <Box style={{ display: "flex", flexDirection: "column", gap: "4px" }} className="min-w-0 flex-1">
<Text> <Text size="sm" className="sm:text-base">
{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 size="sm" className="truncate sm:text-base">
<Text size="sm" c={theme.accent.DEFAULT}> {track.lpLive.location}
</Text>
<Text size="xs" c={theme.accent.DEFAULT} className="sm:text-sm">
{track.lpLive.disclaimer} {track.lpLive.disclaimer}
</Text> </Text>
</Box> </Box>
@ -190,6 +201,7 @@ export default function TrackModal({ opened, onClose, track, theme }: TrackModal
href={track.lpLive.url} href={track.lpLive.url}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="shrink-0"
> >
<FontAwesomeIcon icon={faYoutube} /> <FontAwesomeIcon icon={faYoutube} />
</ActionIcon> </ActionIcon>
@ -203,14 +215,14 @@ export default function TrackModal({ opened, onClose, track, theme }: TrackModal
color={theme.accent.DEFAULT} color={theme.accent.DEFAULT}
size={"lg"} size={"lg"}
label={ label={
<Title c={theme.accent.DEFAULT} order={3}> <Title c={theme.accent.DEFAULT} order={3} className="text-lg sm:text-xl">
LP TV LP TV
</Title> </Title>
} }
/> />
<Group justify="space-between" align="center"> <Group justify="space-between" align="center" wrap="nowrap" gap="xs">
<Box style={{ display: "flex", flexDirection: "column", gap: "4px" }}> <Box style={{ display: "flex", flexDirection: "column", gap: "4px" }} className="min-w-0 flex-1">
<Text> <Text size="sm" className="sm:text-base">
{new Date(track.lpTV.date).toLocaleDateString("en-US", { {new Date(track.lpTV.date).toLocaleDateString("en-US", {
year: "numeric", year: "numeric",
month: "long", month: "long",
@ -227,6 +239,7 @@ export default function TrackModal({ opened, onClose, track, theme }: TrackModal
href={track.lpTV.url} href={track.lpTV.url}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="shrink-0"
> >
<FontAwesomeIcon icon={faYoutube} /> <FontAwesomeIcon icon={faYoutube} />
</ActionIcon> </ActionIcon>

View file

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