From 0766b46cc80605a310eb482526d5c54acc8108b9 Mon Sep 17 00:00:00 2001 From: denshooter Date: Sun, 15 Feb 2026 22:20:43 +0100 Subject: [PATCH] feat: implement dark mode infrastructure, optimize images, and add SEO structured data --- GEMINI.md | 47 ++++++++++++++++ app/[locale]/projects/[slug]/page.tsx | 26 ++++++++- app/__tests__/api/book-reviews.test.tsx | 69 ++++++++++++++++++++++++ app/__tests__/api/hobbies.test.tsx | 69 ++++++++++++++++++++++++ app/__tests__/api/tech-stack.test.tsx | 71 +++++++++++++++++++++++++ app/_ui/ProjectDetailClient.tsx | 11 +++- app/components/ClientProviders.tsx | 9 ++-- app/components/CurrentlyReading.tsx | 8 +-- app/components/Header.tsx | 5 +- app/components/Hero.tsx | 28 +++++----- app/components/ReadBooks.tsx | 8 +-- app/components/ThemeProvider.tsx | 11 ++++ app/components/ThemeToggle.tsx | 35 ++++++++++++ app/globals.css | 71 ++++++++++++++++--------- next.config.ts | 12 +++++ package-lock.json | 11 ++++ package.json | 1 + 17 files changed, 440 insertions(+), 52 deletions(-) create mode 100644 GEMINI.md create mode 100644 app/__tests__/api/book-reviews.test.tsx create mode 100644 app/__tests__/api/hobbies.test.tsx create mode 100644 app/__tests__/api/tech-stack.test.tsx create mode 100644 app/components/ThemeProvider.tsx create mode 100644 app/components/ThemeToggle.tsx diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 0000000..f582442 --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,47 @@ +# GEMINI.md - Portfolio Project Guide + +## Project Overview +Personal portfolio for Dennis Konkol (dk0.dev). A modern, high-performance Next.js 15 application featuring a "liquid" design system, integrated with Directus CMS and n8n for real-time status and content management. + +## Tech Stack & Architecture +- **Framework**: Next.js 15 (App Router), TypeScript, React 19. +- **UI/UX**: Tailwind CSS 3.4, Framer Motion 12, Three.js (Background). +- **Backend/Data**: PostgreSQL (Prisma), Redis (Caching), Directus (CMS), n8n (Automation). +- **i18n**: next-intl (German/English). + +## Core Principles for Gemini +- **Safe Failovers**: Always implement fallbacks for external APIs (Directus, n8n). The site must remain functional even if all external services are down. +- **Liquid Design**: Use custom `liquid-*` color tokens for consistency. +- **Performance**: Favor Server Components where possible; use `use client` only for interactivity. +- **Code Style**: clean, modular, and well-typed. Use functional components and hooks. +- **i18n first**: Never hardcode user-facing strings; always use `messages/*.json`. + +## Common Workflows + +### API Route Pattern +API routes should include: +- Rate limiting (via `lib/auth.ts`) +- Timeout protection +- Proper error handling with logging in development +- Type-safe responses + +### Component Pattern +- Use Framer Motion for entrance animations. +- Use `next/image` for all images to ensure optimization. +- Follow the `glassmorphism` aesthetic: `backdrop-blur-sm`, subtle borders, and gradient backgrounds. + +## Development Commands +- `npm run dev`: Full development environment. +- `npm run lint`: Run ESLint checks. +- `npm run test`: Run unit tests. +- `npm run test:e2e`: Run Playwright E2E tests. + +## Environment Variables (Key) +- `DIRECTUS_URL` & `DIRECTUS_STATIC_TOKEN`: CMS connectivity. +- `N8N_WEBHOOK_URL` & `N8N_SECRET_TOKEN`: Automation connectivity. +- `DATABASE_URL`: Prisma connection string. + +## Git Workflow +- Work on the `dev` branch. +- Use conventional commits: `feat:`, `fix:`, `chore:`, `docs:`, `refactor:`. +- Push to both GitHub and Gitea remotes. diff --git a/app/[locale]/projects/[slug]/page.tsx b/app/[locale]/projects/[slug]/page.tsx index 9311494..a986ca3 100644 --- a/app/[locale]/projects/[slug]/page.tsx +++ b/app/[locale]/projects/[slug]/page.tsx @@ -60,6 +60,30 @@ export default async function ProjectPage({ content: localizedContent, }; - return ; + const jsonLd = { + "@context": "https://schema.org", + "@type": "SoftwareSourceCode", + "name": localized.title, + "description": localized.description, + "codeRepository": localized.github, + "programmingLanguage": localized.technologies, + "author": { + "@type": "Person", + "name": "Dennis Konkol" + }, + "dateCreated": project.date, + "url": toAbsoluteUrl(`/${locale}/projects/${slug}`), + "image": localized.imageUrl ? toAbsoluteUrl(localized.imageUrl) : undefined, + }; + + return ( + <> +