Files
portfolio/src/components/ProjectCard.astro
Nathan Cummins 1f45a74b2a
All checks were successful
Build and Deploy to Web Server / deploy (push) Successful in 18m1s
Some corrections with types and undeleted file
2025-08-14 09:48:52 +09:30

189 lines
5.6 KiB
Plaintext

---
import { getAllProjectImages } from '@lib/utils';
import Paragraph from "@components/Paragraph.astro";
import TextLink from "@components/TextLink.astro";
import Token from "@components/Token.astro";
import { Icon } from "astro-icon/components";
import { Image } from "astro:assets";
import type { CollectionEntry } from "astro:content";
interface Props {
project: CollectionEntry<"projects">;
textOn?: "left" | "right";
quality?: number;
}
const { project, textOn = "left", quality = "80" } = Astro.props;
const images = getAllProjectImages(project);
const translateXOptions = [
"group-hover:translate-x-8",
"group-hover:translate-x-9",
"group-hover:translate-x-10",
"group-hover:translate-x-11",
"group-hover:translate-x-12",
"group-hover:translate-x-13",
"group-hover:translate-x-14",
"group-hover:translate-x-15",
"group-hover:translate-x-16",
"group-hover:translate-x-17",
"group-hover:translate-x-18",
"group-hover:translate-x-19",
"group-hover:translate-x-20",
"group-hover:translate-x-21",
"group-hover:translate-x-22",
"group-hover:translate-x-23",
"group-hover:translate-x-24",
"group-hover:-translate-x-8",
"group-hover:-translate-x-9",
"group-hover:-translate-x-10",
"group-hover:-translate-x-11",
"group-hover:-translate-x-12",
"group-hover:-translate-x-13",
"group-hover:-translate-x-14",
"group-hover:-translate-x-15",
"group-hover:-translate-x-16",
"group-hover:-translate-x-17",
"group-hover:-translate-x-18",
"group-hover:-translate-x-19",
"group-hover:-translate-x-20",
"group-hover:-translate-x-21",
"group-hover:-translate-x-22",
"group-hover:-translate-x-23",
"group-hover:-translate-x-24"
];
const translateYOptions = [
"group-hover:translate-y-8",
"group-hover:translate-y-9",
"group-hover:translate-y-10",
"group-hover:translate-y-11",
"group-hover:translate-y-12",
"group-hover:translate-y-13",
"group-hover:translate-y-14",
"group-hover:translate-y-15",
"group-hover:translate-y-16",
"group-hover:translate-y-17",
"group-hover:translate-y-18",
"group-hover:translate-y-19",
"group-hover:translate-y-20",
"group-hover:translate-y-21",
"group-hover:translate-y-22",
"group-hover:translate-y-23",
"group-hover:translate-y-24",
"group-hover:-translate-y-9",
"group-hover:-translate-y-10",
"group-hover:-translate-y-11",
"group-hover:-translate-y-12",
"group-hover:-translate-y-13",
"group-hover:-translate-y-14",
"group-hover:-translate-y-15",
"group-hover:-translate-y-16",
"group-hover:-translate-y-17",
"group-hover:-translate-y-18",
"group-hover:-translate-y-19",
"group-hover:-translate-y-20",
"group-hover:-translate-y-21",
"group-hover:-translate-y-22",
"group-hover:-translate-y-23",
"group-hover:-translate-y-24"
];
const rotateOptions = [
"rotate-1",
"rotate-2",
"rotate-3",
"rotate-4",
"rotate-5",
"rotate-6",
"rotate-7",
"rotate-8",
"rotate-9",
"rotate-10",
"rotate-11",
"rotate-12",
"-rotate-1",
"-rotate-2",
"-rotate-3",
"-rotate-4",
"-rotate-5",
"-rotate-6",
"-rotate-7",
"-rotate-8",
"-rotate-9",
"-rotate-10",
"-rotate-11",
"-rotate-12"
];
const projectHasBody = project.body && project.body.trim().length > 0;
---
<div class="grid grid-cols-1 text-left md:grid-cols-2">
<div
class:list={[
"order-1 flex flex-col items-start justify-center py-4",
textOn === "right" ? "md:order-2" : "md:order-1"
]}
>
<span
><h2 class="font-header-alt inline-block text-lg font-semibold">
{projectHasBody && <TextLink href=`/projects/${project.id}/`>{project.data.title}</TextLink>}{!projectHasBody && project.data.title }{!project.data.ongoing && <span class="italic text-sm font-light"> ({project.data.date.getFullYear()})</span>}</h2></span
>
<h3 class="font-header-alt font-base font-medium">
{project.data.role}
</h3>
<div class="pt-2">
<Token>{project.data.type}</Token>
</div>
<Paragraph>{project.data.description}</Paragraph>
{
project.data.externalLinks !== undefined && (
<span class="relative order-3 ml-auto flex w-full items-start justify-start space-x-2 text-xl">
{project.data.externalLinks.map((link, index) => (
<TextLink href={link.href} includeExternalLinkIcon={false} aria-label={link.name}>
<Icon name={link.icon} />
</TextLink>
))}
</span>
)
}
</div>
<div
class:list={[
"group relative order-2 ml-auto flex h-full min-h-64 w-full items-center justify-center",
textOn === "right" ? "md:order-1" : "md:order-2"
]}
>
{
images
.reverse()
.map((image, index) => (
<Image
id={`hero-image-${index}`}
class:list={[
"animate-floaty absolute h-48 w-auto origin-center transform rounded object-cover shadow-lg/50 transition duration-300 ease-in-out md:group-hover:z-30 md:group-hover:scale-130 md:hover:z-40",
translateXOptions[
Math.floor(Math.random() * translateXOptions.length)
],
translateYOptions[
Math.floor(Math.random() * translateYOptions.length)
],
rotateOptions[Math.floor(Math.random() * rotateOptions.length)]
]}
src={image}
alt=""
loading="lazy"
layout="constrained"
fit="cover"
height={192}
style={`animation-delay: -${Math.floor(Math.random() * (12 - 4) + 4)}s; animation-direction: ${Math.random() < 0.5 ? "normal" : "reverse"};`}
quality={quality}
/>
))
}
</div>
</div>