Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8,462 changes: 8,462 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

19 changes: 17 additions & 2 deletions src/app/blog/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { formatDate, getBlogPosts } from "@/app/blog/utils";
import { baseUrl } from "@/app/sitemap";
import JsonLd from "@/components/json-ld";
import { Labels } from "@/components/label";
import { CustomMDX } from "@/components/mdx";
import ShareButtons from "@/components/share-buttons";
import { siteConfig } from "@/config/site";
Expand Down Expand Up @@ -37,6 +38,13 @@ export async function generateMetadata(props: Props): Promise<Metadata> {
? image
: `${baseUrl}/og?title=${encodeURIComponent(title)}`;

// Build keywords string including labels
const keywordsArray = [title, "blog", "technology", "programming", "life"];
if (post.metadata.labels && post.metadata.labels.length > 0) {
keywordsArray.push(...post.metadata.labels);
}
const keywords = keywordsArray.join(", ");

return {
title: `${title}`,
description,
Expand Down Expand Up @@ -64,7 +72,7 @@ export async function generateMetadata(props: Props): Promise<Metadata> {
alternates: {
canonical: `/blog/${post.slug}`,
},
keywords: `${title}, blog, technology, programming, life, everything in between`,
keywords,
authors: [{ name: siteConfig.name }],
robots: {
index: true,
Expand Down Expand Up @@ -118,19 +126,26 @@ export default async function Blog(props: Props) {
"@type": "WebPage",
"@id": `${baseUrl}/blog/${post.slug}`,
},
...(post.metadata.labels &&
post.metadata.labels.length > 0 && {
keywords: post.metadata.labels.join(", "),
}),
}}
/>
<header className="mb-8">
<h1 className="p-name title font-display text-2xl md:text-3xl font-medium tracking-tight mb-3">
{post.metadata.title}
</h1>
<div className="flex items-center gap-4">
<div className="flex items-center gap-4 mb-3">
<time className="dt-published text-sm text-(--color-text-secondary)">
{formatDate(post.metadata.publishedAt)}
</time>
<div className="border-l border-(--color-border) h-4" />
<ShareButtons url={postUrl} title={post.metadata.title} />
</div>
{post.metadata.labels && post.metadata.labels.length > 0 && (
<Labels labels={post.metadata.labels} />
)}
</header>

<div className="e-content prose">
Expand Down
22 changes: 21 additions & 1 deletion src/app/blog/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ type Metadata = {
publishedAt: string;
summary: string;
image?: string;
labels?: string[];
};

function parseFrontmatter(fileContent: string) {
Expand All @@ -19,9 +20,28 @@ function parseFrontmatter(fileContent: string) {
// biome-ignore lint/complexity/noForEach: <explanation>
frontMatterLines?.forEach((line) => {
const [key, ...valueArr] = line.split(": ");
const trimmedKey = key.trim();
let value = valueArr.join(": ").trim();
value = value.replace(/^['"](.*)['"]$/, "$1"); // Remove quotes
metadata[key.trim() as keyof Metadata] = value;

// Handle labels array
if (trimmedKey === "labels") {
const labelsMatch = value.match(/\[(.*)\]/);
if (labelsMatch) {
metadata.labels = labelsMatch[1]
.split(",")
.map((label) => label.trim().replace(/^['"](.*)['"]$/, "$1"))
.filter((label) => label.length > 0);
}
} else if (trimmedKey === "title") {
metadata.title = value;
} else if (trimmedKey === "publishedAt") {
metadata.publishedAt = value;
} else if (trimmedKey === "summary") {
metadata.summary = value;
} else if (trimmedKey === "image") {
metadata.image = value;
}
});

return { metadata: metadata as Metadata, content };
Expand Down
16 changes: 12 additions & 4 deletions src/app/feed.xml/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,23 @@ export async function GET() {
);

const items = posts
.map(
(post) => ` <item>
.map((post) => {
const categories =
post.metadata.labels && post.metadata.labels.length > 0
? post.metadata.labels
.map((label) => ` <category>${escapeXml(label)}</category>`)
.join("\n")
: "";

return ` <item>
<title>${escapeXml(post.metadata.title)}</title>
<link>${baseUrl}/blog/${post.slug}</link>
<description>${escapeXml(post.metadata.summary)}</description>
<pubDate>${new Date(post.metadata.publishedAt).toUTCString()}</pubDate>
<guid isPermaLink="true">${baseUrl}/blog/${post.slug}</guid>
</item>`,
)
${categories}
</item>`;
})
.join("\n");

const feed = `<?xml version="1.0" encoding="UTF-8"?>
Expand Down
75 changes: 75 additions & 0 deletions src/components/label.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
interface LabelProps {
label: string;
variant?: "default" | "compact";
index?: number;
}

export function Label({ label, variant = "default", index = 0 }: LabelProps) {
// Book spine dimensions - compact for list, standard for individual posts
const sizeClasses =
variant === "compact"
? "text-xs px-3 py-1.5"
: "text-sm px-4 py-2";

// Slight variation in book "thickness" based on label length and index
const thickness = variant === "compact" ? "h-7" : "h-9";

// Create subtle color variations for different "books"
const bookColors = [
"bg-(--color-surface)",
"bg-[#faf8f4]",
"bg-[#f9f6f0]",
];
const bgColor = bookColors[index % bookColors.length];

return (
<span
className={`
${sizeClasses} ${thickness} ${bgColor}
relative inline-flex items-center justify-center
text-(--color-text-secondary) font-medium
border-l-[3px] border-r-[1px] border-y border-(--color-border)
transition-all duration-300
hover:text-(--color-accent) hover:border-l-(--color-accent)
hover:translate-y-[-2px] hover:shadow-md
group
`}
style={{
borderLeftColor: "var(--color-border)",
boxShadow: "2px 2px 4px rgba(0, 0, 0, 0.04), inset -1px 0 2px rgba(0, 0, 0, 0.02)",
}}
>
{/* Book spine edge highlight */}
<span
className="absolute left-0 top-0 bottom-0 w-[2px] bg-gradient-to-b from-transparent via-white/30 to-transparent opacity-40"
aria-hidden="true"
/>
{/* Label text */}
<span className="relative z-10">{label}</span>
{/* Bottom shadow for depth */}
<span
className="absolute bottom-[-1px] left-0 right-0 h-[1px] bg-gradient-to-r from-transparent via-black/5 to-transparent"
aria-hidden="true"
/>
</span>
);
}

interface LabelsProps {
labels: string[];
variant?: "default" | "compact";
}

export function Labels({ labels, variant = "default" }: LabelsProps) {
if (!labels || labels.length === 0) return null;

const gapClass = variant === "compact" ? "gap-2" : "gap-2.5";

return (
<div className={`flex flex-wrap items-end ${gapClass}`}>
{labels.map((label, index) => (
<Label key={label} label={label} variant={variant} index={index} />
))}
</div>
);
}
6 changes: 5 additions & 1 deletion src/components/posts.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { formatDate, getBlogPosts } from "@/app/blog/utils";
import { Labels } from "@/components/label";
import Link from "next/link";

export function BlogPosts() {
Expand All @@ -25,9 +26,12 @@ export function BlogPosts() {
<p className="text-(--color-text-secondary) text-sm tabular-nums mb-1 transition-colors group-hover:text-(--color-accent)">
{formatDate(post.metadata.publishedAt, false)}
</p>
<p className="text-(--color-text) transition-colors">
<p className="text-(--color-text) transition-colors mb-2">
{post.metadata.title}
</p>
{post.metadata.labels && post.metadata.labels.length > 0 && (
<Labels labels={post.metadata.labels} variant="compact" />
)}
</Link>
))}
</div>
Expand Down
1 change: 1 addition & 0 deletions src/posts/26-lessons-in-26-years.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ title: "26 lessons in 26 years"

publishedAt: "2024-12-04"
summary: "a list of 26 things i've realized or learned over my 26 years of life"
labels: ["life", "philosophy", "personal-growth"]
---

i turn 26 years old today, halfway to unc status and completing half of my twenties. it's just a change in number but a big change in my life and mindset, here are 26 things i think about, wish i knew before, and i've learned along the way:
Expand Down
1 change: 1 addition & 0 deletions src/posts/dont-waste-time-on-dark-mode.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title: "don't waste your time on dark mode"
# Date format: YYYY-MM-DD
publishedAt: "2024-10-30"
summary: "focus on the 20% that will give you 80% of value"
labels: ["tech", "productivity", "philosophy"]
---

there's a saying in my native language, "for work, double work". after spending most of my code writing hours to make our user experience as great as possible, i can confirm that this saying was meant for dark mode. it's a waste of time, really.
Expand Down
1 change: 1 addition & 0 deletions src/posts/first-thought.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title: "hello world"
# Date format: YYYY-MM-DD
publishedAt: "2023-12-13"
summary: "welcome to my mind!"
labels: ["life", "personal"]
---

going to expand upon and transfer my random list of thoughts from my apple notes app onto this site ✌🏾
Expand Down
1 change: 1 addition & 0 deletions src/posts/let-your-kid-play-competitive-games.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ title: "let your kid play competitive video games"

publishedAt: "2025-03-05"
summary: "gaming is a gateway to future success"
labels: ["gaming", "mindset", "personal-growth"]
---

i used to play a lot of competitive video games as a kid. namely (and in order): cod, overwatch, cs:go, league of legends, fortnite, apex legends, valorant, and much more. i ranked pretty high despite putting meager hours into these games. looking back, gaming has taught me so much about life and has molded my personality to be who i am today. i believe that every kid should do something competitive, whether thats sports, arts, video games, or something else.
Expand Down
1 change: 1 addition & 0 deletions src/posts/ripped-shoes-mentality.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title: "the ripped shoes mentality"
# Date format: YYYY-MM-DD
publishedAt: "2025-12-12"
summary: "the feeling of being underrated, undervalued, and unknown"
labels: ["mindset", "philosophy", "personal-growth"]
---

there's a certain feeling you get when you walk into a room underrated, undervalued, and unknown.
Expand Down
1 change: 1 addition & 0 deletions src/posts/thoughts-list.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title: "a running list of some thoughts"
# Date format: YYYY-MM-DD
publishedAt: "2023-08-10"
summary: "unfiltered thoughts straight from my mind"
labels: ["philosophy", "life", "personal"]
---

recently, i've just been tweeting/posting the stuff in my brain on [twitter/x](https://x.com/adiaddxyz) but feel free to read through these other thoughts in the meantime:
Expand Down