initial commit

This commit is contained in:
2025-01-23 11:16:33 -05:00
commit 25cabeb8df
57 changed files with 11214 additions and 0 deletions

67
src/routes/(home).tsx Normal file
View File

@@ -0,0 +1,67 @@
import { For } from "solid-js";
import { posts } from "~/data/posts";
import { Posts } from "~/components/Posts";
const links = [
"https://github.com/minhtrannhat",
"https://linkedin.com/in/minh-tran-nhat",
];
const Homepage = () => {
return (
<div>
<section class="flex flex-col sm:flex-row gap-2v sm:gap-3h">
<div class="font-medium">
<div class="flex items-end mb-1v gap-1h">
<img
class="inline-block h-2v select-none wave-image"
alt="wave emoji"
src="/images/wave-pixel.png"
/>
<p>Hi, Minh here.</p>
</div>
<p class="mb-1v">
I'm Minh Tran, a Computer Engineering student at Concordia
University, Montreal, Canada.
<br />
<br />
I'm most passionate about designing distributed systems that scales
but I'm also interested in compilers and systems programming. When
I'm not coding, I read books, listen to podcasts or study music
theory.
</p>
<p>
Say hi:{" "}
<a
class="underline"
target="_blank"
rel="noreferrer"
href="mailto:minh@minhtrannhat.com"
>
minh@minhtrannhat.com
</a>
</p>
</div>
<ul class="sm:mt-3v text-slate-600 dark:text-slate-200 text-base sm:text-sm leading-1">
<For each={links}>
{(link) => (
<li class="list-square hover:text-black dark:hover:text-white ml-2h leading-1">
<a
target="_blank"
rel="noreferrer"
href={link}
class="underline"
>
{link.replace("https://", "")}
</a>
</li>
)}
</For>
</ul>
</section>
<hr />
</div>
);
};
export default Homepage;

5
src/routes/[...404].mdx Normal file
View File

@@ -0,0 +1,5 @@
import { HttpStatusCode } from "@solidjs/start";
<HttpStatusCode code={404} />
# Page Not Found

View File

@@ -0,0 +1,30 @@
import { posts } from "~/data/posts";
import dayjs from "dayjs";
import { For } from "solid-js";
const Articles = () => {
return (
<div>
<ol class="flex flex-col gap-1v list-square ml-2h">
<For each={Object.values(posts)}>
{(post) => (
<li class="list-square ml-2h mb-1v">
<a
class="font-medium underline block"
href={`/blog/${post.slug}`}
>
{post.title}
</a>
<span class="text-xs leading-1 text-slate-600 dark:text-slate-400">
{dayjs(post.date).format("MMMM YYYY")}
</span>
</li>
)}
</For>
</ol>
</div>
);
};
export default Articles;

87
src/routes/blog.tsx Normal file
View File

@@ -0,0 +1,87 @@
import { For, Show } from "solid-js";
import type { RouteSectionProps } from "@solidjs/router";
import { Meta, Title } from "@solidjs/meta";
import { posts } from "~/data/posts";
import { MDXProvider } from "solid-mdx";
import { markdownComponents, PostImage } from "~/components/Markdown";
import dayjs from "dayjs";
import "../css/prism-theme.css";
import type { Post } from "~/types";
const Blog = (props: RouteSectionProps<unknown>) => {
const meta = () =>
posts.find((p) => props.location.pathname.endsWith(p.slug)) as Post;
const index = () => posts.indexOf(meta());
const prevMeta = () =>
index() === posts.length - 1 ? undefined : posts[index() + 1];
const nextMeta = () => (index() === 0 ? undefined : posts[index() - 1]);
return (
<article class="pb-5v">
<Title>minhtrannhat.com - {meta()?.title}</Title>
<Meta name="og:title" content={meta().title} />
<Meta name="description" content={meta().description} />
<Meta name="og:description" content={meta().description} />
<Show when={meta().featuredImage}>
<PostImage
class="mb-3v saturate-0"
src={meta().featuredImage || ""}
alt={meta().featuredImageDesc || ""}
/>
</Show>
<h1 class="text-2v leading-2 font-bold mb-1v">{meta().title}</h1>
<div class="flex items-center gap-4h mb-2v text-sm leading-1">
<p>{dayjs(meta().date).format("D MMMM YYYY")}</p>
<div class="">
<For each={meta().tags}>
{(tag, index) => (
<>
<a
href={`/tags/${tag}`}
class="font-medium underline underline-offset-2 italic"
>
{tag}
</a>
{index() === meta().tags.length - 1 ? "" : ", "}
</>
)}
</For>
</div>
</div>
<MDXProvider components={markdownComponents}>
{props.children}
</MDXProvider>
<div class="mt-3v flex flex-col gap-1v">
<Show when={prevMeta()} fallback={<div />}>
<div class="flex gap-1h">
<span>Previous:</span>
<a
class="underline underline-offset-2"
href={`/blog/${prevMeta()?.slug}`}
>
{prevMeta()?.title}
</a>
</div>
</Show>
<Show when={nextMeta()} fallback={<div />}>
<div class="flex gap-1h">
<span>Next:</span>
<a
class="underline underline-offset-2"
href={`/blog/${nextMeta()?.slug}`}
>
{nextMeta()?.title}
</a>
</div>
</Show>
</div>
</article>
);
};
export default Blog;

View File

@@ -0,0 +1,27 @@
import { For } from "solid-js";
import { tags } from "~/data/tags";
const Tags = () => {
return (
<div>
<h1 class="text-xl font-bold mt-2v mb-1v">All tags:</h1>
<ol class="flex flex-col gap-1v list-square ml-2h">
<For each={Object.values(tags)}>
{(tag) => (
<li class="">
<a class="underline underline-offset-2" href={`/tags/${tag.id}`}>
{tag.id}
</a>
<span>
{" "}
- {tag.posts.length} Post{tag.posts.length === 1 ? "" : "s"}
</span>
</li>
)}
</For>
</ol>
</div>
);
};
export default Tags;

20
src/routes/tags/[id].tsx Normal file
View File

@@ -0,0 +1,20 @@
import type { RouteSectionProps } from "@solidjs/router";
import { type Component, Show } from "solid-js";
import { posts } from "~/data/posts";
import { Posts } from "~/components/Posts";
import { tags } from "~/data/tags";
const TagId: Component<RouteSectionProps<unknown>> = (props) => {
const tag = () => tags[props.params.id];
return (
<Show when={tag()} fallback={<div>No posts with that tag</div>}>
<div>
<h1 class="text-lg font-bold mb-6">Tag: {tag().id}</h1>
<Posts posts={tag().posts.map((i) => posts[i])} />
</div>
</Show>
);
};
export default TagId;