diff --git a/src/404/404.sass b/src/404/404.sass new file mode 100644 index 0000000..e87d358 --- /dev/null +++ b/src/404/404.sass @@ -0,0 +1,52 @@ +@use "../about/about" + + +.not-found + background: about.$reader-bg + display: flex + flex-direction: column + flex-grow: 1 + justify-content: center + align-items: center + h1,h2,h3,h4 + font-family: Neuton, serif + +.nf-ctr + display: flex + flex-direction: column + + h1,h2,h3,p + text-align: center + margin: 0 + +.nf-title + background: white + color: black + border-radius: 15px 15px 0 0 + padding: 15px + display: flex + flex-direction: column + h1 + margin: 10px 0 + font-size: 100px + h3 + font-size: 30px + margin-bottom: 10px + +.nf-desc + background: black + color: white + padding: 15px + border-radius: 0 0 15px 15px + +.routes-list + padding: 15px + display: flex + flex-direction: row + flex-wrap: wrap + gap: 15px + justify-content: center + align-items: center + a + font-size: 20px + text-decoration: underline diff --git a/src/404/NotFound.tsx b/src/404/NotFound.tsx new file mode 100644 index 0000000..0c363d7 --- /dev/null +++ b/src/404/NotFound.tsx @@ -0,0 +1,35 @@ +import "./404.sass"; +import { ROUTES } from "../router/Route"; +import { Link } from "../router/Link"; +import { motion } from "motion/react"; +import { AnimateSpin, AnimateFade } from "../animations"; +import { type Path } from "../router/router"; + +export default function NotFoundPage() { + return + +
+

404

+

This page was not found

+
+
+

Did you mistype the URL? Here are a list of common links

+
+ { + ROUTES.map( + ([path,name]) => + ) + } +
+
+
+
+} + +function LinkBox({path, name}: {path: Path, name: string}) { + return ( + +
{name}
+ + ); +} diff --git a/src/articles/reader.sass b/src/articles/reader.sass index 155f084..33fb11f 100644 --- a/src/articles/reader.sass +++ b/src/articles/reader.sass @@ -63,4 +63,4 @@ font-weight: bold color: red !important background: white - border-radius: 999px \ No newline at end of file + border-radius: 999px diff --git a/src/index.sass b/src/index.sass index 6ef9740..ea1e1d2 100644 --- a/src/index.sass +++ b/src/index.sass @@ -26,4 +26,4 @@ button border: none padding: 0 color: white - cursor: pointer \ No newline at end of file + cursor: pointer diff --git a/src/index/canvas.sass b/src/index/canvas.sass index 30f4794..feea2bd 100644 --- a/src/index/canvas.sass +++ b/src/index/canvas.sass @@ -20,4 +20,4 @@ align-self: flex-end position: fixed bottom: 0 - right: 15px \ No newline at end of file + right: 15px diff --git a/src/links/links.sass b/src/links/links.sass index 2242b00..23c37d1 100644 --- a/src/links/links.sass +++ b/src/links/links.sass @@ -47,7 +47,6 @@ border-radius: 0 15px 0 0 padding: 10px font-weight: bold - font-family: Neuton, serif border-bottom: white 2px solid h2 margin: 0 @@ -55,9 +54,11 @@ .link-desc background: black color: white - font-family: Inter, sans-serif - padding: 10px + padding: 15px flex-grow: 1 justify-content: center align-items: center border-radius: 0 0 15px 0 + + font-family: Neuton, serif + font-size: 20px diff --git a/src/router/Route.tsx b/src/router/Route.tsx index 1d4f2cb..fbe07d1 100644 --- a/src/router/Route.tsx +++ b/src/router/Route.tsx @@ -1,8 +1,8 @@ -import React, {PropsWithChildren} from "react"; +import React, {type PropsWithChildren, ReactElement} from "react"; import {useRouter} from "./RouterContext"; import {Path} from "./router"; -type Route = [Path, string]; +export type Route = [Path, string]; type Routes = [Route, Route, Route, Route]; export const ROUTES: Routes = [ ["/", "Home"], @@ -11,7 +11,8 @@ export const ROUTES: Routes = [ ["/links", "Links"] ]; -function Route(props: PropsWithChildren & {route: Route}) { +type RouteProps = PropsWithChildren & {route: Route}; +function Route(props: RouteProps) { const {route: [path], children} = props; const router = useRouter(); // remove search params @@ -25,22 +26,38 @@ const Canvas = React.lazy(() => import("../index/Canvas")); const About = React.lazy(() => import("../about/AboutPage")); const ArticlesList = React.lazy(() => import("../articles/ArticlesList")); const LinkTree = React.lazy(() => import("../links/LinkTree")); +const NotFound = React.lazy(() => import("../404/NotFound")); + +// ensures only one route is rendered at a time, with a virtual 404 page as fallback +function RouteSwitch({children}: {children: ReactElement[]}) { + const router = useRouter(); + + const child = children.find(child => { + const [expected] = child.props.route; + const [current] = /\/?\w*[^?]/.exec(router.current) ?? [location.pathname]; + return current === expected + }); + + return <>{child || } +} export function Routes() { const [index, about, articles, links] = ROUTES; return <> - - - - - - - - - - - - - -} \ No newline at end of file + + + + + + + + + + + + + + + +}