118 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			118 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { isYoutubeLink } from "@lib/string.ts";
 | |
| import { IconBrandYoutube } from "@components/icons.tsx";
 | |
| import { GenericResource } from "@lib/types.ts";
 | |
| import { SmallRating } from "@components/Rating.tsx";
 | |
| import { Link } from "@islands/Link.tsx";
 | |
| import { parseRating } from "@lib/helpers.ts";
 | |
| 
 | |
| export function Card(
 | |
|   {
 | |
|     link,
 | |
|     rating,
 | |
|     title,
 | |
|     image,
 | |
|     thumbnail,
 | |
|     backgroundColor,
 | |
|     backgroundSize = 100,
 | |
|   }: {
 | |
|     backgroundSize?: number;
 | |
|     backgroundColor?: string;
 | |
|     thumbnail?: string;
 | |
|     link?: string;
 | |
|     title?: string;
 | |
|     image?: string;
 | |
|     rating?: number;
 | |
|   },
 | |
| ) {
 | |
|   const backgroundStyle: preact.JSX.CSSProperties = {
 | |
|     backgroundSize: "cover",
 | |
|     backgroundColor: backgroundColor,
 | |
|   };
 | |
| 
 | |
|   if (backgroundSize !== 100) {
 | |
|     backgroundStyle["backgroundSize"] = `${backgroundSize}%`;
 | |
|     backgroundStyle["backgroundRepeat"] = "no-repeat";
 | |
|     backgroundStyle["backgroundPosition"] = "center";
 | |
|   }
 | |
| 
 | |
|   return (
 | |
|     <Link
 | |
|       href={link}
 | |
|       style={backgroundStyle}
 | |
|       data-thumb={thumbnail}
 | |
|       class="text-white rounded-3xl shadow-md relative
 | |
|   lg:w-56 lg:h-56 
 | |
|   sm:w-48 sm:h-48
 | |
|   w-[37vw] h-[37vw]"
 | |
|     >
 | |
|       {true && (
 | |
|         <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",
 | |
|           boxShadow: "0px -60px 40px black inset, 0px 10px 20px #fff1 inset",
 | |
|         }}
 | |
|       >
 | |
|         <div class="flex-1">
 | |
|           {/* Recipe Card content */}
 | |
|         </div>
 | |
|         <div
 | |
|           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",
 | |
|           }}
 | |
|         >
 | |
|           {isYoutubeLink(link || "") && <IconBrandYoutube />}
 | |
|           {title}
 | |
|         </div>
 | |
|         {rating !== undefined && (
 | |
|           <div class="my-2">
 | |
|             <SmallRating rating={rating} />
 | |
|           </div>
 | |
|         )}
 | |
|       </div>
 | |
|       <div class="absolute inset-x-0 bottom-0 h-3/4" />
 | |
|     </Link>
 | |
|   );
 | |
| }
 | |
| 
 | |
| export function ResourceCard(
 | |
|   { res, sublink = "movies" }: { sublink?: string; res: GenericResource },
 | |
| ) {
 | |
|   const img = res?.content?.image || res?.content?.cover;
 | |
| 
 | |
|   const imageUrl = img
 | |
|     ? `/api/images?image=${img}&width=200&height=200`
 | |
|     : "/placeholder.svg";
 | |
| 
 | |
|   return (
 | |
|     <Card
 | |
|       title={res.content?.name || res.content?.itemReviewed?.name || res.content?.headline ||
 | |
|         res?.name}
 | |
|       backgroundColor={res.meta?.average}
 | |
|       rating={parseRating(res.content?.reviewRating?.ratingValue)}
 | |
|       thumbnail={res.cover}
 | |
|       image={imageUrl}
 | |
|       link={`/${sublink}/${res.name.replace(/\.md$/g, "")}`}
 | |
|     />
 | |
|   );
 | |
| }
 |