Two concurrent series lanes, Complete studies, self-paced finished books; v2.9.0
Publish Container / build (push) Successful in 17m50s
Publish Container / build (push) Successful in 17m50s
- Study status 'complete' (manual or auto when all lessons released); stays enrollable and self-paced (no sequential lock, Resume button, Finished Studies hub section) - Studies get lane (A/B) and expected start date; planned studies show "Starts <date>"; hub shows next lesson date instead of hardcoded pace - Second concurrent series (homepage card, admin panel) with its own scheduled launch; transitions are per lane and flip the ending study to Complete and the incoming study to Active - Finished books link to their study: "Study This Book" on playlist page, audio-only link from hub (playlist stays public, no account) - Admin: bulk release scheduler (every N days), same-day collision warning, linked-study selects - Weekly digest no longer dumps a finished study's backlog on late enrollees - CI: build and tag the container as :beta on pushes to the beta branch Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2d8e4be5ea
commit
ddcaec0ddf
12 files changed
+628
-105
No files matched your search
+58
-29
@@ -14,7 +14,13 @@ export interface StudyProgram {
|
||||
showOnHomepage?: boolean
|
||||
showNewTag?: boolean
|
||||
newTagLabel?: string
|
||||
status: 'active' | 'planned'
|
||||
// 'complete' = finished and self-paced (still open for enrollment). A study whose lessons
|
||||
// have all been released is treated as complete even if left as 'active'.
|
||||
status: 'active' | 'planned' | 'complete'
|
||||
// Which of the two concurrent release lanes this study airs in (A = primary series, B = second series)
|
||||
lane?: '' | 'A' | 'B'
|
||||
// When a planned study is expected to start (ISO) — shown as "Starts <date>" on the hub
|
||||
startsAt?: string
|
||||
difficulty: 'beginner' | 'intermediate' | 'advanced'
|
||||
estimatedHours: number
|
||||
completionBadge: string
|
||||
@@ -85,16 +91,60 @@ export interface Testimonial {
|
||||
source?: string
|
||||
}
|
||||
|
||||
export interface SecondSeries {
|
||||
label: string
|
||||
title: string
|
||||
description: string
|
||||
imageUrl: string
|
||||
listenUrl: string
|
||||
listenBtnLabel: string
|
||||
studySlug?: string
|
||||
season?: number
|
||||
}
|
||||
|
||||
export interface FinishedBook {
|
||||
id: string
|
||||
title: string
|
||||
description: string
|
||||
imageUrl: string
|
||||
season: number
|
||||
// The study that goes with this book, so the card can offer both "Listen" and "Study"
|
||||
studySlug?: string
|
||||
downloadUrl?: string
|
||||
downloadQrUrl?: string
|
||||
}
|
||||
|
||||
export interface ScheduledSeriesTransition {
|
||||
triggersAt: string // ISO datetime — server fires at or after this time (checks hourly)
|
||||
// New series card
|
||||
newTitle: string
|
||||
newDescription?: string
|
||||
newImageUrl?: string
|
||||
newSeason: number
|
||||
// Study that opens (planned → active) when this series launches; the ending series' study becomes Complete
|
||||
newStudySlug?: string
|
||||
// Start Here section (optional)
|
||||
newStartHereHeading?: string
|
||||
newStartHereIntro?: string
|
||||
newStartHereStep1Title?: string
|
||||
newStartHereStep1Body?: string
|
||||
newStartHereStep1Cta?: string
|
||||
newStartHereStep2Title?: string
|
||||
newStartHereStep2Body?: string
|
||||
newStartHereStep2Cta?: string
|
||||
newStartHereStep3Title?: string
|
||||
newStartHereStep3Body?: string
|
||||
newStartHereStep3Cta?: string
|
||||
// Companion Study Guide / Featured Download (optional)
|
||||
newStudyGuideTitle?: string
|
||||
newStudyGuideDescription?: string
|
||||
newStudyGuideDownloadUrl?: string
|
||||
newStudyGuideUrl?: string
|
||||
newStudyGuideAmazonButtonLabel?: string
|
||||
newStudyGuideAppleBooksUrl?: string
|
||||
newStudyGuideAppleBooksLabel?: string
|
||||
}
|
||||
|
||||
export interface PodcastHost {
|
||||
id: string
|
||||
name: string
|
||||
@@ -184,6 +234,10 @@ export interface SiteContent {
|
||||
seriesImageUrl: string
|
||||
seriesListenUrl: string
|
||||
seriesListenBtnLabel: string
|
||||
seriesStudySlug?: string
|
||||
seriesSeason?: number
|
||||
// Optional second concurrent series (Lane B). Same card as the primary series.
|
||||
secondSeries?: SecondSeries
|
||||
seriesDownloadsBtnLabel: string
|
||||
// ── Downloads ──
|
||||
studyGuideTitle: string
|
||||
@@ -334,34 +388,9 @@ export interface SiteContent {
|
||||
// ── Scheduled Series Transition ──
|
||||
// All fields fire together at triggersAt. Start Here and Study Guide fields are optional —
|
||||
// omit them to leave those sections unchanged when the series transitions.
|
||||
scheduledSeriesTransition?: {
|
||||
triggersAt: string // ISO datetime — server fires at or after this time (checks hourly)
|
||||
// New series card
|
||||
newTitle: string
|
||||
newDescription?: string
|
||||
newImageUrl?: string
|
||||
newSeason: number
|
||||
// Start Here section (optional)
|
||||
newStartHereHeading?: string
|
||||
newStartHereIntro?: string
|
||||
newStartHereStep1Title?: string
|
||||
newStartHereStep1Body?: string
|
||||
newStartHereStep1Cta?: string
|
||||
newStartHereStep2Title?: string
|
||||
newStartHereStep2Body?: string
|
||||
newStartHereStep2Cta?: string
|
||||
newStartHereStep3Title?: string
|
||||
newStartHereStep3Body?: string
|
||||
newStartHereStep3Cta?: string
|
||||
// Companion Study Guide / Featured Download (optional)
|
||||
newStudyGuideTitle?: string
|
||||
newStudyGuideDescription?: string
|
||||
newStudyGuideDownloadUrl?: string
|
||||
newStudyGuideUrl?: string
|
||||
newStudyGuideAmazonButtonLabel?: string
|
||||
newStudyGuideAppleBooksUrl?: string
|
||||
newStudyGuideAppleBooksLabel?: string
|
||||
}
|
||||
scheduledSeriesTransition?: ScheduledSeriesTransition
|
||||
// Same, for the second series lane
|
||||
scheduledSecondSeriesTransition?: ScheduledSeriesTransition
|
||||
// ── Testimonials ──
|
||||
testimonials: Testimonial[]
|
||||
// ── Nuggets (sub-show) ──
|
||||
|
||||
Reference in new issue
Block a user