refactor(ui): rename blog post and note components for consistency

This commit is contained in:
Prad Nukala
2026-06-30 12:03:16 -04:00
parent 7f6445c91a
commit 2760ea960e
8 changed files with 111 additions and 80 deletions
+2 -2
View File
@@ -70,8 +70,8 @@ const socialImageURL = new URL(ogImage ? ogImage : "/social-card.png", Astro.url
<link href="/sitemap-index.xml" rel="sitemap" />
{/* RSS auto-discovery */}
<link href="/rss.xml" title="Blog" rel="alternate" type="application/rss+xml" />
<link href="/notes/rss.xml" title="Notes" rel="alternate" type="application/rss+xml" />
<link href="/rss.xml" title="Writing" rel="alternate" type="application/rss+xml" />
<link href="/projects/rss.xml" title="Projects" rel="alternate" type="application/rss+xml" />
{/* Webmentions */}
{
+25
View File
@@ -0,0 +1,25 @@
---
import { getEntries } from "astro:content";
import type { CollectionEntry } from "astro:content";
interface Props {
experiences: CollectionEntry<"projects" | "writing" | "speaking">["data"]["experiences"];
}
const { experiences } = Astro.props;
const entries = experiences.length ? await getEntries(experiences) : [];
---
{
entries.length > 0 && (
<ul class="flex flex-wrap gap-2">
{entries.map((exp) => (
<li>
<a class="cactus-link inline-block" href={`/experience/${exp.id}/`}>
{exp.data.title}
</a>
</li>
))}
</ul>
)
}
+20
View File
@@ -0,0 +1,20 @@
---
import { streamOrigin } from "@/site.config";
interface Props {
videoId: string;
title?: string;
}
const { videoId, title } = Astro.props;
---
<div class="aspect-video overflow-hidden rounded-md">
<iframe
class="h-full w-full border-0"
src={`${streamOrigin}/${videoId}/iframe`}
title={title}
loading="lazy"
allow="accelerometer; gyroscope; autoplay; encrypted-media; picture-in-picture;"
allowfullscreen></iframe>
</div>
+5 -29
View File
@@ -1,10 +1,11 @@
---
import { Image } from "astro:assets";
import type { CollectionEntry } from "astro:content";
import ExperienceTags from "@/components/ExperienceTags.astro";
import FormattedDate from "@/components/FormattedDate.astro";
interface Props {
content: CollectionEntry<"post">;
content: CollectionEntry<"writing">;
readingTime: string;
}
@@ -51,34 +52,9 @@ const dateTimeOptions: Intl.DateTimeFormatOptions = {
}
</div>
{
!!data.tags?.length && (
<div class="mt-2">
<svg
aria-hidden="true"
class="inline-block h-6 w-6"
fill="none"
focusable="false"
stroke="var(--color-muted)"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M0 0h24v24H0z" fill="none" stroke="none" />
<path d="M7.859 6h-2.834a2.025 2.025 0 0 0 -2.025 2.025v2.834c0 .537 .213 1.052 .593 1.432l6.116 6.116a2.025 2.025 0 0 0 2.864 0l2.834 -2.834a2.025 2.025 0 0 0 0 -2.864l-6.117 -6.116a2.025 2.025 0 0 0 -1.431 -.593z" />
<path d="M17.573 18.407l2.834 -2.834a2.025 2.025 0 0 0 0 -2.864l-7.117 -7.116" />
<path d="M6 9h-.01" />
</svg>
{data.tags.map((tag, i) => (
<>
{/* prettier-ignore */}
<span class="contents">
<a class="cactus-link inline-block before:content-['#']" data-pagefind-filter={`tag:${tag}`} href={`/tags/${tag}/`}><span class="sr-only">View more blogs with the tag&nbsp;</span>{tag}
</a>{i < data.tags.length - 1 && ", "}
</span>
</>
))}
!!data.experiences?.length && (
<div class="mt-3">
<ExperienceTags experiences={data.experiences} />
</div>
)
}
+2 -2
View File
@@ -4,7 +4,7 @@ import type { HTMLTag, Polymorphic } from "astro/types";
import FormattedDate from "@/components/FormattedDate.astro";
type Props<Tag extends HTMLTag> = Polymorphic<{ as: Tag }> & {
post: CollectionEntry<"post">;
post: CollectionEntry<"writing">;
withDesc?: boolean;
};
@@ -14,7 +14,7 @@ const { as: Tag = "div", post, withDesc = false } = Astro.props;
<FormattedDate class="text-muted min-w-30 font-semibold" date={post.data.publishDate} />
<Tag>
{post.data.draft && <span class="text-red-500">(Draft) </span>}
<a class="cactus-link" href={`/posts/${post.id}/`}>
<a class="cactus-link" href={`/writing/${post.id}/`}>
{post.data.title}
</a>
</Tag>
-46
View File
@@ -1,46 +0,0 @@
---
import { type CollectionEntry, render } from "astro:content";
import type { HTMLTag, Polymorphic } from "astro/types";
import FormattedDate from "@/components/FormattedDate.astro";
type Props<Tag extends HTMLTag> = Polymorphic<{ as: Tag }> & {
note: CollectionEntry<"note">;
isPreview?: boolean | undefined;
};
const { as: Tag = "div", note, isPreview = false } = Astro.props;
const { Content } = await render(note);
---
<article
class:list={[isPreview && "bg-global-text/5 inline-grid rounded-md px-4 py-3"]}
data-pagefind-body={isPreview ? false : true}
>
<Tag class="title" class:list={{ "text-base": isPreview }}>
{
isPreview ? (
<a class="cactus-link" href={`/notes/${note.id}/`}>
{note.data.title}
</a>
) : (
<>{note.data.title}</>
)
}
</Tag>
<FormattedDate
dateTimeOptions={{
hour: "2-digit",
minute: "2-digit",
year: "2-digit",
month: "2-digit",
day: "2-digit",
}}
date={note.data.publishDate}
/>
<div
class="prose prose-sm prose-cactus mt-4 max-w-none [&>p:last-of-type]:mb-0"
class:list={{ "line-clamp-6": isPreview }}
>
<Content />
</div>
</article>
+56
View File
@@ -0,0 +1,56 @@
---
import { type CollectionEntry, render } from "astro:content";
import type { HTMLTag, Polymorphic } from "astro/types";
import ExperienceTags from "@/components/ExperienceTags.astro";
import FormattedDate from "@/components/FormattedDate.astro";
type Props<Tag extends HTMLTag> = Polymorphic<{ as: Tag }> & {
project: CollectionEntry<"projects">;
isPreview?: boolean | undefined;
};
const { as: Tag = "div", project, isPreview = false } = Astro.props;
const { Content } = await render(project);
const { title, publishDate, link, repo, experiences } = project.data;
---
<article
class:list={[isPreview && "bg-global-text/5 inline-grid rounded-md px-4 py-3"]}
data-pagefind-body={isPreview ? false : true}
>
<Tag class="title" class:list={{ "text-base": isPreview }}>
{
isPreview ? (
<a class="cactus-link" href={`/projects/${project.id}/`}>
{title}
</a>
) : (
<>{title}</>
)
}
</Tag>
<FormattedDate date={publishDate} />
{
!isPreview && (link || repo) && (
<div class="mt-2 flex flex-wrap gap-x-4 gap-y-1">
{link && (
<a class="cactus-link" href={link} rel="noopener noreferrer" target="_blank">
Visit →
</a>
)}
{repo && (
<a class="cactus-link" href={repo} rel="noopener noreferrer" target="_blank">
Source →
</a>
)}
</div>
)
}
<div
class="prose prose-sm prose-cactus mt-4 max-w-none [&>p:last-of-type]:mb-0"
class:list={{ "line-clamp-6": isPreview }}
>
<Content />
</div>
{!isPreview && experiences.length > 0 && <div class="mt-6"><ExperienceTags experiences={experiences} /></div>}
</article>
+1 -1
View File
@@ -8,7 +8,7 @@ import WebMentions from "@/components/blog/webmentions/index.astro";
import BaseLayout from "./Base.astro";
interface Props {
post: CollectionEntry<"post">;
post: CollectionEntry<"writing">;
}
const { post } = Astro.props;