All checks were successful
Docker Deploy / build-and-push (push) Successful in 3m48s
85 lines
3.9 KiB
Plaintext
85 lines
3.9 KiB
Plaintext
---
|
|
import Layout from "../layouts/Layout.astro";
|
|
import Icon from "../components/Icon.astro";
|
|
import { config } from "../config";
|
|
|
|
// Sort talks by date, newest first
|
|
const sortedTalks = [...config.talks].sort((a, b) => {
|
|
if (!a.date || !b.date) return 0;
|
|
return new Date(b.date).valueOf() - new Date(a.date).valueOf();
|
|
});
|
|
|
|
function formatDate(dateStr: string): string {
|
|
return new Date(dateStr).toLocaleDateString("en-us", {
|
|
month: "short",
|
|
day: "numeric",
|
|
year: "numeric",
|
|
});
|
|
}
|
|
---
|
|
|
|
<Layout
|
|
title={config.siteConfig.pageOpenGraph.talks.title}
|
|
description={config.siteConfig.pageOpenGraph.talks.description}
|
|
ogImage={config.siteConfig.pageOpenGraph.talks.image}
|
|
ogType={config.siteConfig.pageOpenGraph.talks.type}
|
|
>
|
|
<div class="w-full max-w-3xl mx-auto p-4 sm:p-8">
|
|
<h1
|
|
class="text-3xl sm:text-4xl font-bold text-primary mb-6 sm:mb-8 text-center"
|
|
>
|
|
Talks
|
|
</h1>
|
|
|
|
{
|
|
sortedTalks.length === 0 ? (
|
|
<p class="text-center text-gray-500 mt-12">
|
|
No talks available yet. Check back soon!
|
|
</p>
|
|
) : (
|
|
<ul class="flex flex-col bg-base-100 rounded-box shadow-md border border-base-content/20 divide-y divide-base-content/20">
|
|
{sortedTalks.map((talk) => {
|
|
const talkDate = talk.date ? new Date(talk.date) : null;
|
|
return (
|
|
<li class="flex items-center hover:bg-base-200/50 transition-colors p-4 group relative rounded-none first:rounded-t-box last:rounded-b-box">
|
|
<a
|
|
href={talk.link}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
class="absolute inset-0 z-0"
|
|
aria-label={`View ${talk.name}`}
|
|
></a>
|
|
|
|
<div class="w-24 sm:w-32 flex-none opacity-80 flex flex-col justify-center text-right pr-4 border-r border-base-content/20 z-10 pointer-events-none">
|
|
{talkDate ? (
|
|
<>
|
|
<span class="font-mono text-sm sm:text-base font-bold">
|
|
{talkDate.toLocaleDateString("en-us", { month: "short", day: "numeric" })}
|
|
</span>
|
|
<span class="text-xs opacity-70">
|
|
{talkDate.getFullYear()}
|
|
</span>
|
|
</>
|
|
) : (
|
|
<span class="text-xs opacity-50 italic">Undated</span>
|
|
)}
|
|
</div>
|
|
|
|
<div class="flex-grow flex flex-col gap-1 justify-center pl-4 z-10 pointer-events-none">
|
|
<h2 class="font-bold text-lg sm:text-xl text-primary group-hover:text-accent transition-colors flex items-center gap-2">
|
|
{talk.name}
|
|
<Icon name="open-in-new" class="w-4 h-4 opacity-50 group-hover:opacity-100 transition-opacity" />
|
|
</h2>
|
|
<p class="text-sm opacity-80 line-clamp-2 leading-relaxed">
|
|
{talk.description}
|
|
</p>
|
|
</div>
|
|
</li>
|
|
);
|
|
})}
|
|
</ul>
|
|
)
|
|
}
|
|
</div>
|
|
</Layout>
|