From ed3a3306e346830223a954ffc9da774194949414 Mon Sep 17 00:00:00 2001 From: Jon Pither Date: Thu, 7 May 2026 10:49:21 +0100 Subject: [PATCH 1/2] xt26: render speaker headshots inline in agenda Each agenda subtitle line is parsed for the speaker name and matched against speakers.json. Where there's a hit, a small circular avatar renders next to the line, matching the juxt-bordered style of the speaker grid above. Lines without a speaker entry (Nik Tkachev, Payal Jain, panel TBA placeholders, plain non-speaker subtitles) fall through gracefully - placeholder spacing keeps multi-speaker rows aligned. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/components/XT26Agenda.astro | 41 +++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/src/components/XT26Agenda.astro b/src/components/XT26Agenda.astro index 61d7aac50..560fdb4a3 100644 --- a/src/components/XT26Agenda.astro +++ b/src/components/XT26Agenda.astro @@ -1,4 +1,11 @@ --- +import speakers from '../data/xt26/speakers.json' +import AssetImage from '@components/AssetImage.astro' + +const speakerByName = Object.fromEntries( + speakers.map((s) => [s.name, s]) +) + const agenda = [ { time: '08:30', @@ -104,10 +111,23 @@ const agenda = [ isSpecialEvent: true } ] + +const resolveLines = (subTitle) => + (subTitle == null + ? [] + : Array.isArray(subTitle) + ? subTitle + : [subTitle] + ).map((line) => { + const name = line.split('|')[0].trim() + return { line, speaker: speakerByName[name] } + }) --- { agenda.map(({ time, title, subTitle, isSpecialEvent }, index) => { + const lines = resolveLines(subTitle) + const hasAnySpeaker = lines.some((l) => l.speaker) const nextItem = index < agenda.length - 1 ? agenda[index + 1] : null const isConsecutiveSpecialEvent = isSpecialEvent && nextItem?.isSpecialEvent @@ -125,10 +145,23 @@ const agenda = [

{title}

- {subTitle && - (Array.isArray(subTitle) ? subTitle : [subTitle]).map((s) => ( -

{s}

- ))} + {lines.map(({ line, speaker }) => ( +
+ {hasAnySpeaker && + (speaker?.image ? ( +
+ +
+ ) : ( +
+ ))} +

{line}

+
+ ))}
From 5513d42dbd12939e72d2272d33c571045e3e5c4b Mon Sep 17 00:00:00 2001 From: Jon Pither Date: Thu, 7 May 2026 10:57:28 +0100 Subject: [PATCH 2/2] xt26: fix AssetImage import path The AssetImage component lives under @components/team/, not directly under @components/. Tested locally with yarn build. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/components/XT26Agenda.astro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/XT26Agenda.astro b/src/components/XT26Agenda.astro index 560fdb4a3..2197bccaf 100644 --- a/src/components/XT26Agenda.astro +++ b/src/components/XT26Agenda.astro @@ -1,6 +1,6 @@ --- import speakers from '../data/xt26/speakers.json' -import AssetImage from '@components/AssetImage.astro' +import AssetImage from '@components/team/AssetImage.astro' const speakerByName = Object.fromEntries( speakers.map((s) => [s.name, s])