Skip to content

feat(landing): upgrade built-in templates to live-data widgets (#429) - #488

Merged
guillermoscript merged 1 commit into
masterfrom
feat/live-data-templates-429
Jul 22, 2026
Merged

feat(landing): upgrade built-in templates to live-data widgets (#429)#488
guillermoscript merged 1 commit into
masterfrom
feat/live-data-templates-429

Conversation

@guillermoscript

Copy link
Copy Markdown
Owner

Description

Upgrades all 33 static built-in landing templates to the live-data widgets shipped in #430, so a tenant applying any template sees their real courses, plans, and stats instead of fake placeholder numbers.

The survey behind this change found the gap was narrower than the issue assumed: TestimonialGrid, TeamGrid, and PricingTable already prefer live tenant data whenever it exists (live.length > 0 ? live : items) — their hard-coded arrays only ever render as the no-data fallback, which acceptance criterion 5 wants kept. The real bug was the stats blocks: StatsCounter only goes live when useLiveStats === true, and Puck's <Render> does not backfill defaultProps for content stored in puck_data, so every applied template rendered fake numbers ("8,000+ students", "Founded 2019") forever.

Changes made

  • useLiveStats: true on all 14 StatsCounter instances (4 in index.ts, 2 in each of the 5 vertical packs). Hard-coded items stay as the no-data fallback.
  • Explicit courseIds: [] on all 9 remaining CourseGrid instances — documents the "latest courses" curation contract and matches the free-course-school reference template.
  • Catalog pages upgraded to CatalogBrowser: the "Course Catalog" and "Code School — Courses" templates swap their static maxItems: 12 "All Courses" CourseGrid for the live CatalogBrowser (search + Free/Paid filter + pagination), keeping each page's title/subtitle.
  • Deliberately unchanged: static testimonial/team/pricing arrays (they are already pure fallback and preserve each template's branding on empty tenants); SocialProof (already per-field live-aware); EnrollCta not added — every home template already closes with a CTA block, and EnrollCta only adds value once an admin curates a specific course in the editor.

No component, schema, or query changes — template data only. Existing saved landing_pages rows are snapshots and are unaffected; only pages created from templates after this change pick it up.

Type of change

  • New feature (non-breaking change which adds functionality)

Relationship

Closes #429

Testing

  • npm run build — exit 0 (only pre-existing bigint binding warnings)
  • npm run gen:puck-fields — no diff (manifest derives from lib/puck/config.ts, not templates; verified anyway)
  • Browser spot-check on the seeded Code Academy tenant: "Language School — Home", "Course Catalog", and "Code School — About" re-rendered from the updated templates — stats sections show live counts (1 student / 2 courses / 0 completions), the catalog page shows the searchable CatalogBrowser, and testimonial/team/pricing fallbacks still render for data the tenant lacks (reviews/instructors).

QA verification steps

  1. Log in as an admin (creator@codeacademy.com / password123 on code-academy.lvh.me:3005).
  2. Go to Dashboard → Website → Landing Pages, create a new page, and apply the "Language School — Home" template (or any vertical Home template).
  3. In the editor preview (or via Preview after saving), scroll to the stats band under the hero: it should show the tenant's real counts (students / courses / lessons completed), not "8,000+ / 6 / 120+".
  4. Apply the "Course Catalog" template to another page: the "All Courses" section should now be a searchable catalog with Free/Paid filter chips listing the tenant's real courses. Type a course name in the search box and confirm filtering works.
  5. Apply any template to a tenant with no courses/reviews (e.g. a fresh school): stats fall back to the template's placeholder numbers and testimonials/team/pricing show the template's placeholder content — no empty sections, no crashes.

Screenshots

Before/after screenshots and a verification GIF follow in a PR comment (private repo — uploaded as attachments).

Set useLiveStats on all 14 StatsCounter instances (Puck Render does not
backfill defaultProps for template content, so the flag must be explicit),
add courseIds: [] to every CourseGrid to document the latest-courses
curation contract, and swap the two dedicated catalog pages' static
"All Courses" CourseGrid for the live CatalogBrowser with search and
price filters. Static testimonial/team/pricing arrays stay as the
no-data fallback — the live path already overrides them when tenant
data exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@guillermoscript guillermoscript added the enhancement New feature or request label Jul 22, 2026
@guillermoscript guillermoscript self-assigned this Jul 22, 2026
guillermoscript added a commit that referenced this pull request Jul 22, 2026
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@guillermoscript

Copy link
Copy Markdown
Owner Author

Visual verification — before / after

All captures are from the admin preview route on the seeded Code Academy tenant (2 real courses, 2 real plans, 1 student). Before-shots were taken in a dark-theme session and after-shots in a light-theme session — the theme difference is incidental; compare the data in each section. Reviewer: please verify these visually before merging.

Language School — Home: stats band

Before — hard-coded placeholder stats ("8,000+ active students, 6 languages, 120+ native teachers") no matter which tenant applies the template:

before: static stats

After — live tenant stats (1 student / 2 courses / 0 completions):

after: live stats

Course Catalog: "All Courses" section

Before — plain static CourseGrid:

before: plain course grid

After — live CatalogBrowser with search box and All/Free/Paid filter chips over the tenant's real catalog:

after: catalog browser

Code School — About: stats

Before — fake story numbers ("12,000+ students, 40+ countries, 85% placement, founded 2019"):

before: fake story stats

After — live tenant stats:

after: live about stats

Flow recording

The GIF walks the upgraded "Language School — Home" page top to bottom (live stats → live courses → live pricing), then the upgraded "Course Catalog" page, including typing "python" into the new catalog search and clearing it:

verification GIF

@guillermoscript
guillermoscript marked this pull request as ready for review July 22, 2026 23:41
@guillermoscript
guillermoscript merged commit 2b67ac0 into master Jul 22, 2026
2 checks passed
@guillermoscript
guillermoscript deleted the feat/live-data-templates-429 branch July 22, 2026 23:50
@guillermoscript

Copy link
Copy Markdown
Owner Author

Shipped — squash-merged to master as 2b67ac0.

Final scope, unchanged from the review body: useLiveStats: true on all 14 template StatsCounter instances, explicit courseIds: [] on the 9 remaining CourseGrid instances, and the two catalog templates ("Course Catalog", "Code School — Courses") upgraded from a static course grid to the live CatalogBrowser. Template data only — no component, schema, or migration changes, so nothing to apply to the cloud database. Existing saved landing pages are unaffected; pages created from templates after this merge pick up the live-data behavior.

QA record: npm run build clean, gen:puck-fields no diff, and browser verification on the seeded Code Academy tenant (before/after screenshots and flow GIF in the comment above).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Upgrade built-in landing templates to live-data widgets

1 participant