mirror of
https://github.com/prdlk/website.git
synced 2026-08-02 17:31:41 +00:00
refactor(index): simplify homepage sections and add person schema
This commit is contained in:
+40
-5
@@ -2,20 +2,20 @@
|
|||||||
import { type CollectionEntry, getCollection } from "astro:content";
|
import { type CollectionEntry, getCollection } from "astro:content";
|
||||||
import PostPreview from "@/components/blog/PostPreview.astro";
|
import PostPreview from "@/components/blog/PostPreview.astro";
|
||||||
import Project from "@/components/project/Project.astro";
|
import Project from "@/components/project/Project.astro";
|
||||||
import SocialList from "@/components/SocialList.astro";
|
|
||||||
import { getAllPosts } from "@/data/post";
|
import { getAllPosts } from "@/data/post";
|
||||||
import { getAllSpeaking } from "@/data/speaking";
|
import { getAllSpeaking } from "@/data/speaking";
|
||||||
import PageLayout from "@/layouts/Base.astro";
|
import PageLayout from "@/layouts/Base.astro";
|
||||||
|
import { siteConfig, socialLinks } from "@/site.config";
|
||||||
import { collectionDateSort } from "@/utils/date";
|
import { collectionDateSort } from "@/utils/date";
|
||||||
|
|
||||||
const MAX_POSTS = 5;
|
const MAX_POSTS = 4;
|
||||||
const allPosts = await getAllPosts();
|
const allPosts = await getAllPosts();
|
||||||
const latestPosts = (allPosts.sort(collectionDateSort) as CollectionEntry<"writing">[]).slice(
|
const latestPosts = (allPosts.sort(collectionDateSort) as CollectionEntry<"writing">[]).slice(
|
||||||
0,
|
0,
|
||||||
MAX_POSTS,
|
MAX_POSTS,
|
||||||
);
|
);
|
||||||
|
|
||||||
const MAX_PROJECTS = 3;
|
const MAX_PROJECTS = 2;
|
||||||
const allProjects = await getCollection("projects");
|
const allProjects = await getCollection("projects");
|
||||||
const latestProjects = allProjects
|
const latestProjects = allProjects
|
||||||
.sort(collectionDateSort)
|
.sort(collectionDateSort)
|
||||||
@@ -23,16 +23,42 @@ const latestProjects = allProjects
|
|||||||
|
|
||||||
const MAX_TALKS = 3;
|
const MAX_TALKS = 3;
|
||||||
const latestTalks = (await getAllSpeaking()).sort(collectionDateSort).slice(0, MAX_TALKS);
|
const latestTalks = (await getAllSpeaking()).sort(collectionDateSort).slice(0, MAX_TALKS);
|
||||||
|
|
||||||
|
const meta = {
|
||||||
|
title: "Engineer & Founder",
|
||||||
|
description:
|
||||||
|
"Prad Nukala — engineer and founder building decentralized identity infrastructure. Explore my projects, experience, writing, and talks.",
|
||||||
|
};
|
||||||
|
|
||||||
|
const social = Object.fromEntries(socialLinks.map((s) => [s.friendlyName, s.link]));
|
||||||
|
|
||||||
|
// Person structured data for richer search results.
|
||||||
|
const personSchema = {
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "Person",
|
||||||
|
name: siteConfig.author,
|
||||||
|
url: siteConfig.url,
|
||||||
|
jobTitle: "Engineer & Founder",
|
||||||
|
description: meta.description,
|
||||||
|
image: new URL("/avatar.png", siteConfig.url).href,
|
||||||
|
sameAs: socialLinks.filter((s) => !s.link.startsWith("mailto:")).map((s) => s.link),
|
||||||
|
};
|
||||||
---
|
---
|
||||||
|
|
||||||
<PageLayout meta={{ title: "Home" }}>
|
<PageLayout meta={meta}>
|
||||||
|
<script type="application/ld+json" set:html={JSON.stringify(personSchema)} is:inline />
|
||||||
<section>
|
<section>
|
||||||
<h1 class="title mb-6">Prad Nukala</h1>
|
<h1 class="title mb-6">Prad Nukala</h1>
|
||||||
<p class="mb-4">
|
<p class="mb-4">
|
||||||
Engineer and founder. I build decentralized identity infrastructure and tools for developers.
|
Engineer and founder. I build decentralized identity infrastructure and tools for developers.
|
||||||
Here you'll find what I've built, where I've worked, what I write, and the talks I've given.
|
Here you'll find what I've built, where I've worked, what I write, and the talks I've given.
|
||||||
</p>
|
</p>
|
||||||
<SocialList />
|
<p>
|
||||||
|
Find me on <a class="cactus-link" href={social.GitHub} rel="noreferrer" target="_blank">Github</a>,
|
||||||
|
<a class="cactus-link" href={social.X} rel="noreferrer" target="_blank">X</a>,
|
||||||
|
<a class="cactus-link" href={social.LinkedIn} rel="noreferrer" target="_blank">LinkedIn</a>, or
|
||||||
|
<a class="cactus-link" href={social.Email}>contact me directly</a>.
|
||||||
|
</p>
|
||||||
</section>
|
</section>
|
||||||
{
|
{
|
||||||
latestProjects.length > 0 && (
|
latestProjects.length > 0 && (
|
||||||
@@ -47,6 +73,9 @@ const latestTalks = (await getAllSpeaking()).sort(collectionDateSort).slice(0, M
|
|||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
<a class="hover:text-link mt-6 inline-block" href="/projects/">
|
||||||
|
See all projects <span aria-hidden="true">→</span>
|
||||||
|
</a>
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -61,6 +90,9 @@ const latestTalks = (await getAllSpeaking()).sort(collectionDateSort).slice(0, M
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
|
<a class="hover:text-link mt-6 inline-block" href="/writing/">
|
||||||
|
See all writing <span aria-hidden="true">→</span>
|
||||||
|
</a>
|
||||||
</section>
|
</section>
|
||||||
{
|
{
|
||||||
latestTalks.length > 0 && (
|
latestTalks.length > 0 && (
|
||||||
@@ -78,6 +110,9 @@ const latestTalks = (await getAllSpeaking()).sort(collectionDateSort).slice(0, M
|
|||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
<a class="hover:text-link mt-6 inline-block" href="/speaking/">
|
||||||
|
See all talks <span aria-hidden="true">→</span>
|
||||||
|
</a>
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,24 @@ export const siteConfig: SiteConfig = {
|
|||||||
// The Stream player iframe is loaded from `${streamOrigin}/<videoId>/iframe`.
|
// The Stream player iframe is loaded from `${streamOrigin}/<videoId>/iframe`.
|
||||||
export const streamOrigin = "https://customer-CODE.cloudflarestream.com";
|
export const streamOrigin = "https://customer-CODE.cloudflarestream.com";
|
||||||
|
|
||||||
|
// Social links shown in the homepage intro and the footer's icon row.
|
||||||
|
// ! Update the handles below to your own.
|
||||||
|
export const socialLinks: {
|
||||||
|
friendlyName: string;
|
||||||
|
link: string;
|
||||||
|
name: string;
|
||||||
|
isWebmention?: boolean;
|
||||||
|
}[] = [
|
||||||
|
{ friendlyName: "GitHub", link: "https://github.com/prdlk", name: "mdi:github" },
|
||||||
|
{ friendlyName: "X", link: "https://x.com/prad_nukala", name: "mdi:twitter" },
|
||||||
|
{
|
||||||
|
friendlyName: "LinkedIn",
|
||||||
|
link: "https://www.linkedin.com/in/prad-nukala/",
|
||||||
|
name: "mdi:linkedin",
|
||||||
|
},
|
||||||
|
{ friendlyName: "Email", link: "mailto:prad@sonr.io", name: "mdi:email-outline" },
|
||||||
|
];
|
||||||
|
|
||||||
// Used to generate links in both the Header & Footer.
|
// Used to generate links in both the Header & Footer.
|
||||||
export const menuLinks: { path: string; title: string }[] = [
|
export const menuLinks: { path: string; title: string }[] = [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user