73 lines
2.4 KiB
TypeScript
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>
|
|
);
|
|
}
|