One companion study guide per series; v2.9.8
Publish Container / build (push) Successful in 21m12s

- Second series gets its own guide (Resources page card, download page, admin fields)
- When a series ends (scheduled or manual) its guide moves onto its Finished Book, which shows a guide button; the main series' guide is cleared unless the launch supplies a new one
- Lane B launch schedule can supply the incoming series' guide
- Download lookup covers second-series and finished-book guides; guide URLs are sanitized on save and on use

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 5.5 committed 2026-10-08 16:00:52 -04:00
1 parent 39691aedb3
commit e2150e1cd7
7 files changed
+244 -4

No files matched your search

+56 -1
View File
@@ -303,6 +303,33 @@ function resolveDownloadPageResource(content: SiteContent, pageId: string | unde
}
}
// Companion guide of the second series, or one kept on a finished book
const guideSource = pageId === 'second-guide'
? { guide: content.secondSeries?.guide, imageUrl: content.secondSeries?.imageUrl, resourceId: 'guide:second' }
: pageId.startsWith('book-guide--')
? (() => {
const book = (content.finishedBooks ?? []).find(item => item.id === pageId.slice('book-guide--'.length))
return { guide: book?.guide, imageUrl: book?.imageUrl, resourceId: `guide:book:${book?.id ?? ''}` }
})()
: null
if (guideSource) {
const guide = guideSource.guide
if (!guide?.title) return null
return {
id: pageId,
label: guide.title,
imageUrl: guideSource.imageUrl,
summary: guide.description || 'Complete the short form below and your download will start right away.',
tags: [],
buttonText: `Download ${guide.title}`,
resourceId: guideSource.resourceId,
amazonUrl: guide.amazonUrl,
amazonLabel: guide.amazonLabel,
appleBooksUrl: guide.appleBooksUrl,
appleBooksLabel: guide.appleBooksLabel,
}
}
if (pageId.startsWith('custom--')) {
const customId = pageId.slice('custom--'.length)
const resource = (content.customLinks ?? []).find(link => link.id === customId && link.placement === 'resources')
@@ -824,7 +851,7 @@ function DownloadLibrarySection({ content }: { content: SiteContent }) {
return !activeTag || (r.tags ?? []).includes(activeTag)
})
if (!hasPrimaryGuide && resources.length === 0) return null
if (!hasPrimaryGuide && !content.secondSeries?.guide?.title && resources.length === 0) return null
return (
<section className="section-resources section-download-library" aria-label="Download library">
@@ -852,6 +879,29 @@ function DownloadLibrarySection({ content }: { content: SiteContent }) {
</Link>
)}
{content.secondSeries?.guide?.title && (
<Link to="/downloads/second-guide" className="resource-download-card resource-download-card--link resource-download-card--featured">
<div className="resource-download-header">
{content.secondSeries.imageUrl && (
<img
src={content.secondSeries.imageUrl}
alt={content.secondSeries.title}
className="resource-link-image resource-link-image--featured"
loading="lazy"
/>
)}
<div className="resource-download-meta">
<div className="featured-badge">Featured</div>
<span className="resource-link-label">{content.secondSeries.guide.title}</span>
{content.secondSeries.guide.description && (
<p className="resource-link-description">{content.secondSeries.guide.description}</p>
)}
<span className="resource-link-action">Download free guide →</span>
</div>
</div>
</Link>
)}
{resources.length > 0 && (
<>
{allTags.length > 0 && (
@@ -1768,6 +1818,11 @@ function FinishedSeriesPage({ content }: { content: SiteContent }) {
📖 Study This Book
</Link>
)}
{book.guide?.title && (
<Link to={`/downloads/book-guide--${book.id}`} className="finished-series-btn-download">
📄 {book.guide.title}
</Link>
)}
</div>
{book.downloadQrUrl && book.downloadUrl && (
<div className="finished-series-qr">