rearch links, routes + add resume link
This commit is contained in:
@@ -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
BIN
src/img/resume.pdf
Executable file
Binary file not shown.
40
src/index.d.ts
vendored
40
src/index.d.ts
vendored
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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>
|
||||
}
|
||||
@@ -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>
|
||||
</>
|
||||
}
|
||||
Reference in New Issue
Block a user