Files
my-website-v2/frontend/islands/ProjectCard.tsx

96 lines
2.8 KiB
TypeScript
Raw Normal View History

import { useState } from "preact/hooks";
import { Portal } from "./portal.tsx";
import { Modal } from "./modal.tsx";
2024-12-02 18:29:45 -05:00
export const ProjectCard = function ProjectCard(props: ProjectProps) {
const [open, setOpen] = useState(false);
2024-12-02 18:29:45 -05:00
return (
<div
2025-07-14 20:09:10 -04:00
class={`md:m-8 group space-y-1 rounded-md ${
props.wip ? "border-2" : "cursor-pointer"
} bg-[#44485b] px-3 py-2 m-4 shadow-md transition-all duration-300 ease-in-out border-b-4 border-b-[#94e2d5] hover:shadow-xl hover:scale-105`}
style={
props.wip
? {
borderTopStyle: "dashed",
borderRightStyle: "dashed",
borderLeftStyle: "dashed",
}
: {}
}
onClick={() => {
// clicking the card (not the link) opens the modal
console.log("opened portal");
setOpen(true);
}}
2024-12-02 18:29:45 -05:00
>
<div class="flex items-center justify-between">
<h2 class="text-lg text-white font-black uppercase">
<a
href={props.repo}
target="_blank"
onClick={(e) => {
// clicking the link should not open the modal
e.stopPropagation();
}}
>
2024-12-02 18:29:45 -05:00
{props.title}
</a>
</h2>
<div class="bg-[#585b70] text-[#a6adc8] text-xs font-bold uppercase px-2.5 py-0.5 rounded-full">
{props.repo && <span>Active</span>}
2024-12-02 18:29:45 -05:00
{!props.repo && !props.wip && <span>Dead</span>}
{props.wip && <span>WIP</span>}
</div>
</div>
<p class="whitespace-pre-wrap italic font-light text-lg text-[#a6adc8]">
{props.summary}
</p>
<p class="whitespace-pre-wrap text-sm font-semibold text-[#a6adc8]">
{props.tech}
</p>
{open && !props.wip ? (
<Portal into="body">
<Modal
title={props.title}
onClose={() => setOpen(false)}
actions={[
{
label: "Open repository",
onClick: () => {
if (props.repo) window.open(props.repo, "_blank");
},
variant: "primary",
},
{
label: "Close",
onClick: () => setOpen(false),
variant: "secondary",
},
]}
>
<div class="space-y-3">
<p class="text-sm text-gray-800 dark:text-gray-200">
{props.summary}
</p>
<p class="text-xs font-mono text-gray-600 dark:text-gray-300">
Technologies used: {props.tech}
</p>
</div>
</Modal>
</Portal>
) : null}
2024-12-02 18:29:45 -05:00
</div>
);
};
type ProjectProps = {
title: string;
repo?: string;
summary: string;
tech: string;
wip?: boolean;
};