Skip to content
Merged
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
41 changes: 24 additions & 17 deletions src/content.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,29 @@ export const seoSchemaWithoutImage = z.object({
type: z.string().optional(),
keywords: z.string().optional(),
canonicalUrl: z.string().optional(),
twitter: z.object({
creator: z.string().optional(),
}).optional(),
twitter: z
.object({
creator: z.string().optional(),
})
.optional(),
robots: z.string().optional(),
})
});

const seoSchema = (image: ImageFunction) =>
z.object({
image: image().optional(),
}).merge(seoSchemaWithoutImage);
z
.object({
image: image().optional(),
})
.merge(seoSchemaWithoutImage);

const pageCollection = defineCollection({
loader: glob({ pattern: '**/[^_]*.{md,mdx}', base: './src/content/pages' }),
schema: ({ image }) => z.object({
title: z.string(),
seo: seoSchema(image),
}),
schema: ({ image }) =>
z.object({
title: z.string(),
description: z.string().optional(),
seo: seoSchema(image),
}),
});

const linkCollection = defineCollection({
Expand Down Expand Up @@ -61,12 +67,13 @@ const talkCollection = defineCollection({

const postCollection = defineCollection({
loader: glob({ pattern: '**/[^_]*.{md,mdx}', base: './src/content/posts' }),
schema: ({ image }) => z.object({
title: z.string(),
date: z.date(),
image: image().optional(),
seo: seoSchema(image),
}),
schema: ({ image }) =>
z.object({
title: z.string(),
date: z.date(),
image: image().optional(),
seo: seoSchema(image),
}),
});

export const collections = {
Expand Down
9 changes: 9 additions & 0 deletions src/content/pages/404.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: 404 - Page not found
description: Sorry, the page you are looking for doesn't exist or has been moved.
seo:
title: 404 - Page not found
description: Sorry, the page you are looking for doesn't exist or has been moved.
type: website
robots: noindex, no follow
---
80 changes: 80 additions & 0 deletions src/pages/404.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
import { getEntry } from 'astro:content';
import BaseLayout from '@/layouts/BaseLayout.astro';
import Container from '@/components/Container.astro';

const entry = await getEntry('pages', '404');
---

<BaseLayout seo={entry?.data.seo}>
<Container
as="section"
class="min-h-[calc(100vh-12rem)] flex items-center justify-center"
>
<div class="text-center space-y-8">
<!-- 404 Number -->
<div class="space-y-4">
<h1 class="text-6xl md:text-8xl font-bold text-headings opacity-20">
404
</h1>
<div class="space-y-2">
<h2 class="text-2xl md:text-3xl font-medium text-headings">
{entry?.data.title}
</h2>
<p class="text-muted-foreground max-w-md mx-auto">
{entry?.data.description}
</p>
</div>
</div>

<!-- Action Buttons -->
<div
class="flex flex-col sm:flex-row gap-4 justify-center items-center pt-4"
>
<a
href="/"
class="group inline-flex items-center justify-center px-6 py-3 bg-headings text-background font-medium rounded-full transition-all duration-200 hover:bg-headings/90 hover:scale-105 focus:outline-none focus:ring-2 focus:ring-headings/50 focus:ring-offset-2 focus:ring-offset-background min-w-[140px]"
>
<svg
class="w-4 h-4 mr-2 transition-transform group-hover:-translate-x-1"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>
</svg>
Go Home
</a>

<a
href="/writing"
class="group inline-flex items-center justify-center px-6 py-3 border border-border text-headings font-medium rounded-full transition-all duration-200 hover:bg-muted-foreground/10 hover:border-headings/30 focus:outline-none focus:ring-2 focus:ring-headings/50 focus:ring-offset-2 focus:ring-offset-background min-w-[140px]"
>
Browse Writing
<svg
class="w-4 h-4 ml-2 transition-transform group-hover:translate-x-1"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M14 5l7 7m0 0l-7 7m7-7H3"></path>
</svg>
</a>
</div>

<!-- Additional Help Text -->
<p class="text-sm text-muted-foreground/70 pt-8">
If you believe this is an error, please check the URL or try refreshing
the page.
</p>
</div>
</Container>
</BaseLayout>
15 changes: 10 additions & 5 deletions src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import Talk from '@/components/ui/Talk.astro';
import { sortJobsByDate } from '@/lib/utils';

const entry = await getEntry('pages', 'homepage');

if (!entry) {
throw new Error('Homepage entry not found');
}

const { Content } = await render(entry);

const links = await getCollection('links');
Expand All @@ -18,11 +23,11 @@ const talks = await getCollection('talks');
---

<BaseLayout seo={entry.data.seo}>
<Container as='section' class='py-6'>
<Container as="section" class="py-6">
<Author {...DEFAULT_CONFIGURATION.author} />
</Container>

<Container as='section' class='py-6'>
<Container as="section" class="py-6">
<div class="flex flex-col gap-6">
<div class="flex items-center">
<span class="text-headings">About</span>
Expand All @@ -34,7 +39,7 @@ const talks = await getCollection('talks');
</Container>
{
links.length > 0 && (
<Container as='section' class='py-8'>
<Container as="section" class="py-8">
<div class="flex flex-col gap-5">
<span class="text-headings">Contact</span>
<ul class="flex flex-col gap-3">
Expand Down Expand Up @@ -62,7 +67,7 @@ const talks = await getCollection('talks');
}
{
sortedJobs.length > 0 && (
<Container as='section' class='py-6'>
<Container as="section" class="py-6">
<div class="flex flex-col gap-5">
<span class="text-headings">Work Experience</span>
<ul class="flex flex-col gap-8">
Expand All @@ -76,7 +81,7 @@ const talks = await getCollection('talks');
}
{
talks.length > 0 && (
<Container as='section' class='py-6'>
<Container as="section" class="py-6">
<div class="flex flex-col gap-5">
<span class="text-headings">Speaking</span>
<ul class="flex flex-col gap-8">
Expand Down