rearch links, routes + add resume link

This commit is contained in:
2026-03-07 12:17:21 -06:00
parent 23d206de99
commit 1a5b5a336f
7 changed files with 104 additions and 49 deletions

View File

@@ -1,5 +1,7 @@
import "./about.scss";
import {lazy, PropsWithChildren} from "react";
import {HTMLProps, lazy} from "react";
import {Link} from "../router/Link";
import {Path} from "../router/router";
const About = lazy(() => import("./About.mdx"));
@@ -15,8 +17,8 @@ export default function AboutPage() {
</main>
}
function ExternalLink(props: PropsWithChildren & { href: string }) {
function ExternalLink(props: HTMLProps<HTMLAnchorElement>) {
return (
<a href={props.href} className="link external-link" target="_blank">{props.children}</a>
<Link {...props} href={props.href as Path} className="external-link" target="_blank">{props.children}</Link>
)
}

BIN
src/img/resume.pdf Executable file

Binary file not shown.

40
src/index.d.ts vendored
View File

@@ -19,49 +19,71 @@ declare module '*.md' {
export default MDXComponent;
}
declare module '*.pdf' {
import {Path} from "./router/router";
const src: Path;
export default src;
}
declare module '*.avif' {
const src: string;
import {Path} from "./router/router";
const src: Path;
export default src;
}
declare module '*.bmp' {
const src: string;
import {Path} from "./router/router";
const src: Path;
export default src;
}
declare module '*.gif' {
const src: string;
import {Path} from "./router/router";
const src: Path;
export default src;
}
declare module '*.jpg' {
const src: string;
import {Path} from "./router/router";
const src: Path;
export default src;
}
declare module '*.jpeg' {
const src: string;
import {Path} from "./router/router";
const src: Path;
export default src;
}
declare module '*.png' {
const src: string;
import {Path} from "./router/router";
const src: Path;
export default src;
}
declare module '*.webp' {
const src: string;
export default src;
import {Path} from "./router/router";
const src: Path;
export default src;
}
declare module '*.svg' {
import {Path} from "./router/router";
import * as React from 'react';
export const ReactComponent: React.FunctionComponent<React.SVGProps<
SVGSVGElement
> & { title?: string }>;
const src: string;
const src: Path;
export default src;
}

View File

@@ -2,12 +2,10 @@ import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.scss';
import {RouterProvider} from "./router/RouterContext";
import {Route} from "./router/Route";
import "@fontsource/inter"; // Defaults to weight 400
import "@fontsource/neuton"; // Defaults to weight 400
import "@fontsource/neuton";
import {Routes} from "./router/Route";
const Canvas = React.lazy(() => import("./index/Canvas"));
const About = React.lazy(() => import("./about/AboutPage"));
const Nav = React.lazy(() => import("./nav/Nav"));
const root = ReactDOM.createRoot(
@@ -18,15 +16,7 @@ root.render(
<React.StrictMode>
<RouterProvider>
<Nav/>
<Route path="/">
<Canvas/>
</Route>
<Route path="/about">
<About/>
</Route>
<Route path="/articles">
<div>Test</div>
</Route>
<Routes/>
</RouterProvider>
</React.StrictMode>
);

View File

@@ -1,21 +1,33 @@
import {useState} from "react";
import {Link} from "../router/Link";
import {motion} from "framer-motion";
import {ROUTES} from "../router/Route";
import ResumePdf from "../img/resume.pdf";
export function Links() {
const [links] = useState(["About", "Articles"]);
return <div className="links">
{ links.map(() => /* add spacers for flexbox */ <div/> )}
<Title/>
{ links.map(link => <Link href={`/${link}`}><h3>{link}</h3></Link>) }
</div>
}
function Title() {
return (
<Spacers length={ROUTES.length + 1} />
<Link href="/" className="name">
<motion.h1 className="name">Tymur Arsentiev</motion.h1>
</Link>
);
{
ROUTES.map(([path, name]) =>
<Link key={path} href={path}>
<h3>{name}</h3>
</Link>
)
}
<Link key={ResumePdf} href={ResumePdf} target="_blank">
<h3>Resume</h3>
</Link>
</div>
}
function Spacers(props: {length: number}) {
const spacers = [];
for (let i = 0; i < props.length; i++) {
spacers.push(<div key={i}/>);
}
return spacers;
}

View File

@@ -1,21 +1,29 @@
import "./link.scss";
import React, {PropsWithChildren} from "react";
import React, {HTMLProps, ReactNode} from "react";
import {useRouter} from "./RouterContext";
import {Path} from "./router";
export function Link(props: {className?: string, href: Path, replace?: boolean } & PropsWithChildren) {
const {children, className, href} = props;
export function Link(props: {href: Path, children : ReactNode, target?: '_blank' } & HTMLProps<HTMLAnchorElement>) {
let {children, className, href} = props;
const router = useRouter();
className = `${className} link`;
function onClick(event: React.MouseEvent) {
event.preventDefault();
if(window.location.pathname === href) {
router.replacePage(props.href);
} else {
router.pushPage(props.href);
}
// perform the default action if _blank
if(props.target === "_blank") {
return;
}
event.preventDefault();
if(window.location.pathname === href) {
router.replacePage(props.href);
} else {
router.pushPage(props.href);
}
}
return <a onClick={onClick} href={href} className={`${className} link`}>{children}</a>
return <a {...props} onClick={onClick} className={className}>
{children}
</a>
}

View File

@@ -1,10 +1,31 @@
import {PropsWithChildren} from "react";
import React, {PropsWithChildren} from "react";
import {useRouter} from "./RouterContext";
import {Path} from "./router";
export function Route(props: PropsWithChildren & {path: Path}) {
const Canvas = React.lazy(() => import("../index/Canvas"));
const About = React.lazy(() => import("../about/AboutPage"));
export const ROUTES: [Path, string][] = [
["/", "Home"],
["/about", "About"],
["/articles", "Articles"]
];
function Route(props: PropsWithChildren & {path: Path}) {
const {path, children} = props;
const router = useRouter();
return router.current.toLowerCase() === path ? <>{children}</> : <></>
return <>{router.current === path && children}</>
}
export function Routes() {
return <>
<Route path={ROUTES[0]![0]}>
<Canvas/>
</Route>
<Route path={ROUTES[1]![0]}>
<About/>
</Route>
</>
}