This commit is contained in:
parent
54644e3195
commit
60e2aed9f9
3 changed files with 127 additions and 0 deletions
|
|
@ -10,6 +10,7 @@ import ContactPage from "./pages/ContactPage";
|
|||
import RaycasterPage from "./pages/project/RaycasterPage";
|
||||
import RaytracerPage from "./pages/project/RaytracerPage";
|
||||
import EmulatorPage from "./pages/project/EmulatorPage";
|
||||
import NotFoundPage from "./pages/NotFoundPage";
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
|
|
@ -86,6 +87,14 @@ export default function App() {
|
|||
</PageTransition>
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
path="*404"
|
||||
component={() => (
|
||||
<PageTransition>
|
||||
<NotFoundPage />
|
||||
</PageTransition>
|
||||
)}
|
||||
/>
|
||||
</Route>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,20 @@ export const homeMetadata = {
|
|||
"Mike Karl — Systementwickler & Creative Technologist aus Grafenau. Portfolio mit Projekten aus Systems Programming, Computer Graphics und Low-Level-Entwicklung.",
|
||||
};
|
||||
|
||||
export const notFoundPage = {
|
||||
metadata: {
|
||||
title: "404 — Seite nicht gefunden",
|
||||
description: "Die angeforderte Seite existiert nicht.",
|
||||
},
|
||||
label: "404 — Seite nicht gefunden",
|
||||
title: "404",
|
||||
subtitle: "Die angeforderte Route existiert nicht oder wurde verschoben.",
|
||||
terminalPrompt: "$ navigate",
|
||||
terminalError: "ENOENT — route not found",
|
||||
homeCta: "Zur Startseite",
|
||||
browseLabel: "Oder schau dich um:",
|
||||
};
|
||||
|
||||
export const heroContent = {
|
||||
subtitle: [
|
||||
"Full-Stack Entwickler",
|
||||
|
|
|
|||
104
src/pages/NotFoundPage.tsx
Normal file
104
src/pages/NotFoundPage.tsx
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
import { A, useLocation } from "@solidjs/router";
|
||||
import { For } from "solid-js";
|
||||
import { ArrowRight, Home } from "lucide-solid";
|
||||
import { usePageMeta } from "@/lib/meta";
|
||||
import { navLinks, notFoundPage } from "@/data/site";
|
||||
|
||||
export default function NotFoundPage() {
|
||||
const location = useLocation();
|
||||
|
||||
usePageMeta(
|
||||
notFoundPage.metadata.title,
|
||||
notFoundPage.metadata.description
|
||||
);
|
||||
|
||||
return (
|
||||
<main class="relative min-h-screen bg-deep-space overflow-hidden flex items-center">
|
||||
<div
|
||||
class="absolute inset-0 pointer-events-none"
|
||||
style={{
|
||||
background:
|
||||
"radial-gradient(ellipse at 50% 30%, rgba(232,97,1,0.06) 0%, transparent 55%)",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
class="absolute inset-0 pointer-events-none"
|
||||
style={{
|
||||
background:
|
||||
"linear-gradient(to bottom, transparent 60%, #0F0E0C 100%)",
|
||||
}}
|
||||
/>
|
||||
|
||||
<section class="relative z-10 w-full pt-32 pb-24 px-[5vw]">
|
||||
<div class="max-w-[640px] mx-auto text-center space-y-8">
|
||||
<p class="section-label">{notFoundPage.label}</p>
|
||||
|
||||
<h1
|
||||
class="font-display font-bold text-text-primary leading-[0.85] tracking-tight"
|
||||
style={{ "font-size": "clamp(5rem, 18vw, 9rem)" }}
|
||||
>
|
||||
{notFoundPage.title}
|
||||
</h1>
|
||||
|
||||
<div class="flex items-center justify-center gap-4">
|
||||
<div class="w-[60px] h-px bg-amber" />
|
||||
<p class="font-mono text-text-secondary text-xs md:text-sm tracking-wider uppercase">
|
||||
Not Found
|
||||
</p>
|
||||
<div class="w-[60px] h-px bg-amber" />
|
||||
</div>
|
||||
|
||||
<p class="text-text-secondary text-lg leading-relaxed">
|
||||
{notFoundPage.subtitle}
|
||||
</p>
|
||||
|
||||
<div class="border border-warm-grey bg-charcoal p-5 md:p-6 text-left code-block">
|
||||
<p class="text-text-secondary mb-3">
|
||||
{notFoundPage.terminalPrompt}{" "}
|
||||
<span class="text-text-primary">{location.pathname}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="keyword">Error</span>
|
||||
{": "}
|
||||
<span class="type">ENOENT</span>
|
||||
<span class="text-text-secondary"> — </span>
|
||||
<span class="string">{notFoundPage.terminalError}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col sm:flex-row items-center justify-center gap-4 pt-2">
|
||||
<A
|
||||
href="/"
|
||||
class="inline-flex items-center gap-2 px-6 py-3 bg-amber text-deep-space font-display font-medium hover:bg-amber-hover transition-colors"
|
||||
>
|
||||
<Home size={18} />
|
||||
{notFoundPage.homeCta}
|
||||
</A>
|
||||
</div>
|
||||
|
||||
<div class="pt-4 space-y-4">
|
||||
<p class="font-mono text-text-secondary text-xs uppercase tracking-wider">
|
||||
{notFoundPage.browseLabel}
|
||||
</p>
|
||||
<div class="flex flex-wrap items-center justify-center gap-3">
|
||||
<For each={navLinks}>
|
||||
{(link) => (
|
||||
<A
|
||||
href={link.href}
|
||||
class="inline-flex items-center gap-1.5 text-sm text-text-secondary hover:text-amber transition-colors group"
|
||||
>
|
||||
<span class="text-link">{link.label}</span>
|
||||
<ArrowRight
|
||||
size={14}
|
||||
class="opacity-0 -translate-x-1 group-hover:opacity-100 group-hover:translate-x-0 transition-all"
|
||||
/>
|
||||
</A>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue