From 1c78e959f66e1a4db08713757bd848feb833f330 Mon Sep 17 00:00:00 2001 From: Tymur Arsentiev Date: Fri, 25 Sep 2026 11:15:40 -0400 Subject: [PATCH] add LinkTree like links page --- src/img/links/gitea-logo.svg | 1 + src/img/links/github.svg | 3 ++ src/img/links/gmail.svg | 7 +++ src/img/links/instagram.svg | 20 +++++++++ src/img/links/linkedin.svg | 1 + src/img/links/scroll.svg | 84 ++++++++++++++++++++++++++++++++++++ src/links/LinkTree.tsx | 37 ++++++++++++++++ src/links/link.ts | 9 ++++ src/links/links.sass | 63 +++++++++++++++++++++++++++ src/links/links.ts | 65 ++++++++++++++++++++++++++++ src/nav/Links.tsx | 6 +-- src/router/Route.tsx | 11 +++-- webpack.config.ts | 2 +- 13 files changed, 300 insertions(+), 9 deletions(-) create mode 100644 src/img/links/gitea-logo.svg create mode 100644 src/img/links/github.svg create mode 100644 src/img/links/gmail.svg create mode 100644 src/img/links/instagram.svg create mode 100644 src/img/links/linkedin.svg create mode 100644 src/img/links/scroll.svg create mode 100644 src/links/LinkTree.tsx create mode 100644 src/links/link.ts create mode 100644 src/links/links.sass create mode 100644 src/links/links.ts diff --git a/src/img/links/gitea-logo.svg b/src/img/links/gitea-logo.svg new file mode 100644 index 0000000..a38ed78 --- /dev/null +++ b/src/img/links/gitea-logo.svg @@ -0,0 +1 @@ + diff --git a/src/img/links/github.svg b/src/img/links/github.svg new file mode 100644 index 0000000..54d698f --- /dev/null +++ b/src/img/links/github.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/img/links/gmail.svg b/src/img/links/gmail.svg new file mode 100644 index 0000000..6eb14e3 --- /dev/null +++ b/src/img/links/gmail.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/img/links/instagram.svg b/src/img/links/instagram.svg new file mode 100644 index 0000000..2a03d14 --- /dev/null +++ b/src/img/links/instagram.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/img/links/linkedin.svg b/src/img/links/linkedin.svg new file mode 100644 index 0000000..4044c0e --- /dev/null +++ b/src/img/links/linkedin.svg @@ -0,0 +1 @@ + diff --git a/src/img/links/scroll.svg b/src/img/links/scroll.svg new file mode 100644 index 0000000..248b09c --- /dev/null +++ b/src/img/links/scroll.svg @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/links/LinkTree.tsx b/src/links/LinkTree.tsx new file mode 100644 index 0000000..8512c7b --- /dev/null +++ b/src/links/LinkTree.tsx @@ -0,0 +1,37 @@ +import "./links.sass"; +import {Link as LinkBase} from "../router/Link"; +import {Path} from "../router/router"; +import {Link} from "./link"; +import {LINKS} from "./links"; +import {motion} from "motion/react"; +import {AnimateFade} from "../animations"; + +export default function LinkTree() { + return +
+ { + LINKS.map(link => ) + } +
+
+} + +function LinkBox(props: Link) { + const {name, desc, img, href} = props; + + return
+ +
+ { + img && {img.alt} + } +
+
+
+

{name}

+
+
{desc}
+
+
+
+} diff --git a/src/links/link.ts b/src/links/link.ts new file mode 100644 index 0000000..1469a7c --- /dev/null +++ b/src/links/link.ts @@ -0,0 +1,9 @@ +export interface Link { + name: string, + desc: string, + href: string, + img?: { + href: string, + alt: string + } +} diff --git a/src/links/links.sass b/src/links/links.sass new file mode 100644 index 0000000..2242b00 --- /dev/null +++ b/src/links/links.sass @@ -0,0 +1,63 @@ +@use "../about/about" +@use "../nav/nav" + +.link-tree + display: flex + flex-direction: column + flex-grow: 1 + background: about.$reader-bg + padding-top: 150px + +.link-ctr + margin: auto + display: flex + flex-direction: column + justify-content: center + +.link-box + display: flex + flex-direction: column + border-radius: 15px + margin: 15px + max-width: 400px + +.link-box-ctr + display: flex + +.link-img-ctr + background: white + display: flex + justify-content: center + align-items: center + border-radius: 15px 0 0 15px + +.link-img + padding: 15px + +.content-ctr + display: flex + flex-direction: column + flex-grow: 1 + &>* + display: flex + flex-direction: column + +.link-title + background: nav.$menu + border-radius: 0 15px 0 0 + padding: 10px + font-weight: bold + font-family: Neuton, serif + border-bottom: white 2px solid + h2 + margin: 0 + +.link-desc + background: black + color: white + font-family: Inter, sans-serif + padding: 10px + flex-grow: 1 + justify-content: center + align-items: center + border-radius: 0 0 15px 0 diff --git a/src/links/links.ts b/src/links/links.ts new file mode 100644 index 0000000..1e51906 --- /dev/null +++ b/src/links/links.ts @@ -0,0 +1,65 @@ +import {Link} from "./link"; +import ResumePdf from "../img/resume.pdf"; +import GiteaLogo from "../img/links/gitea-logo.svg"; +import LinkedInLogo from "../img/links/linkedin.svg"; +import GitHubLogo from "../img/links/github.svg"; +import InstagramLogo from "../img/links/instagram.svg"; +import GmailLogo from "../img/links/gmail.svg"; +import ResumeLogo from "../img/links/scroll.svg"; + +export const LINKS: Link[] = [ + { + name: "Gitea Profile", + desc: "Personal Gitea instance hosting this blog's source code with Gitea CI/CD and artifact storage", + href: "https://gitea.tymur999.com/tymur999", + img: { + alt: "Gitea logo", + href: GiteaLogo + } + }, + { + name: "LinkedIn", + desc: "Personal LinkedIn Account with work experiences and resume", + href: "https://www.linkedin.com/in/tymurarsent/", + img: { + alt: "LinkedIn logo", + href: LinkedInLogo + } + }, + { + name: "Github (Deprecated)", + desc: "GitHub account with old projects **moved to Gitea", + href: "https://github.com/tymur999", + img: { + alt: "GitHub logo", + href: GitHubLogo + } + }, + { + name: "Instagram", + desc: "Welcome to the aura factory.", + href: "https://www.instagram.com/_tymur999_/", + img: { + alt: "Instagram logo", + href: InstagramLogo + } + }, + { + name: "Email", + desc: "Please reach out with any questions or offers (tymur.arsent@gmail.com)", + href: "mailto:tymur.arsent@gmail.com", + img: { + alt: "Gmail logo", + href: GmailLogo + } + }, + { + name: "Resume", + desc: "Work experiences, current knowledge, education credentials", + href: ResumePdf, + img: { + alt: "Scroll of antique paper", + href: ResumeLogo + } + } +]; diff --git a/src/nav/Links.tsx b/src/nav/Links.tsx index 30293bf..77ef16a 100644 --- a/src/nav/Links.tsx +++ b/src/nav/Links.tsx @@ -2,7 +2,6 @@ import {Link} from "../router/Link"; import {ROUTES} from "../router/Route"; import ResumePdf from "../img/resume.pdf"; import {motion} from "motion/react"; -import {Path} from "../router/router"; export function Links() { @@ -20,8 +19,5 @@ export function Links() {

Resume

- -

GitHub

- -} \ No newline at end of file +} diff --git a/src/router/Route.tsx b/src/router/Route.tsx index 4359136..1d4f2cb 100644 --- a/src/router/Route.tsx +++ b/src/router/Route.tsx @@ -3,11 +3,12 @@ import {useRouter} from "./RouterContext"; import {Path} from "./router"; type Route = [Path, string]; -type Routes = [Route, Route, Route]; +type Routes = [Route, Route, Route, Route]; export const ROUTES: Routes = [ ["/", "Home"], ["/about", "About"], - ["/articles", "Articles"] + ["/articles", "Articles"], + ["/links", "Links"] ]; function Route(props: PropsWithChildren & {route: Route}) { @@ -23,9 +24,10 @@ function Route(props: PropsWithChildren & {route: Route}) { 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")); export function Routes() { - const [index, about, articles] = ROUTES; + const [index, about, articles, links] = ROUTES; return <> @@ -37,5 +39,8 @@ export function Routes() { + + + } \ No newline at end of file diff --git a/webpack.config.ts b/webpack.config.ts index b8a0f78..8cade4d 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -139,7 +139,7 @@ const config: webpack.Configuration = { plugins: [ new HtmlWebpackPlugin({ template: path.resolve(import.meta.dirname, "public/index.html"), - favicon: "./src/img/favicon.ico", + favicon: path.resolve(import.meta.dirname, "src/img/favicon.ico"), inject: true, }), new webpack.DefinePlugin({