From 2943ace31b7cdd8a38282b697690be80a04df280 Mon Sep 17 00:00:00 2001 From: Alexander Daichendt Date: Thu, 14 Aug 2025 22:20:44 +0200 Subject: [PATCH] more project sectioning --- src/components/Carousel.astro | 214 ++++++++++++++++++++++++ src/components/ProjectSection.astro | 114 ++++++++++--- src/components/ThreeColumnSection.astro | 49 ++++++ src/consts.ts | 49 +++--- src/pages/index.astro | 45 ++--- 5 files changed, 401 insertions(+), 70 deletions(-) create mode 100644 src/components/Carousel.astro create mode 100644 src/components/ThreeColumnSection.astro diff --git a/src/components/Carousel.astro b/src/components/Carousel.astro new file mode 100644 index 0000000..74d21ad --- /dev/null +++ b/src/components/Carousel.astro @@ -0,0 +1,214 @@ +--- +// ────────────────────────────────────────────────────────────── +// Types & Props +// ────────────────────────────────────────────────────────────── +import type { ImageMetadata } from "astro"; + +interface Props { + /** Array of images for the carousel */ + images: { + /** Astro image metadata – we only need the `src` field */ + src: ImageMetadata; + /** Alt text for the image (required for accessibility) */ + alt: string; + }[]; +} + +const { images } = Astro.props; + +// ────────────────────────────────────────────────────────────── +// Unique ID – needed so multiple carousels on the same page don’t +// clash when we query the DOM from the diff --git a/src/components/ProjectSection.astro b/src/components/ProjectSection.astro index e8785c4..164ecf0 100644 --- a/src/components/ProjectSection.astro +++ b/src/components/ProjectSection.astro @@ -1,6 +1,8 @@ --- -import { Picture } from "astro:assets"; +import { Icon } from "astro-icon/components"; import { projects } from "../consts"; +import Carousel from "./Carousel.astro"; +import ThreeColumnSection from "./ThreeColumnSection.astro"; ---
@@ -10,31 +12,95 @@ import { projects } from "../consts"; Software I developed -
-
project details
+
+ { + projects.map((project) => ( + + {/* ---------- LEFT: Project details ---------- */} +
+
+ {/* Title + optional company */} +

+ {project.title} -
- { - projects.map((project, index) => ( -
- -- TODO: make it rotate through images, create new component for - this - + {/* Duration */} +

+ + {project.duration} +

+

+ + {/* Description */} +

+ {project.description} +

+ + {/* Tech stack */} +
+ {project.tech_stack.map((tech) => ( + + {tech} + + ))} +
+ + {/* Deliverables (optional) */} + {project.deliverables?.length && ( +
    + {project.deliverables.map((item) => ( +
  • {item}
  • + ))} +
+ )} + + {/* Links */} +
+ {project.live_url && ( + + Live + + )} + {project.repo_url && ( + + Repo + + )} +
+
- )) - } -
- + {/* ---------- CENTER: Carousel ---------- */} +
+
+ +
+
+ + {/* ---------- RIGHT: Empty for now ---------- */} +
diff --git a/src/components/ThreeColumnSection.astro b/src/components/ThreeColumnSection.astro new file mode 100644 index 0000000..5f17777 --- /dev/null +++ b/src/components/ThreeColumnSection.astro @@ -0,0 +1,49 @@ +--- +export interface Props { + bgClass?: string; + containerClass?: string; + maxWidth?: "sm" | "md" | "lg" | "xl" | "2xl" | "4xl" | "6xl" | "8xl"; + py?: string; + reverseOnMobile?: boolean; +} + +const { + bgClass = "", + containerClass = "", + maxWidth = "8xl", + py = "py-8 md:py-12", + reverseOnMobile = false, +} = Astro.props; + +const maxWidthClasses = { + sm: "max-w-sm", + md: "max-w-md", + lg: "max-w-lg", + xl: "max-w-xl", + "2xl": "max-w-2xl", + "4xl": "max-w-4xl", + "6xl": "max-w-6xl", + "8xl": "max-w-8xl", +}; +--- + +
+
+ +
+ +
+ + +
+ +
+ + +
+ +
+
+
diff --git a/src/consts.ts b/src/consts.ts index e6ea557..3c82246 100644 --- a/src/consts.ts +++ b/src/consts.ts @@ -45,29 +45,30 @@ export const projects: Project[] = [ // complexity: 4, // company: "TV1 GmbH", // }, - // { - // title: "VIDEO.TAXI Meetings", - // live_url: "https://meetings.video.taxi/", - // description: - // "Records, transcribes, and translates meetings (Webex, Teams, Zoom). Interfaces with the GraphQL API of VIDEO.TAXI. Architecure, development, and deployment all done by me. Greenfield project.", - // tech_stack: [ - // "Svelte", - // "TypeScript", - // "Tailwind CSS", - // "Express", - // "GraphQL", - // "PostgreSQL", - // "Docker", - // "OpenAPI", - // ], - // duration: "2024 - Present", - // company: "TV1 GmbH", - // deliverables: [ - // "Live Updating Dashboard", - // "Meeting Bots for Teams, Zoom and Webex", - // "Keycloak integration", - // ], - // }, + { + title: "VIDEO.TAXI Meetings", + live_url: "https://meetings.video.taxi/", + description: + "Records, transcribes, and translates meetings (Webex, Teams, Zoom). Interfaces with the GraphQL API of VIDEO.TAXI. Architecure, development, and deployment all done by me. Greenfield project.", + tech_stack: [ + "Svelte", + "TypeScript", + "Tailwind CSS", + "Express", + "GraphQL", + "PostgreSQL", + "Docker", + "OpenAPI", + ], + duration: "2024 - Present", + company: "TV1 GmbH", + deliverables: [ + "Live Updating Dashboard", + "Meeting Bots for Teams, Zoom and Webex", + "Keycloak integration", + ], + images: [], + }, // { // title: "Netbox PDU Plugin", // repo_url: "https://github.com/AlexDaichendt/axians-netbox-plugin-pdu", @@ -107,7 +108,7 @@ export const projects: Project[] = [ // company: "TV1 GmbH", // }, { - title: "Discretize -- Gear Optimizer", + title: "Discretize: Gear Optimizer", live_url: "https://optimizer.discretize.eu/", repo_url: "https://github.com/discretize/discretize-gear-optimizer", description: diff --git a/src/pages/index.astro b/src/pages/index.astro index 803df97..811b3f2 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,11 +1,10 @@ --- -import BaseLayout from "../layouts/BaseLayout.astro"; import me from "../assets/me.jpg"; -import { Image } from "astro:assets"; -import Picture from "../components/Picture.astro"; import Link from "../components/Link.astro"; -import { projects } from "../consts"; +import Picture from "../components/Picture.astro"; import ProjectSection from "../components/ProjectSection.astro"; +import ThreeColumnSection from "../components/ThreeColumnSection.astro"; +import BaseLayout from "../layouts/BaseLayout.astro"; const love = [ { @@ -59,16 +58,10 @@ const skills = { subtitle="Software Engineer, Linux Enthusiast, Lightweight Systems Advocate" className="w-full py-16 flex flex-col" > -
- + +
-
+

I am a privacy-first software engineer passionate about building web applications that are efficient, user-friendly, and respectful of your @@ -86,13 +79,18 @@ const skills = {

-
- +
+
-
+ -
-
+ +
+

@@ -111,10 +109,12 @@ const skills = { }

-
+
+ -
-
+ +
+

@@ -139,7 +139,8 @@ const skills = { }

-
+
+