initial commit
This commit is contained in:
@@ -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;
|
||||
@@ -0,0 +1,5 @@
|
||||
import { HttpStatusCode } from "@solidjs/start";
|
||||
|
||||
<HttpStatusCode code={404} />
|
||||
|
||||
# Page Not Found
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
Reference in New Issue
Block a user