Finalised lab page

This commit is contained in:
GeorgeWebberley 2026-02-03 11:30:13 +01:00
parent ab481053bf
commit 8369d59310
8 changed files with 154 additions and 32 deletions

79
app/forge/page.tsx Normal file
View file

@ -0,0 +1,79 @@
"use client";
import { Hammer, History, Target, Code2 } from "lucide-react";
import PageLayout from "@/components/PageLayout";
export default function ForgePage() {
return (
<PageLayout backLink="/" maxWidth="5xl">
<header className="mb-20">
<div className="flex items-center gap-3 mb-4">
<Hammer className="text-orange-500 animate-pulse" size={24} />
<h1 className="text-4xl font-bold tracking-tighter text-white uppercase">
TheForge
</h1>
</div>
<p className="text-neutral-500 max-w-2xl leading-relaxed text-sm font-mono">
<br />
The Forge is where I document my current engineering focus. This space
reflects active builds, experimental prototypes and gives a taste of
my next releases.
</p>
</header>
{/* Main Project Card */}
<section className="bg-neutral-900/40 border border-neutral-800 rounded-2xl p-8 mb-16">
<div className="flex flex-wrap items-center justify-between gap-4 mb-8">
<div>
<h2 className="text-2xl font-bold text-white mb-2 italic">
Project: PixelPals
</h2>
<div className="flex gap-4">
<span className="text-[10px] text-orange-500 font-bold uppercase tracking-[0.2em]">
Build Phase: Alpha 0.1
</span>
<span className="text-[10px] text-neutral-600 font-bold uppercase tracking-[0.2em]">
Engine: Godot / GDScript
</span>
</div>
</div>
<div className="px-4 py-2 bg-orange-500/10 border border-orange-500/20 rounded-full">
<span className="text-[10px] text-orange-500 font-bold uppercase tracking-widest">
Active Focus
</span>
</div>
</div>
<p className="text-neutral-400 text-sm leading-relaxed mb-8">
Exploring procedural generation and state-machine-driven AI behaviors.
The goal is to bridge my experience in systems architecture with
real-time game loops and interactive storytelling.
</p>
{/* Milestones / Changelog */}
<div className="space-y-6">
<h3 className="flex items-center gap-2 text-xs font-bold text-neutral-500 uppercase tracking-widest border-b border-neutral-800 pb-2">
<History size={14} /> Development_Log
</h3>
<ul className="space-y-4">
<li className="flex gap-4">
<span className="text-xs text-neutral-600 font-mono mt-1 shrink-0">
2026-02-02
</span>
<p className="text-xs text-neutral-400">
Implemented dynamic weather patterns using custom shaders.
</p>
</li>
<li className="flex gap-4">
<span className="text-xs text-neutral-600 font-mono mt-1 shrink-0">
2026-01-28
</span>
<p className="text-xs text-neutral-400">
Optimized asset loading pipeline for faster initial scene entry.
</p>
</li>
</ul>
</div>
</section>
</PageLayout>
);
}

View file

@ -127,7 +127,7 @@ export default function InfrastructurePage() {
whileTap={{ scale: 0.98 }}
className="px-8 py-4 rounded-xl bg-white text-black font-bold text-[11px] uppercase tracking-[0.2em] flex items-center gap-3 transition-all duration-300"
>
Examine Logic
View case
<Zap size={14} />
</motion.div>
</Link>

View file

@ -1,6 +1,6 @@
"use client";
import { LAB_SERVICES } from "@/data/lab";
import { ExternalLink, Lock, Box, Terminal, Globe } from "lucide-react";
import { Lock, Box, Globe } from "lucide-react";
import { motion } from "framer-motion";
import Image from "next/image";
import PageLayout from "@/components/PageLayout";
@ -12,12 +12,12 @@ export default function LabPage() {
<div className="flex items-center gap-2 mb-4">
<Box className="text-blue-500" size={20} />
<h1 className="text-4xl font-bold tracking-tighter text-white uppercase">
System_Lab
System Lab
</h1>
</div>
<p className="text-neutral-500 max-w-2xl leading-relaxed text-sm">
A registry of operational services and experimental R&D. Services
labeled
A registry of self hosted operational services and experimental R&D.
Services labeled
<span className="text-blue-500"> [VPN]</span> are secured via
Tailscale to maintain a hardened perimeter for sensitive telemetry.
</p>

View file

@ -2,7 +2,7 @@
import Link from "next/link";
import { motion, Variants } from "framer-motion";
import { Globe, Smartphone, Server, Gamepad2 } from "lucide-react";
import { Globe, Smartphone, Server, Gamepad2, Hammer } from "lucide-react";
import { useState } from "react";
import MonitorCard from "@/components/MonitorCard";
import PageLayout from "@/components/PageLayout";
@ -170,20 +170,28 @@ export default function Home() {
/>
{/* Bottom Row: The Forge */}
<Link href="/forge" className="md:col-span-6">
<motion.div
variants={itemVariants}
className="md:col-span-6 p-8 rounded-3xl bg-neutral-900/50 border border-neutral-800 flex items-center gap-6 group hover:border-orange-500/30 transition-colors cursor-pointer"
className="p-8 rounded-3xl bg-neutral-900/50 border border-neutral-800 flex items-center gap-6 group hover:border-orange-500/30 transition-colors cursor-pointer"
>
<div className="p-4 bg-orange-500/10 rounded-2xl border border-orange-500/20 group-hover:border-orange-500/40 transition-colors">
<Gamepad2 className="text-orange-500 w-8 h-8" />
<Hammer className="text-orange-500 w-8 h-8 group-hover:rotate-12 transition-transform" />
</div>
<div>
<h3 className="font-bold text-xl">The Forge</h3>
<p className="text-sm text-neutral-500">
Indie Game Dev & Creative Prototypes
<div className="flex items-center gap-2 mb-0.5">
<h3 className="font-bold text-xl tracking-tight">
The Forge
</h3>
<span className="w-1.5 h-1.5 rounded-full bg-orange-500 animate-pulse" />
</div>
<p className="text-sm text-neutral-500 leading-tight">
A space where I demonstrate what I am currently working on and
any future projects.
</p>
</div>
</motion.div>
</Link>
</div>
</motion.div>
</PageLayout>

26
data/forge.ts Normal file
View file

@ -0,0 +1,26 @@
import { ForgeProject } from "@/types";
export const ACTIVE_BUILD: ForgeProject = {
id: "pixelpals",
name: "PixelPals",
status: "Alpha",
engine: "Godot 4.x",
description:
"A mobile-first creature collection game focusing on procedural behaviors and lightweight state-management.",
highlights: [
"State-machine AI",
"Custom Shader Pipelines",
"Mobile-optimized Loops",
],
externalLink: "/projects/pixelpals", // Link to your internal portfolio or a dedicated site
changelog: [
{
date: "2026-02-03",
update: "Refined touch-input latency for mobile devices.",
},
{
date: "2026-01-25",
update: "Integrated local SQLite database for creature persistence.",
},
],
};

View file

@ -9,7 +9,7 @@ export const LAB_SERVICES: LabService[] = [
stack: ["Next.js", "Node", "SQLite"],
visibility: "public",
url: "https://observatory.georgew.dev",
gitUrl: "https://git.georgew.dev/george/observatory",
gitUrl: "https://git.georgew.dev/georgew/mission-control",
image: "/lab/observatory.jpg",
uptimeId: 12,
},
@ -22,6 +22,7 @@ export const LAB_SERVICES: LabService[] = [
visibility: "public",
url: "https://surf.georgew.dev/d/adrx6b4/llangennith-beach-surf-data?orgId=1&from=now-24h&to=now&timezone=browser&refresh=1h&theme=dark&kiosk=true",
image: "/lab/surf-hub.jpg",
gitUrl: "https://git.georgew.dev/georgew/surf-hub",
uptimeId: 13,
},
{
@ -31,8 +32,8 @@ export const LAB_SERVICES: LabService[] = [
"Dedicated audiobook server for the household. Primarily used for our Brandon Sanderson, Patrick Rothfuss, and Dungeon Crawler Carl marathons.",
stack: ["Docker", "Compose", "Tailscale", "rclone"],
visibility: "tailscale",
url: "https://audio.georgew.dev",
image: "/lab/audiobookshelf.jpg",
gitUrl: "https://git.georgew.dev/georgew/audiobookshelf",
uptimeId: 6,
},
{
@ -42,8 +43,8 @@ export const LAB_SERVICES: LabService[] = [
"A specialized tracker for our anime watch-lists! Features custom metadata hooks to keep our seasonal progress in sync.",
stack: ["Docker", "Redis", "Tailscale"],
visibility: "tailscale",
url: "https://anime.georgew.dev",
image: "/lab/yamtrack.jpg",
gitUrl: "https://git.georgew.dev/georgew/yamtrack",
uptimeId: 11,
},
{
@ -53,8 +54,9 @@ export const LAB_SERVICES: LabService[] = [
"Personal document management system with OCR and automated tagging. Digitizing our physical mail and records into a searchable, versioned archive.",
stack: ["Docker", "Redis", "PostgreSQL"],
visibility: "tailscale",
url: "https://paperless.georgew.dev",
image: "/lab/paperless.jpg",
gitUrl: "https://git.georgew.dev/georgew/paperless-ngx",
uptimeId: 14,
},
{
@ -64,8 +66,8 @@ export const LAB_SERVICES: LabService[] = [
"Automated monitoring for the essentials: NASA news updates, hobby stock alerts, and Telegram pings the second a new episode of 'The Traitors' drops.",
stack: ["Telegram API", "Webhooks"],
visibility: "tailscale",
url: "https://alerts.georgew.dev",
image: "/lab/change-detection.jpg",
gitUrl: "https://git.georgew.dev/georgew/change-detection",
uptimeId: 15,
},
{
@ -75,7 +77,6 @@ export const LAB_SERVICES: LabService[] = [
"The 'Engine Room.' Utilizing Portainer for orchestration, Dozzle for log streaming, and Watchtower for automated container lifecycle management across the Hetzner node.",
stack: ["Portainer", "Dozzle", "Watchtower"],
visibility: "tailscale",
url: "https://portainer.georgew.dev",
image: "/lab/portainer.jpg",
},
{
@ -85,7 +86,6 @@ export const LAB_SERVICES: LabService[] = [
"The 'Source of Truth' for the home infrastructure. Contains deployment guides, network maps, and disaster recovery procedures for the entire node.",
stack: ["Wiki.js", "Markdown"],
visibility: "tailscale",
url: "https://wiki.georgew.dev",
image: "/lab/wikijs.jpg",
uptimeId: 5,
},
@ -93,11 +93,9 @@ export const LAB_SERVICES: LabService[] = [
id: "dashboard",
name: "System Dashboard",
description:
"The central entry point for the GeorgeW ecosystem. A high-level overview providing unified access to all public and VPN-secured services.",
stack: ["Next.js", "Docker", "Reverse Proxy"],
visibility: "public",
url: "https://dash.georgew.dev",
gitUrl: "https://git.georgew.dev/george/homepage",
"The central entry point for the GeorgeW ecosystem, used as my personal home page. A high-level overview providing unified access to all public and VPN-secured services.",
stack: ["Homepage", "Docker", "Reverse Proxy"],
visibility: "tailscale",
image: "/lab/dashboard.jpg",
},
];

BIN
public/lab/dashboard.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 KiB

View file

@ -47,3 +47,14 @@ export interface LabService {
image: string;
uptimeId?: number;
}
export interface ForgeProject {
id: string;
name: string;
status: "Alpha" | "Beta" | "R&D";
engine: string;
description: string;
highlights: string[];
externalLink?: string;
changelog: { date: string; update: string }[];
}