wip: added project modal

still want to add carousel, summary, etc.
This commit is contained in:
2025-12-02 14:07:18 -05:00
parent 82cf30447b
commit 3e24c3936a
4 changed files with 252 additions and 12 deletions

View File

@@ -1,4 +1,10 @@
import { useState } from "preact/hooks";
import { Portal } from "./portal.tsx";
import { Modal } from "./modal.tsx";
export const ProjectCard = function ProjectCard(props: ProjectProps) {
const [open, setOpen] = useState(false);
return (
<div
class={`md:m-8 group space-y-1 rounded-md ${
@@ -13,25 +19,27 @@ export const ProjectCard = function ProjectCard(props: ProjectProps) {
}
: {}
}
onClick={() => props.repo && open(props.repo, "_blank")}
onClick={() => {
// clicking the card (not the link) opens the modal
console.log("opened portal");
setOpen(true);
}}
>
<div class="flex items-center justify-between">
<h2 class="text-lg text-white font-black uppercase">
<a href={props.repo} target="_blank">
<a
href={props.repo}
target="_blank"
onClick={(e) => {
// clicking the link should not open the modal
e.stopPropagation();
}}
>
{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 && (
<a
class="hover:underline"
href={props.repo}
target="_blank"
onClick={(e) => e.stopPropagation()}
>
Active
</a>
)}
{props.repo && <span>Active</span>}
{!props.repo && !props.wip && <span>Dead</span>}
{props.wip && <span>WIP</span>}
</div>
@@ -42,6 +50,38 @@ export const ProjectCard = function ProjectCard(props: ProjectProps) {
<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}
</div>
);
};