diff --git a/components/PostCard.tsx b/components/PostCard.tsx new file mode 100644 index 0000000..cad316c --- /dev/null +++ b/components/PostCard.tsx @@ -0,0 +1,37 @@ +import { LuArrowRight, LuClock } from "@preact-icons/lu"; +import { Post } from "../lib/posts.ts"; + +export default function PostCard(props: { post: Post }) { + const { post } = props; + return ( +
+
+

+ {post.title} +

+ +

{post.blurb}

+ +
+ + + {post.publishedAt!.toLocaleDateString("en-us", { + month: "long", + day: "numeric", + year: "numeric", + })} + +
+ +
+ + + +
+
+
+ ); +} diff --git a/components/TechLinks.tsx b/components/TechLinks.tsx index 514df1d..8802ba3 100644 --- a/components/TechLinks.tsx +++ b/components/TechLinks.tsx @@ -1,13 +1,23 @@ -import { LuMail } from "@preact-icons/lu"; -import { SiBluesky, SiForgejo, SiRss } from "@preact-icons/si"; +import { + SiDeno, + SiDocker, + SiGo, + SiPostgresql, + SiReact, + SiRedis, + SiTypescript, +} from "@preact-icons/si"; export default function TechLinks() { return (
- - - - + + + + + + +
); } diff --git a/deno.json b/deno.json index f866593..03f901a 100644 --- a/deno.json +++ b/deno.json @@ -23,9 +23,13 @@ ], "imports": { "$fresh/": "https://deno.land/x/fresh@1.7.3/", + "@deno/gfm": "jsr:@deno/gfm@^0.11.0", "@pakornv/fresh-plugin-tailwindcss": "jsr:@pakornv/fresh-plugin-tailwindcss@^1.0.2", "@preact-icons/lu": "jsr:@preact-icons/lu@^1.0.13", "@preact-icons/si": "jsr:@preact-icons/si@^1.0.13", + "@std/front-matter": "jsr:@std/front-matter@^1.0.9", + "@std/path": "jsr:@std/path@^1.0.9", + "@tailwindcss/typography": "npm:@tailwindcss/typography@^0.5.16", "daisyui": "npm:daisyui@^5.0.27", "preact": "npm:preact@10.22.1", "preact/jsx-runtime": "npm:preact@10.22.1/jsx-runtime", diff --git a/fresh.gen.ts b/fresh.gen.ts index 1fa99b1..4e56c15 100644 --- a/fresh.gen.ts +++ b/fresh.gen.ts @@ -7,6 +7,7 @@ import * as $_app from "./routes/_app.tsx"; import * as $_layout from "./routes/_layout.tsx"; import * as $api_joke from "./routes/api/joke.ts"; import * as $index from "./routes/index.tsx"; +import * as $post_slug_ from "./routes/post/[slug].tsx"; import * as $posts from "./routes/posts.tsx"; import * as $projects from "./routes/projects.tsx"; @@ -19,6 +20,7 @@ const manifest = { "./routes/_layout.tsx": $_layout, "./routes/api/joke.ts": $api_joke, "./routes/index.tsx": $index, + "./routes/post/[slug].tsx": $post_slug_, "./routes/posts.tsx": $posts, "./routes/projects.tsx": $projects, }, diff --git a/lib/posts.ts b/lib/posts.ts new file mode 100644 index 0000000..9b8425c --- /dev/null +++ b/lib/posts.ts @@ -0,0 +1,47 @@ +import { extractYaml } from "@std/front-matter"; +import { join } from "@std/path"; + +const POSTS_DIR = "./posts"; + +// This is what gets parsed from the post front matter +interface FrontMatter { + title: string; + published_at: string; + blurb: string; +} + +// This is what gets used for rendering +export interface Post { + slug: string; + title: string; + publishedAt: Date | null; + blurb: string; + content: string; +} + +export async function getPost(slug: string): Promise { + const text = await Deno.readTextFile(join(POSTS_DIR, `${slug}.md`)); + const { attrs, body } = extractYaml(text); + const post = { + slug, + title: attrs.title, + publishedAt: attrs.published_at ? new Date(attrs.published_at) : null, + blurb: attrs.blurb, + content: body, + }; + return post; +} + +export async function getPosts(): Promise { + const files = Deno.readDir(POSTS_DIR); + const promises = []; + for await (const file of files) { + if (file.name.startsWith(".")) continue; + const slug = file.name.replace(".md", ""); + promises.push(getPost(slug)); + } + const posts = (await Promise.all(promises) as Post[]) + .filter((post) => post.publishedAt instanceof Date); + posts.sort((a, b) => b.publishedAt!.getTime() - a.publishedAt!.getTime()); + return posts; +} diff --git a/posts/favourite_tools_list.md b/posts/favourite_tools_list.md new file mode 100644 index 0000000..3e3da78 --- /dev/null +++ b/posts/favourite_tools_list.md @@ -0,0 +1,27 @@ +--- +title: Current List of Favourite Tools +published_at: 2025-01-28T15:00:00.000Z +--- + +I change what I use _constantly_ in order to find something that feels just +right. I wanted to share them here and update them here so when someone asks, I +can just point them to this article. + +1. Sublime Text - Currently my favourite text editor. Fast, simple, and + extensible. Just a joy to use! +2. Sublime Merge - Honestly one of the fastest and best looking git GUIs around! + Awesome for visualizing changes when you have larger code changes. +3. Ghostty - A Zig based terminal emulator by one of the founders of Hashicorp. + Runs great on MacOS and Linux. No windows for those who are into that. +4. OrbStack - A faster alternative to Docker Desktop that also runs VMs! +5. Bitwarden - An open-source password manager. Easy to self host with + Vaultwarden and with the recent updates, it has SSH Agent support! +6. iA Writer - A minimalist Markdown editor. For MacOS and Windows only, but + really the MacOS version is the most mature. Awesome for focus. +7. Dataflare - A simple but powerful cross-platform database client. Supports + most common databases, including LibSQL which is rare! +8. Bruno - A simple and powerful API client, similar to Postman. An critical + tool to debug API endpoints. + +I hope you found this helpful! This will be periodically updated to avoid +outdated recommendations. diff --git a/posts/welcome.md b/posts/welcome.md new file mode 100644 index 0000000..9a80836 --- /dev/null +++ b/posts/welcome.md @@ -0,0 +1,10 @@ +--- +title: Welcome! +published_at: 2024-10-20T15:00:00.000Z +--- + +Welcome to my site! This is a place for me to share my thoughts and updates on +my projects. I hope you find something interesting here. + +Feel free to reach out if you have any questions or comments. I'd love to hear +from you! I can be reached by email at [me@atri.dad](mailto:me@atri.dad). diff --git a/routes/_layout.tsx b/routes/_layout.tsx index 3682680..480b359 100644 --- a/routes/_layout.tsx +++ b/routes/_layout.tsx @@ -1,6 +1,7 @@ // routes/_layout.tsx import { PageProps } from "$fresh/server.ts"; import { Head } from "$fresh/runtime.ts"; +import { LuBook, LuBriefcase, LuHouse } from "@preact-icons/lu"; export default function Layout({ Component, url }: PageProps) { const currentPath = url.pathname; @@ -11,32 +12,19 @@ export default function Layout({ Component, url }: PageProps) { - Fresh App + Atridad Lahiji -
+
-