initial commit
This commit is contained in:
		
							
								
								
									
										67
									
								
								src/routes/(home).tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/routes/(home).tsx
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										5
									
								
								src/routes/[...404].mdx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
import { HttpStatusCode } from "@solidjs/start";
 | 
			
		||||
 | 
			
		||||
<HttpStatusCode code={404} />
 | 
			
		||||
 | 
			
		||||
# Page Not Found
 | 
			
		||||
							
								
								
									
										30
									
								
								src/routes/articles/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/routes/articles/index.tsx
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										87
									
								
								src/routes/blog.tsx
									
									
									
									
									
										Normal 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;
 | 
			
		||||
							
								
								
									
										27
									
								
								src/routes/tags/(tags).tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/routes/tags/(tags).tsx
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										20
									
								
								src/routes/tags/[id].tsx
									
									
									
									
									
										Normal 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;
 | 
			
		||||
		Reference in New Issue
	
	Block a user