From 0c0ee849a630f125a8f08c10ee71dfdbc6b7c7ce Mon Sep 17 00:00:00 2001
From: schererleander
Date: Fri, 27 Jun 2025 00:42:58 +0200
Subject: chore
---
src/App.tsx | 16 +++---
src/components/Card.tsx | 82 +++++++++++++++++++++++++++++
src/components/CardLink.tsx | 82 -----------------------------
src/components/Gallery.tsx | 100 ++++++++++++++++++++++++++++++++++++
src/components/ImageGalleryGrid.tsx | 100 ------------------------------------
src/index.css | 13 +++--
src/pages/404.tsx | 21 ++++++++
src/pages/404Page.tsx | 21 --------
src/pages/Blog.tsx | 19 +++----
src/pages/Gear.tsx | 8 +--
src/pages/Home.tsx | 8 +--
src/pages/Post.tsx | 8 +--
src/pages/Projects.tsx | 8 +--
13 files changed, 246 insertions(+), 240 deletions(-)
create mode 100644 src/components/Card.tsx
delete mode 100644 src/components/CardLink.tsx
create mode 100644 src/components/Gallery.tsx
delete mode 100644 src/components/ImageGalleryGrid.tsx
create mode 100644 src/pages/404.tsx
delete mode 100644 src/pages/404Page.tsx
(limited to 'src')
diff --git a/src/App.tsx b/src/App.tsx
index dba1c7c..ca7bcb4 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,10 +1,10 @@
import { Routes, Route } from 'react-router-dom';
import Navbar from './components/Navbar';
-import GearPage from './pages/Gear';
-import HomePage from './pages/Home';
-import ProjectsPage from './pages/Projects';
+import Gear from './pages/Gear';
+import Home from './pages/Home';
+import Projects from './pages/Projects';
import Footer from './components/Footer';
-import NotFoundPage from './pages/404Page';
+import NotFound from './pages/404';
import Blog from './pages/Blog';
import Post from './pages/Post';
@@ -15,12 +15,12 @@ function App() {
- } />
- } />
- } />
+ } />
+ } />
+ } />
} />
} />
- } />
+ } />
diff --git a/src/components/Card.tsx b/src/components/Card.tsx
new file mode 100644
index 0000000..e71cf33
--- /dev/null
+++ b/src/components/Card.tsx
@@ -0,0 +1,82 @@
+import { useRef, useState } from "react";
+
+function Icon() {
+ return ;
+}
+
+interface Props {
+ title: string;
+ body: string;
+ href?: string;
+ imgSrc?: string;
+}
+
+export default function CardLink({ title, body, href, imgSrc }: Props) {
+ const divRef = useRef(null);
+ const [position, setPosition] = useState({ x: 0, y: 0 });
+ const [opacity, setOpacity] = useState(0);
+
+ const handleMouseMove: React.MouseEventHandler = (e) => {
+ if (!divRef.current) return;
+ const rect = divRef.current.getBoundingClientRect();
+ setPosition({ x: e.clientX - rect.left, y: e.clientY - rect.top });
+ };
+
+ const handleMouseEnter = () => setOpacity(0.6);
+ const handleMouseLeave = () => setOpacity(0);
+
+ return (
+ window.open(href, "_blank", "noopener,noreferrer"),
+ role: "link",
+ tabIndex: 0,
+ })}
+ >
+ {/* Spotlight overlay - light */}
+
+
+ {/* Spotlight overlay - dark mode */}
+
+
+ {/* Content */}
+ {imgSrc && (
+
+ )}
+
+ {href &&
}
+
+ );
+}
diff --git a/src/components/CardLink.tsx b/src/components/CardLink.tsx
deleted file mode 100644
index e71cf33..0000000
--- a/src/components/CardLink.tsx
+++ /dev/null
@@ -1,82 +0,0 @@
-import { useRef, useState } from "react";
-
-function Icon() {
- return ;
-}
-
-interface Props {
- title: string;
- body: string;
- href?: string;
- imgSrc?: string;
-}
-
-export default function CardLink({ title, body, href, imgSrc }: Props) {
- const divRef = useRef(null);
- const [position, setPosition] = useState({ x: 0, y: 0 });
- const [opacity, setOpacity] = useState(0);
-
- const handleMouseMove: React.MouseEventHandler = (e) => {
- if (!divRef.current) return;
- const rect = divRef.current.getBoundingClientRect();
- setPosition({ x: e.clientX - rect.left, y: e.clientY - rect.top });
- };
-
- const handleMouseEnter = () => setOpacity(0.6);
- const handleMouseLeave = () => setOpacity(0);
-
- return (
- window.open(href, "_blank", "noopener,noreferrer"),
- role: "link",
- tabIndex: 0,
- })}
- >
- {/* Spotlight overlay - light */}
-
-
- {/* Spotlight overlay - dark mode */}
-
-
- {/* Content */}
- {imgSrc && (
-
- )}
-
- {href &&
}
-
- );
-}
diff --git a/src/components/Gallery.tsx b/src/components/Gallery.tsx
new file mode 100644
index 0000000..ffcf0e1
--- /dev/null
+++ b/src/components/Gallery.tsx
@@ -0,0 +1,100 @@
+import React, { useState, useEffect } from 'react';
+
+interface ImageItems {
+ images: Array<{
+ src: string;
+ alt?: string;
+ id?: string | number;
+ }>;
+}
+
+export default function Gallery({ images }: ImageItems) {
+ const [selectedIndex, setSelectedIndex] = useState(null);
+ const closeModal = () => setSelectedIndex(null);
+ const prev = (e?: React.MouseEvent) => {
+ e?.stopPropagation();
+ setSelectedIndex((i) => (i !== null && i > 0 ? i - 1 : i));
+ };
+ const next = (e?: React.MouseEvent) => {
+ e?.stopPropagation();
+ setSelectedIndex((i) => (i !== null && i < images.length - 1 ? i + 1 : i));
+ };
+
+ useEffect(() => {
+ function handleKeyDown(event: KeyboardEvent) {
+ if (selectedIndex === null) return;
+ if (event.key === 'ArrowLeft') {
+ prev();
+ } else if (event.key === 'ArrowRight') {
+ next();
+ }
+ }
+
+ window.addEventListener('keydown', handleKeyDown);
+ return () => window.removeEventListener('keydown', handleKeyDown);
+ }, [selectedIndex, images.length]);
+
+ return (
+ <>
+
+ {images.map((image, idx) => (
+
setSelectedIndex(idx)}
+ >
+
+
+ ))}
+
+
+ {/* Overlay */}
+ {selectedIndex !== null && (
+
+ {/* Prev arrow */}
+
+ ←
+
+
+
+
+ {/* Next arrow */}
+
+ →
+
+
{
+ e.stopPropagation();
+ closeModal();
+ }}
+ className="absolute top-4 right-4 text-black dark:text-white text-3xl"
+ >
+ ×
+
+
+ )}
+ >
+ );
+}
diff --git a/src/components/ImageGalleryGrid.tsx b/src/components/ImageGalleryGrid.tsx
deleted file mode 100644
index 0b657cf..0000000
--- a/src/components/ImageGalleryGrid.tsx
+++ /dev/null
@@ -1,100 +0,0 @@
-import React, { useState, useEffect } from 'react';
-
-interface ImageItems {
- images: Array<{
- src: string;
- alt?: string;
- id?: string | number;
- }>;
-}
-
-export default function ImageGalleryGrid({ images }: ImageItems) {
- const [selectedIndex, setSelectedIndex] = useState(null);
- const closeModal = () => setSelectedIndex(null);
- const prev = (e?: React.MouseEvent) => {
- e?.stopPropagation();
- setSelectedIndex((i) => (i !== null && i > 0 ? i - 1 : i));
- };
- const next = (e?: React.MouseEvent) => {
- e?.stopPropagation();
- setSelectedIndex((i) => (i !== null && i < images.length - 1 ? i + 1 : i));
- };
-
- useEffect(() => {
- function handleKeyDown(event: KeyboardEvent) {
- if (selectedIndex === null) return;
- if (event.key === 'ArrowLeft') {
- prev();
- } else if (event.key === 'ArrowRight') {
- next();
- }
- }
-
- window.addEventListener('keydown', handleKeyDown);
- return () => window.removeEventListener('keydown', handleKeyDown);
- }, [selectedIndex, images.length]);
-
- return (
- <>
-
- {images.map((image, idx) => (
-
setSelectedIndex(idx)}
- >
-
-
- ))}
-
-
- {/* Overlay */}
- {selectedIndex !== null && (
-
- {/* Prev arrow */}
-
- ←
-
-
-
-
- {/* Next arrow */}
-
- →
-
-
{
- e.stopPropagation();
- closeModal();
- }}
- className="absolute top-4 right-4 text-black dark:text-white text-3xl"
- >
- ×
-
-
- )}
- >
- );
-}
diff --git a/src/index.css b/src/index.css
index fcfe02a..4e1f7d9 100644
--- a/src/index.css
+++ b/src/index.css
@@ -3,7 +3,10 @@
@custom-variant dark (&:where(.dark, .dark *));
@layer base {
- body {
+
+ html,
+ body,
+ #root {
@apply bg-white dark:bg-black/95;
}
@@ -31,15 +34,15 @@
@apply text-xl font-semibold dark:text-gray-200;
}
- article>*>p {
+ .post p {
@apply mb-4 leading-relaxed;
}
- article>*>ul {
+ .post ul {
@apply list-disc pl-6 space-y-1;
}
- article>*>*>img {
+ .post img {
@apply mx-auto mb-4 w-64 rounded-lg shadow;
}
@@ -51,7 +54,7 @@
@apply underline text-purple-500;
}
- pre {
+ .post pre {
@apply whitespace-pre overflow-x-auto max-w-full max-h-80 rounded-lg border p-2 my-2 border-neutral-300 dark:border-neutral-800 bg-neutral-100 dark:bg-neutral-900;
}
diff --git a/src/pages/404.tsx b/src/pages/404.tsx
new file mode 100644
index 0000000..d9eed89
--- /dev/null
+++ b/src/pages/404.tsx
@@ -0,0 +1,21 @@
+import { useNavigate } from "react-router-dom";
+import { useEffect } from "react";
+
+export default function NotFound() {
+ const navigate = useNavigate();
+
+ useEffect(() => {
+ const timer = setTimeout(() => {
+ navigate('/', { replace: true });
+ }, 4000);
+
+ return () => clearTimeout(timer);
+ }, [navigate]);
+
+ return (
+ <>
+ 404 - Not found
+
+ >
+ );
+}
diff --git a/src/pages/404Page.tsx b/src/pages/404Page.tsx
deleted file mode 100644
index d7bfa10..0000000
--- a/src/pages/404Page.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { useNavigate } from "react-router-dom";
-import { useEffect } from "react";
-
-export default function NotFoundPage() {
- const navigate = useNavigate();
-
- useEffect(() => {
- const timer = setTimeout(() => {
- navigate('/', { replace: true });
- }, 4000);
-
- return () => clearTimeout(timer);
- }, [navigate]);
-
- return (
- <>
- 404 - Not found
-
- >
- );
-}
diff --git a/src/pages/Blog.tsx b/src/pages/Blog.tsx
index 47b44d6..fb07fb1 100644
--- a/src/pages/Blog.tsx
+++ b/src/pages/Blog.tsx
@@ -1,6 +1,6 @@
-import CardLink from "../components/CardLink";
+import Card from "../components/Card";
-interface PostMeta {
+interface Meta {
slug: string;
title: string;
date: string;
@@ -10,13 +10,13 @@ interface PostMeta {
const postFiles = import.meta.glob("../blog/*.md", { eager: true }) as Record<
string,
- { attributes: Omit }
+ { attributes: Omit }
>;
-const posts: PostMeta[] = Object.entries(postFiles)
+const posts: Meta[] = Object.entries(postFiles)
.map(([path, mod]) => ({
slug: path.split("/").pop()!.replace(".md", ""),
- ...(mod.attributes as Omit),
+ ...(mod.attributes as Omit ),
}))
.sort(
(a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()
@@ -24,18 +24,19 @@ const posts: PostMeta[] = Object.entries(postFiles)
export default function Blog() {
return (
-
- Blog
+ <>
+ ߸ projects
+ Blog
{posts.map((post) => (
-
))}
-
+ >
);
}
diff --git a/src/pages/Gear.tsx b/src/pages/Gear.tsx
index dbbcdfb..a1984ee 100644
--- a/src/pages/Gear.tsx
+++ b/src/pages/Gear.tsx
@@ -1,4 +1,4 @@
-import CardLink from '../components/CardLink';
+import Card from '../components/Card';
import {
dailyDrivers,
@@ -14,7 +14,7 @@ function PartsGroup({ title, parts }: { title?: string; parts: Part[] }) {
{parts.map((p) => (
-
߸ gear
@@ -40,4 +40,4 @@ export default function GearPage() {
>
);
-}
\ No newline at end of file
+}
diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx
index 2048122..9b73c05 100644
--- a/src/pages/Home.tsx
+++ b/src/pages/Home.tsx
@@ -1,6 +1,6 @@
-import ImageGalleryGrid from "../components/ImageGalleryGrid";
+import Gallery from "../components/Gallery";
-export default function HomePage() {
+export default function Home() {
return (
<>
߸ hi
@@ -10,7 +10,7 @@ export default function HomePage() {
I have a passion for hardware and software, studying computer science. Currently building own 3d printing projects and learning nix.
-
>
);
-}
\ No newline at end of file
+}
diff --git a/src/pages/Post.tsx b/src/pages/Post.tsx
index b2b1d5b..76396ae 100644
--- a/src/pages/Post.tsx
+++ b/src/pages/Post.tsx
@@ -26,7 +26,7 @@ export default function Post() {
const { attributes: meta, ReactComponent: Content } = post;
return (
-
+ <>
← Back
@@ -41,7 +41,9 @@ export default function Post() {
{meta.title}
{formDate.format(new Date(meta.date))}
-
-
+
+
+
+ >
);
}
diff --git a/src/pages/Projects.tsx b/src/pages/Projects.tsx
index d49a3d2..973eaa0 100644
--- a/src/pages/Projects.tsx
+++ b/src/pages/Projects.tsx
@@ -1,7 +1,7 @@
-import CardLink from '../components/CardLink';
+import Card from '../components/Card';
import { projects, type Project } from '../data/projects';
-export default function ProjectsPage() {
+export default function Projects() {
return (
<>
߸ projects
@@ -10,7 +10,7 @@ export default function ProjectsPage() {
{projects.map((p: Project) => (
-
>
);
-}
\ No newline at end of file
+}
--
cgit v1.3.1