100 lines
3.4 KiB
TypeScript
100 lines
3.4 KiB
TypeScript
export type ProjectLink = { label: string; href: string };
|
||
|
||
export type ProjectSection = {
|
||
title: string;
|
||
content: string;
|
||
};
|
||
|
||
export type Project = {
|
||
slug: string;
|
||
title: string;
|
||
description: string;
|
||
tag: string;
|
||
href: string;
|
||
image: string;
|
||
year?: string;
|
||
stack?: string[];
|
||
status?: "Live" | "WIP" | "Archived";
|
||
links?: ProjectLink[];
|
||
sections?: ProjectSection[];
|
||
gallery?: string[];
|
||
};
|
||
|
||
export const projects: Project[] = [
|
||
{
|
||
slug: "unraid-docker",
|
||
title: "Unraid + Docker Homelab",
|
||
description:
|
||
"A private homelab used as a test enviroment to try out Docker containers and VM's. The current setup has a cloudflare tunnel for remote access and some media related containers. There is also a VM running Home Assistant for home automation.",
|
||
tag: "Homelab",
|
||
href: "/projects/unraid-docker",
|
||
image: "/projects/unraid_docker.png",
|
||
year: "2020-2026",
|
||
stack: ["Unraid", "Docker", "Cloudflare", "NPM"],
|
||
status: "WIP",
|
||
links: [
|
||
{ label: "Home", href: "/" },
|
||
{ label: "Lab", href: "/lab" },
|
||
{ label: "Projects", href: "/#projects" },
|
||
],
|
||
gallery: [
|
||
"/projects/unraid_docker.png",
|
||
"/projects/image_2026-02-21_112603143.png",
|
||
],
|
||
sections: [
|
||
{
|
||
title: "Goal",
|
||
content:
|
||
"A secure, cleanly routed homelab for testing purposes with the goal to make a permenant one, backed by containerized services and VM's",
|
||
},
|
||
{
|
||
title: "How it's routed",
|
||
content:
|
||
"Cloudflare Tunnel forwards to NPM. NPM handles host-based routing and access lists per subdomain.",
|
||
},
|
||
{
|
||
title: "Future Plans",
|
||
content:
|
||
"Have all services self-hosted to be less dependant on cloud services and subscriptions. Once there is no use for adding new containers this will be deployed permenantly.",
|
||
},
|
||
],
|
||
},
|
||
{
|
||
slug: "macropad",
|
||
title: "Macropad Controller",
|
||
description:
|
||
"A tactile control surface for workflows: 12 macro keys, 4 encoders, and RGB feedback — paired with a desktop app for press/hold macros and per-app volume control.",
|
||
tag: "Embedded + Desktop",
|
||
href: "/projects/macropad",
|
||
image: "/projects/macropad.png",
|
||
year: "2025–2026",
|
||
stack: ["ESP32", "USB HID", "FastLED", "Python", "GUI", "EEPROM"],
|
||
status: "WIP",
|
||
links: [
|
||
{ label: "Home", href: "/" },
|
||
{ label: "Projects", href: "/#projects" },
|
||
],
|
||
gallery: [
|
||
"/projects/macropad.png",
|
||
"/projects/Model.png",
|
||
],
|
||
sections: [
|
||
{
|
||
title: "What it is",
|
||
content:
|
||
"A programmable macropad with physical controls and real-time RGB feedback. It’s built for fast actions (macros), precise adjustments (encoders), and clear state visibility (LED rings).",
|
||
},
|
||
{
|
||
title: "Why it exists",
|
||
content:
|
||
"It was a new hobby learning about electronics and a wanted a simple macro button for my pc, but one thing led to the other and developed the full PCB for this together with 3d modeling for the case.",
|
||
},
|
||
{
|
||
title: "How it works",
|
||
content:
|
||
"The desktop app assigns press/hold macros and target apps for volume control. The ESP32 executes input logic with serial monitoring and that gets transformed into keyboard inputs, the LED animation is synced to system state of the assigned program's volume percentage..",
|
||
},
|
||
],
|
||
},
|
||
];
|