trptk/components/release/ReleaseCard.tsx
2026-02-24 17:14:07 +01:00

73 lines
2.4 KiB
TypeScript

import Link from "next/link";
import Image from "next/image";
import { urlFor } from "@/lib/sanityImage";
import type { SanityImageSource } from "@sanity/image-url";
export type ReleaseCardData = {
_id?: string;
name?: string;
albumArtist?: string;
catalogNo?: string;
releaseDate?: string;
slug?: string;
albumCover?: SanityImageSource;
};
type Props = {
release: ReleaseCardData;
href?: string;
className?: string;
};
function formatReleaseMonth(dateString?: string) {
if (!dateString) return null;
return new Intl.DateTimeFormat("en-US", {
month: "short",
year: "numeric",
}).format(new Date(dateString));
}
export function ReleaseCard({ release, href, className = "" }: Props) {
const url = href ?? (release.slug ? `/release/${release.slug}` : "#");
const coverSrc = release.albumCover ? urlFor(release.albumCover).url() : null;
return (
<Link
href={url}
className={`group transition-color relative z-10 rounded-xl bg-lightbg shadow-lg ring-1 ring-lightline duration-300 ease-in-out hover:text-trptkblue hover:ring-lightline-hover dark:bg-darkbg dark:ring-darkline dark:hover:text-white dark:hover:ring-darkline-hover ${className}`}
>
<div className="relative aspect-square w-full overflow-hidden rounded-xl">
{coverSrc ? (
<Image
src={coverSrc}
alt={
release.name
? `Album cover for ${release.name} by ${release.albumArtist}`
: `Album cover`
}
fill
className="object-cover"
sizes="(max-width: 560px) calc(100vw - 32px), 450px"
/>
) : (
<div className="absolute inset-0 bg-lightline-mid dark:bg-darkline-mid" />
)}
</div>
<div className="p-3 sm:p-5 sm:pb-15">
<div className="">
<h3 className="mb-2 break-words">{release.name}</h3>
<h4 className="text-sm break-words text-lightsec dark:text-darksec">
{release.albumArtist}
</h4>
</div>
</div>
<div className="absolute right-3 bottom-3 left-3 hidden items-center justify-between text-lightsec opacity-50 sm:right-5 sm:bottom-5 sm:left-5 sm:flex dark:text-darksec">
<span className="text-sm">{release.catalogNo}</span>
<span className="text-sm">{formatReleaseMonth(release.releaseDate)}</span>
</div>
</Link>
);
}