memorium/components/Card.tsx

116 lines
2.9 KiB
TypeScript
Raw Normal View History

import { isYoutubeLink } from "@lib/string.ts";
2023-08-07 13:42:00 +02:00
import { IconBrandYoutube } from "@components/icons.tsx";
2023-08-12 18:32:56 +02:00
import { GenericResource } from "@lib/types.ts";
import { SmallRating } from "@components/Rating.tsx";
2025-01-20 23:37:03 +01:00
import { Link } from "@islands/Link.tsx";
2023-08-07 13:42:00 +02:00
export function Card(
{
link,
rating,
title,
image,
thumbnail,
backgroundColor,
backgroundSize = 100,
}: {
2023-08-09 15:20:14 +02:00
backgroundSize?: number;
2023-08-12 18:32:56 +02:00
backgroundColor?: string;
thumbnail?: string;
2023-08-09 15:20:14 +02:00
link?: string;
title?: string;
image?: string;
rating?: number;
2023-08-09 15:20:14 +02:00
},
) {
2025-01-20 23:37:03 +01:00
const backgroundStyle: preact.JSX.CSSProperties = {
2023-08-09 15:20:14 +02:00
backgroundSize: "cover",
2023-08-12 18:32:56 +02:00
backgroundColor: backgroundColor,
2023-08-09 15:20:14 +02:00
};
if (backgroundSize !== 100) {
backgroundStyle["backgroundSize"] = `${backgroundSize}%`;
backgroundStyle["backgroundRepeat"] = "no-repeat";
backgroundStyle["backgroundPosition"] = "center";
}
return (
2025-01-20 23:37:03 +01:00
<Link
href={link}
2023-08-09 15:20:14 +02:00
style={backgroundStyle}
data-thumb={thumbnail}
2023-08-12 18:32:56 +02:00
class="text-white rounded-3xl shadow-md relative
lg:w-56 lg:h-56
2023-08-02 01:58:03 +02:00
sm:w-48 sm:h-48
2023-08-02 17:35:10 +02:00
w-[37vw] h-[37vw]"
>
{true && (
2023-08-12 18:32:56 +02:00
<span class="absolute top-0 left-0 overflow-hidden rounded-3xl w-full h-full">
<img
class="w-full h-full object-cover"
data-thumb-img
loading="lazy"
src={image || "/placeholder.svg"}
/>
</span>
)}
<div
class="p-4 flex flex-col justify-between relative z-10"
style={{
outline: "solid 2px #141218",
borderRadius: "1.4rem",
height: "calc(100% + 0.5px)",
width: "calc(100% + 0.5px)",
marginTop: "-0.5px",
marginLeft: "-0.5px",
2023-08-12 18:32:56 +02:00
boxShadow: "0px -60px 40px black inset, 0px 10px 20px #fff1 inset",
}}
>
<div class="flex-1">
{/* Recipe Card content */}
</div>
<div
2023-08-23 14:06:28 +02:00
class="mt-2 flex gap-2"
style={{
maxHeight: "50%",
textShadow:
"0px 0px 2px black, 0px 2px 8px black, 2px 3px 12px black",
overflow: "hidden",
textOverflow: "ellipsis",
}}
>
2023-08-07 13:42:00 +02:00
{isYoutubeLink(link || "") && <IconBrandYoutube />}
{title}
</div>
{rating !== undefined && (
<div class="my-2">
<SmallRating rating={rating} />
</div>
)}
</div>
2023-08-09 15:31:21 +02:00
<div class="absolute inset-x-0 bottom-0 h-3/4" />
2025-01-20 23:37:03 +01:00
</Link>
);
}
2023-08-12 18:32:56 +02:00
export function ResourceCard(
{ res, sublink = "movies" }: { sublink?: string; res: GenericResource },
) {
2025-01-18 00:46:05 +01:00
const { meta: { image } = {} } = res || {};
2023-08-12 18:32:56 +02:00
const imageUrl = image
2023-08-12 18:32:56 +02:00
? `/api/images?image=${image}&width=200&height=200`
: "/placeholder.svg";
2023-08-12 18:32:56 +02:00
return (
<Card
title={res.name}
backgroundColor={res.meta?.average}
rating={res.meta?.rating}
2023-08-12 18:32:56 +02:00
thumbnail={res.meta?.thumbnail}
image={imageUrl}
link={`/${sublink}/${res.id}`}
/>
);
}