mirror of
https://github.com/prdlk/prdlk.git
synced 2026-11-04 05:57:49 +00:00
feat(pages): add new site pages, routes, and OG image generation
This commit is contained in:
1 parent
8a191f65cc
commit
01eac43ecf
19 files changed
+1206
No files matched your search
@@ -0,0 +1,121 @@
|
||||
---
|
||||
import { render } from "astro:content";
|
||||
import type { GetStaticPaths, InferGetStaticPropsType } from "astro";
|
||||
import { Icon } from "astro-icon/components";
|
||||
import PostPreview from "@/components/blog/PostPreview.astro";
|
||||
import TagList from "@/components/TagList.astro";
|
||||
import { getAllExperience, getContentForExperience } from "@/data/experience";
|
||||
import PageLayout from "@/layouts/Base.astro";
|
||||
import { breadcrumbList } from "@/utils/seo";
|
||||
|
||||
export const getStaticPaths = (async () => {
|
||||
const experiences = await getAllExperience();
|
||||
return Promise.all(
|
||||
experiences.map(async (exp) => ({
|
||||
params: { slug: exp.id },
|
||||
props: { exp, content: await getContentForExperience(exp.id) },
|
||||
})),
|
||||
);
|
||||
}) satisfies GetStaticPaths;
|
||||
|
||||
type Props = InferGetStaticPropsType<typeof getStaticPaths>;
|
||||
|
||||
const { exp, content } = Astro.props as Props;
|
||||
const { Content } = await render(exp);
|
||||
const { startDate, endDate, organization, role, location, url, tags } = exp.data;
|
||||
const range = `${startDate.getFullYear()} – ${endDate ? endDate.getFullYear() : "Present"}`;
|
||||
|
||||
const meta = {
|
||||
description: exp.data.description ?? `${role ?? ""} at ${organization}`.trim(),
|
||||
keywords: tags,
|
||||
ogImage: `/og-image/experience/${exp.id}.png`,
|
||||
schema: breadcrumbList([
|
||||
{ name: "Home", path: "/" },
|
||||
{ name: "Experience", path: "/experience/" },
|
||||
{ name: exp.data.title, path: `/experience/${exp.id}/` },
|
||||
]),
|
||||
title: exp.data.title,
|
||||
};
|
||||
---
|
||||
|
||||
<PageLayout meta={meta}>
|
||||
<nav class="mb-8" aria-label="Breadcrumbs">
|
||||
<ul class="flex items-center">
|
||||
<li class="flex items-center">
|
||||
<a class="text-accent" href="/experience/">Experience</a>
|
||||
<Icon aria-hidden="true" name="lucide:chevron-right" class="mx-1.5" />
|
||||
</li>
|
||||
<li aria-current="page">{exp.data.title}</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<h1 class="title">{role ? `${role}, ${organization}` : organization}</h1>
|
||||
<p class="text-muted mt-1">
|
||||
{range}{location && ` · ${location}`}
|
||||
{
|
||||
url && (
|
||||
<>
|
||||
{" · "}
|
||||
<a class="cactus-link" href={url} rel="noopener noreferrer" target="_blank">
|
||||
Website →
|
||||
</a>
|
||||
</>
|
||||
)
|
||||
}
|
||||
</p>
|
||||
|
||||
<div class="prose prose-sm prose-cactus mt-6 mb-12 max-w-none">
|
||||
<Content />
|
||||
</div>
|
||||
|
||||
{
|
||||
content.projects.length > 0 && (
|
||||
<section class="mb-12">
|
||||
<h2 class="title mb-4 text-xl">Projects</h2>
|
||||
<ul class="space-y-3">
|
||||
{content.projects.map((p) => (
|
||||
<li>
|
||||
<a class="cactus-link" href={`/projects/${p.id}/`}>
|
||||
{p.data.title}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
content.writing.length > 0 && (
|
||||
<section class="mb-12">
|
||||
<h2 class="title mb-4 text-xl">Writing</h2>
|
||||
<ul class="space-y-4">
|
||||
{content.writing.map((p) => (
|
||||
<li class="grid gap-1 sm:grid-cols-[auto_1fr]">
|
||||
<PostPreview as="h3" post={p} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
content.speaking.length > 0 && (
|
||||
<section class="mb-12">
|
||||
<h2 class="title mb-4 text-xl">Speaking</h2>
|
||||
<ul class="space-y-3">
|
||||
{content.speaking.map((t) => (
|
||||
<li>
|
||||
<a class="cactus-link" href={`/speaking/${t.id}/`}>
|
||||
{t.data.title}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
<TagList tags={tags} class="border-global-text/10 mt-6 border-t pt-6" />
|
||||
</PageLayout>
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
import { getAllExperience } from "@/data/experience";
|
||||
import PageLayout from "@/layouts/Base.astro";
|
||||
import { breadcrumbList, collectionPageSchema } from "@/utils/seo";
|
||||
|
||||
const experiences = await getAllExperience();
|
||||
|
||||
const meta = {
|
||||
description: "Roles and organizations I've worked with",
|
||||
schema: [
|
||||
breadcrumbList([
|
||||
{ name: "Home", path: "/" },
|
||||
{ name: "Experience", path: "/experience/" },
|
||||
]),
|
||||
collectionPageSchema({
|
||||
name: "Experience",
|
||||
description: "Roles and organizations I've worked with",
|
||||
path: "/experience/",
|
||||
items: experiences.map((e) => ({
|
||||
name: e.data.role ? `${e.data.role}, ${e.data.organization}` : e.data.organization,
|
||||
path: `/experience/${e.id}/`,
|
||||
})),
|
||||
}),
|
||||
],
|
||||
title: "Experience",
|
||||
};
|
||||
|
||||
const range = (start: Date, end?: Date) =>
|
||||
`${start.getFullYear()} – ${end ? end.getFullYear() : "Present"}`;
|
||||
---
|
||||
|
||||
<PageLayout meta={meta}>
|
||||
<h1 class="title mb-12">Experience</h1>
|
||||
<ul class="space-y-10">
|
||||
{
|
||||
experiences.map((exp) => (
|
||||
<li>
|
||||
<div class="flex flex-wrap items-baseline justify-between gap-x-4">
|
||||
<h2 class="title text-lg">
|
||||
<a class="cactus-link" href={`/experience/${exp.id}/`}>
|
||||
{exp.data.role ? `${exp.data.role}, ${exp.data.organization}` : exp.data.organization}
|
||||
</a>
|
||||
</h2>
|
||||
<span class="text-muted text-sm">{range(exp.data.startDate, exp.data.endDate)}</span>
|
||||
</div>
|
||||
{exp.data.location && <p class="text-muted text-sm">{exp.data.location}</p>}
|
||||
{exp.data.description && <p class="mt-2">{exp.data.description}</p>}
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
<section class="mt-16">
|
||||
<h2 class="title text-accent mb-6 text-xl">Education</h2>
|
||||
<p>
|
||||
<strong>Virginia Commonwealth University</strong><br />
|
||||
B.S. in Applied Mathematics
|
||||
</p>
|
||||
<p class="mt-2">
|
||||
Attended 5 MLH hackathons, published 3 apps in 3 years with over 1M downloads, and wrote 3
|
||||
articles with over 120k reads. Coursework spanned linear algebra, number theory, topological
|
||||
data analysis, and vector calculus.
|
||||
</p>
|
||||
</section>
|
||||
</PageLayout>
|
||||
Reference in new issue
Block a user