Commit Graph
115 Commits
Author SHA1 Message Date
nmemmertandClaude Sonnet 5.5 e74bd1df5d Upgrade Asset Manager and Inbox; load Resend templates in Broadcast; v2.5.0
Publish Container / build (push) Successful in 16m39s
- Asset Manager: search/filter/sort, list+grid views, rename, move between R2 folders, tag chips, bulk actions, used-in counts; fix R2 delete lookup
- Inbox: readable wrapped rows with subject/preview, real read state, type filters, bulk actions, mojibake repair
- Broadcast: pick a Resend template to fill subject and body

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 07:45:50 -04:00
nmemmertandClaude Sonnet 4.6 06f89d6436 Fix Scripture Index page width; v2.0.35
Publish Container / docker (push) Successful in 14m16s
.scripture-index-main had no max-width — page stretched full viewport width.
Set to 900px with auto margins to match the site standard.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-18 11:13:54 -04:00
nmemmertandClaude Sonnet 4.6 a4c37d0276 Render QR code on finished series page; v2.0.34
Publish Container / docker (push) Successful in 13m37s
The downloadQrUrl field was saved but never displayed — add the QR image
below the action buttons, wrapped in a link to the download URL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-18 11:12:20 -04:00
nmemmertandClaude Sonnet 4.6 e64c784c7c Standardize page content widths to 900px; v2.0.33
Publish Container / docker (push) Successful in 14m16s
- Add missing .page-inner CSS (finished series page was stretching full width)
- Fix .site-search-bar-inner: 860px → 900px
- Remove redundant max-width from .section-share-inner (inherits 900px from .section-inner)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-18 10:34:21 -04:00
nmemmertandClaude Sonnet 4.6 e86594b096 Add download option and CD disc artwork to finished books; v2.0.31
Publish Container / docker (push) Successful in 14m49s
- Add downloadUrl field to FinishedBook type
- Admin: paste any external URL (Drive, Dropbox, etc.) per finished book
- Public series page: replace square hero image with circular CD disc artwork
  (conic-gradient sheen, center hole, drop shadow, slight tilt)
- Stream Episodes + Download Album action buttons in the hero
- Grid cards show a gold download badge when a download URL is set

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-18 10:16:42 -04:00
nmemmertandClaude Sonnet 4.6 7ff5c453e8 Redesign Nuggets page: host pills in a row above episodes; v2.0.22
Publish Container / docker (push) Successful in 14m8s
Replaces the two-column hosts/episodes sidebar layout with a single full-width
column: host pills (photo + name, pill-shaped, clickable) in a horizontal row
at the top, episodes list filling the full width below.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-16 07:37:25 -04:00
nmemmertandClaude Sonnet 4.6 b35605f411 Add clickable host bios linking to host detail pages on Nuggets; v2.0.21
Publish Container / docker (push) Has been cancelled
Each host card on /nuggets now links to /nuggets/hosts/:hostId showing
the host's full photo, bio, and listen links. Archived hosts return a
graceful "not found" page with a back link.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-16 07:32:18 -04:00
nmemmertandClaude Sonnet 4.6 29d2ace1b2 Fix cramped host card layout on Nuggets page; v2.0.3
Publish Container / docker (push) Successful in 12m59s
- Restructure host card: image+name/role in a row header, bio spans full card width below
- Widen hosts column from 300px max to 360px max
- Add nuggets-host-card-header and nuggets-host-card-meta CSS classes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-08 10:47:21 -04:00
nmemmertandClaude Sonnet 5 31e79ad542 Add Verse By Verse: Nuggets sub-show with editable hosts and RSS feed
Publish Container / docker (push) Successful in 14m16s
New /nuggets page for the companion show, linked from the Episodes nav
dropdown. Hosts (name, role, bio, photo) show in a left column with the
episode list on the right — latest episode featured, rest below.
Episodes are pulled from an admin-configurable RSS feed URL (empty by
default, shows "coming soon" until set) rather than hardcoded like the
main show's feed, since the show doesn't have one yet.

Everything is editable in /admin under a new Nuggets section: Show
Settings (title, tagline, description, podcast art, RSS/platform URLs)
and Hosts (add freely; removing a host archives them instead of
deleting — kept on record and restorable, never lost).

Extracted the RSS item-parsing logic shared with the main show's feed
(server/routes/episodes.js) into server/rss-helpers.js so both feeds
use the same parser instead of duplicating it.

Also fixes the local Vite dev server not proxying /uploads/* to the
backend — it was silently serving the SPA shell (200, text/html)
instead of the actual file, so any admin-uploaded image (podcast art,
host photos, etc.) appeared broken in local dev only.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016Yvx4rPVy2HWe7ubuk3X3J
2026-09-07 14:27:52 -04:00
nmemmertandClaude Sonnet 5 c158fb6317 Fix contact form crash, analytics range filter, Scripture Index parsing, and unsafe-delete UI bugs
Publish Container / docker (push) Successful in 13m12s
- server/routes/contact.js: import fireWebhooks (was undefined, throwing on every submission)
- server/routes/analytics.js: filter admin-stats by row.at, the field recordVisitor actually sets, instead of the never-populated row.visitedAt
- src/App.tsx: parseSIRef now supports chapter-spanning verse ranges (e.g. "5:15-6:2"); SI_BOOK_MAP indexes both spaced and unspaced book names so multi-word Bible Book values from the admin field resolve correctly
- src/App.css / src/App.tsx: fix Episodes/Studies nav dropdown menus being unclickable — a positioning gap between the trigger and menu created a hover dead zone; menu is now flush with spacing moved into padding so hover carries through
- src/components/StudySectionComments.tsx: check response status before removing a comment locally, so a rejected delete no longer appears to succeed
- src/components/QASection.tsx: don't bail out of search scoring for 1-2 character queries, so short substrings like "OT" or "AI" can still match
- src/AdminPage.tsx: check response status in study-user, QR code, and episode-script delete handlers before updating local state

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016Yvx4rPVy2HWe7ubuk3X3J
2026-09-07 09:39:37 -04:00
nmemmertandClaude Sonnet 5 6ed29ea527 Rebuild Scripture Index as a true cross-content reference index
Publish Container / docker (push) Successful in 15m2s
Previously it just grouped study lessons under each study (essentially
another list of lessons) and ignored podcast episodes entirely. Now it
parses every reference from studies and episode show notes, merges
entries that point at the same verse(s) into one row with links to all
sources, and groups rows by book in canonical Bible order. References
that don't parse (e.g. whole-chapter refs) fall into an "Other
References" section instead of being dropped.

Also fixes the reference passed to the index for studies without a
bibleBook set — it was falling back to the study's marketing title
instead of its slug, producing unparseable references.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016Yvx4rPVy2HWe7ubuk3X3J
2026-09-07 09:20:12 -04:00
nmemmertandClaude Sonnet 4.6 53e200174f Add community shortcut to lesson sidebar; v1.2.7
Adds a "Discuss this lesson" link in the classroom sidebar that takes
the user directly to the community page pre-filtered to the current
lesson's sectionId, so they can jump into discussion without navigating
back to the study index first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-03 16:38:38 -04:00
nmemmertandClaude Sonnet 4.6 49e3a80c2c Redesign community section with social media feed UX; v1.2.6
- Twitter/X-style post cards: avatar thread line, author + relative timestamp
- Heart like button with optimistic toggle and like count per post
- Comment button with reply count; inline threaded replies always visible
- Compose card with user avatar, borderless textarea, pill Post button
- Horizontal scrollable lesson filter chips (All + per-lesson)
- New POST /api/study-community/posts/:postId/like endpoint (toggle)
- GET community posts now returns likedByMe + likeCount per post
- sanitizeStudyCommunityPosts preserves likedBy array on disk
- Relative timestamps (just now, Xm ago, Xh ago, Xd ago, then date)
- UserAvatar helper renders img or initials fallback consistently

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-03 16:34:28 -04:00
nmemmertandClaude Sonnet 4.6 874dd0c89b Redesign study lesson UI: progress bar, sidebar nav, inline answers; v1.2.5
- Progress bar: thin gold bar under lesson label showing completed/total lessons
- Sidebar lesson navigator: all lessons listed with ✓/current/○ states, replaces static Study Track + Lesson Navigation blocks
- Notes panel moves to sidebar: clicking a block's Note button opens NoteCard in sidebar instead of inline, preserving reading position
- Inline reflection answers: textareas under each question auto-save to quiz API; replaces separate quiz page link
- Note buttons: "Note" / "✎ Note" text label instead of bare pencil icon for better discoverability
- Greek Word Study block hidden when lesson has no greek notes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-03 16:01:15 -04:00
nmemmertandClaude Sonnet 4.6 525ae85f6a Fix scripture verse popup clipped by overflow:hidden parents; v1.2.2
Publish Container / docker (push) Successful in 13m53s
Switch from position:absolute (relative to trigger) to position:fixed
with getBoundingClientRect() so the popup escapes any overflow:hidden
ancestor. Also closes on scroll and window resize.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-03 11:21:04 -04:00
nmemmertandClaude Sonnet 4.6 36dfa0c1d7 Redesign Scripture Index with BSB verse text and row layout; v1.2.1
Publish Container / docker (push) Successful in 13m38s
- Replace cramped auto-fill grid with full-width row layout (reference | verse text | arrow)
- Fetch BSB passage text from bible.helloao.org, grouped by chapter to minimize API calls
- Display 2-line italic excerpt of each passage beneath the lesson title
- Hover state reveals arrow and highlights row in gold
- Mobile-responsive collapse to single column

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-03 11:04:22 -04:00
nmemmertandClaude Sonnet 4.6 83d631608b Add Studies dropdown with Scripture Index link; split nav triggers into hover+click
Publish Container / docker (push) Successful in 14m4s
- Studies nav item is now a dropdown (same pattern as Episodes): hover to expand,
  click the label to navigate directly to /study
- Dropdown contains: All Studies (/study) and Scripture Index (/scripture)
- Episodes dropdown follows the same split pattern: label navigates, caret toggles
- Dropdown menus open on CSS :hover (desktop) and stay toggle-able on mobile
- v1.2.1

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-03 10:34:17 -04:00
nmemmertandClaude Sonnet 4.6 63d4f9e316 v1.2.0: Broadcast emails, webhook admin UI, dynamic sitemap, scripture index
Publish Container / docker (push) Successful in 14m11s
- Admin > Audience > Broadcast Email: compose and send one-off HTML emails
  to all subscribers via Resend batch API; {{name}} personalization; confirm step
- Admin > Configure > Webhooks: CRUD UI for managing POST event webhooks;
  backend GET/POST/DELETE /api/admin-webhooks routes wired to existing state.webhooks
- Sitemap: dynamically appends released study lesson URLs (/study/:slug/:id)
  and episode highlight URLs (/episodes/:id) to /sitemap.xml
- Scripture Index: public /scripture page listing every released lesson grouped
  by study with passage reference links; served by /api/public/scripture-index

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-03 09:54:43 -04:00
nmemmertandClaude Sonnet 4.6 14665d06b5 Replace study lesson expanding cards with master-detail drill-down; v1.1.51
Publish Container / docker (push) Successful in 13m15s
Studies section now uses a three-level navigation: study list → study detail
with compact sortable lesson rows → individual lesson editor. Eliminates the
40+ expanding AdminCollapsibleCard items for lessons, replacing them with a
compact table (drag handle, reference, title, live/draft status, edit/preview/
delete per row) and a focused lesson editor opened by clicking Edit. Prev/Next
navigation between lessons added. BsbFetchButton extracted as a standalone
component for the inline lesson editor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-03 09:23:56 -04:00
nmemmertandClaude Sonnet 4.6 e593031d0d Revamp /admin with drill-down sidebar nav and focused sub-views; v1.1.50
Publish Container / docker (push) Successful in 13m50s
- Replace flat sidebar with accordion nav: parent items (Homepage, About,
  Contact, Podcast Hub) expand to reveal focused sub-items
- Split big sections into granular sub-views so each form shows only 3-8
  fields (Homepage: Hero/Share/PRISM/Where-to-Next, About: Show Copy/Bio/
  Testimonials, Contact: Profile/Copy & Scripture, Podcast: Current Series/
  Highlights/Finished Books/Scripts/RSS)
- New topbar: brand + breadcrumb (Homepage › Hero), clean gold Save Draft
  button, ghost Preview/Publish buttons — no more jump-to select
- New sidebar: compact 196px width, filter input at top, small-caps group
  labels, chevron-animated parent items, indented sub-items with active
  highlight, Back-to-site/Log-out/version at the bottom
- Replace PodcastTab state with adminView sub-views (podcast:current-series
  etc.) eliminating the secondary tab bar inside the panel
- Extend AdminView type with all new colon-separated sub-view values

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-03 09:09:52 -04:00
nmemmertandClaude Sonnet 4.6 0d2e68ae11 Fix Ko-fi support section to match dark site theme; v1.1.48
Publish Container / docker (push) Successful in 13m37s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-02 12:03:16 -04:00
nmemmertandClaude Sonnet 4.6 07b2dc843f Add Ko-fi support section with QR code to About page; v1.1.47
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-02 11:58:34 -04:00
nmemmertandClaude Sonnet 4.6 fc63a34ef2 Shrink download detail cover image to 180px wide; v1.1.44
Publish Container / docker (push) Successful in 14m28s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-27 13:40:48 -04:00
nmemmertandClaude Sonnet 4.6 0512d40fc6 Redesign resources page with PageBanner, featured download, and consistent page headers; v1.1.40
Publish Container / docker (push) Has been cancelled
- Replace hero study guide form with PageBanner + featured download card in library
- Add PageBanner component used consistently across all interior pages (Downloads, Episodes, About, Contact, Q&A, Finished Books)
- Remove duplicate headings/eyebrows that conflicted with banner titles on About, Contact, Q&A, Finished Books pages
- Compact download card sizing (padding, border-radius, image size)
- Add Books & Resources tabbed section with fallback to TruthForLife widget
- Fix server sanitizer to pass through 'resources' placement items without URL
- Add featured-badge and featured card styling for primary guide

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-26 11:03:43 -04:00
nmemmertandClaude Sonnet 4.6 eb1d3ddd9c Add Books + editable Recommended Resources sections; improve content block links; v1.1.38
- CustomBlock: add linkUrl/linkLabel fields for a styled button below the body
- Body text auto-linkifies raw URLs into gold anchor tags
- New 'books' placement: Reading List grid on Downloads page (cover, desc, Amazon btn)
- New 'recommended' placement: editable Recommended Resources section on Downloads
  page; falls back to Truth For Life widget when empty
- Admin: Books and Recommended Resources panels added to Content nav

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-26 08:16:36 -04:00
nmemmertandClaude Sonnet 4.6 111b559865 Add webhook outbound, Contact→Calendar, checklist automation; v1.1.26
- Webhook CRUD (GET/POST/DELETE /api/admin-webhooks, POST .../test) with
  ⚡ Webhooks drawer in EmailPage; fires contact.new and reply.sent events
- Contact→Calendar: history panel shows checklist episodes within ±30 days
- Checklist automation: saveEdit auto-sets productionStatus (idea→scheduled
  for future dates, idea→published for past); ⚙ Tasks button generates
  Record (−14d) and Edit (−7d) calendar task events for scheduled episodes
- Audit log captures webhook-added, webhook-removed, webhook-test events
- Webhook infrastructure: state, disk persistence, fire-and-forget with
  AbortSignal.timeout(8000), loaded on startup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-29 08:03:30 -04:00
nmemmertandClaude Sonnet 4.6 f5c4557e9f Add Tier 2 remaining features: publishing pipeline, broadcasts, audit log, drip trigger, today banner; v1.1.25
- CalendarPage: productionStatus field on episodes (idea→recorded→edited→scheduled→published), color dot on chips, dropdown in edit popover; "publishing today" banner with draft announcement button
- EmailPage: Broadcasts drawer (plain-text → Resend Broadcasts API); Audit Log drawer showing activity history; em-status-msg--ok style
- ContactsPage: ▶ Drip button in edit mode syncs contact to Resend audience and triggers drip automation
- server: appendAuditEntry() logged on reply-sent, email-sent, submission-deleted, contacts-merged, contacts-imported, broadcast-sent, drip-triggered; GET /api/admin-audit-log; POST /api/admin-broadcasts/send; POST /api/admin-contacts/trigger-drip; AUDIT_LOG_FILE persisted to data/audit-log.json

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-29 07:52:07 -04:00
nmemmertandClaude Sonnet 4.6 bf16deea92 Add Tier 2 email features: AI draft, Calendar→Email announce, delivery status, engagement badges; v1.1.24
- EmailPage: useLocation to accept pre-filled compose from Calendar; delivery status pill on sent bubbles; AI Draft button calling ANTHROPIC_API_KEY endpoint
- CalendarPage: useNavigate + announceEpisode(); ✉ Announce button in episode edit popover
- ContactsPage: emailStatus types; unreplied badge; best delivery status pill; engagement score stars
- server/routes/contact.js: POST /api/admin-contact-submissions/:id/draft-reply → Anthropic claude-haiku-4-5

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-28 17:10:25 -04:00
nmemmertandClaude Sonnet 4.6 e2c560a1ab Add contacts features: tags, history, CSV import/export, merge, last-contacted; fix CalendarPage unused var; v1.1.23
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-28 17:00:21 -04:00
nmemmertandClaude Sonnet 4.6 5e43c41b2b Add recurring events, week/day view, drag-to-reschedule, iCal export, and start times to calendar; v1.1.22
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-28 16:46:45 -04:00
nmemmertandClaude Sonnet 4.6 ee7c783de8 Add email threading, snooze, bulk actions, scheduled send, stars, and attachments; v1.1.21
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-28 16:29:24 -04:00
nmemmertandClaude Sonnet 4.6 a263f40178 Fix compose focus steal; add contact picker to To field; v1.1.17
- Focus effect now only fires when compose/reply first opens, not on every
  keystroke — typing in the To field no longer jumps focus to the body
- 👥 button next to To field opens a searchable contact picker dropdown;
  selecting a contact fills in email and name instantly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-28 12:15:45 -04:00
nmemmertandClaude Sonnet 4.6 f0635753f1 Add general calendar events (recording, social, task, general); nav links; v1.1.16
- Four event types on the calendar: General, Recording, Social, Task — each color-coded
- + Event button opens form with type picker, title, date, notes, reminder
- Task events have a Mark Complete toggle; completed events show strikethrough
- Edit/delete popover for each event
- Email reminders work for calendar events same as episodes
- Added Email/Calendar nav links to /contacts header
- Added Email link to /calendar header (already had Admin)
- /email already links to Contacts and Calendar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-28 11:26:48 -04:00
nmemmertandClaude Sonnet 4.6 de201ff356 Add email reminders to calendar episodes; v1.1.15
- Per-episode reminder select (1d/2d/3d/1wk/2wk before publish date)
- Server checks hourly; fires Resend email to admin on reminder day
- reminderSentAt persisted so reminders don't re-fire; cleared if date or setting changes
- Bell indicator on calendar chips; sent confirmation in edit popover

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-28 11:12:17 -04:00
nmemmertandClaude Sonnet 4.6 ce235ba9ef Add /contacts and /calendar pages; email signature settings; v1.1.12
- /contacts: standalone page with hybrid contact list (submissions + manual entry), inline edit, search, archive
- /calendar: monthly release scheduling calendar reading/writing podcast checklist episode dates
- /email settings: editable signature panel; signature persisted server-side and injected into outgoing emails
- Move contacts out of /admin panel (now links to /contacts route)
- Partial PATCH for contact submissions (name, notes, archived independently)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-28 10:12:52 -04:00
nmemmertandClaude Sonnet 4.6 7670b44d27 Add /email route as standalone web email client; v1.1.11
Extracts the email inbox from /admin and builds it as a full-viewport
email client at /email with the same admin auth. Key improvements over
the old embedded panel:

- Full-height split-pane layout (sidebar list + detail pane)
- Subject line extracted and shown separately for inbound emails
- Inline reply composer inside the detail pane (no more page-jump)
- Compose-new button for outbound messages to arbitrary addresses
- Search/filter across name, email, subject, and body
- Unread dot indicators with localStorage tracking (marks read on open)
- Keyboard navigation: ↑/↓ or j/k to move, r to reply, e to archive, Esc to close
- Source badges (contact-form / inbound-email) on list items
- Sent history and reply templates accessible via footer drawers
- 30-second polling for new messages
- New POST /api/admin-email/compose server endpoint for outbound sends
- Dashboard card "Open Inbox" now links to /email

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-28 09:34:39 -04:00
nmemmertandClaude Sonnet 4.6 e75a6d0e15 Increase episode title size on /episodes player; v1.1.10
Bumped .latest-episode-player__title from 1rem to 1.65rem for legibility.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 14:54:49 -04:00
nmemmertandClaude Sonnet 4.6 021fe24c7e Separate /episodes player from per-episode player; v1.1.8
- EpisodeAudioPlayer restored to original horizontal layout (unchanged
  for individual episode detail pages chosen in /admin)
- LatestEpisodePlayer on /episodes page gets its own markup + CSS
  (.latest-episode-player__*) with the centered layout A — large gold
  play button, skip-back 15s / skip-forward 30s, full-width scrubber

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 14:42:08 -04:00
nmemmertandClaude Sonnet 4.6 5d4ba7e593 Replace Spotify iframe with custom centered player (layout A); v1.1.5
- EpisodeAudioPlayer full variant: centered title, large gold play button,
  skip-back 15s / skip-forward 30s flanking controls, full-width scrubber
- Compact variant (study sections) unchanged
- Episode detail page fetches direct Anchor MP3 URL from /api/episodes by
  title match; falls back to resolvedEmbedUrl while loading
- Plays stream from Anchor CDN so stats still count

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 14:32:05 -04:00
nmemmertandClaude Sonnet 4.6 43799b8c6d Make compact view visually distinct; v1.0.9
Add qa-cards--compact class to container when active. Compact mode now
tightens padding, reduces font sizes, hides related questions, and
reduces card gaps — making the density difference obvious.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 12:41:43 -04:00
nmemmertandClaude Sonnet 4.6 b60604aa80 Add testimonials section and Q&A submit CTA; v1.0.8
- Testimonials: new Testimonial type, CMS field, admin UI under About,
  and TestimonialsSection rendered on homepage and About page (hidden when empty)
- Q&A: "Submit a Question →" CTA at bottom of Q&A page linking to /contact

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 12:37:46 -04:00
nmemmertandClaude Sonnet 4.6 a7c5906c7b Remove dead CSS for qa-top-nav and thanks-page Q&A overrides; v1.0.7
These rules became orphaned after converting QuestionsPage to a full site
layout and removing the back-to-site nav link from QASection.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 12:02:07 -04:00
nmemmertandClaude Sonnet 4.6 172e4a9358 Add version numbering (v1.0.0)
- package.json: bump to 1.0.0
- server/config.js: export APP_VERSION (from package.json) and GIT_COMMIT
  (from COMMIT_SHA env var set by CI, or git rev-parse --short HEAD fallback)
- GET /api/version: new public endpoint returning { version, commit }
- GET /api/admin-auth/status: includes version and commit in response
- AdminPage sidebar: displays version string (e.g. "v1.0.0 (1d43875)")
  below the Log Out button, styled as muted metadata text

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-16 07:55:52 -04:00
nmemmertandClaude Sonnet 4.6 25fa24afdf Add Finished Books feature with episode playlists and nav dropdown
Public:
- /finished page with ornament heading, intro text, book grid, and styled empty state
- /finished/:id episode playlist page filtered by RSS season number
- Episodes nav becomes click-toggle dropdown (Current Series / Finished Books)
- Finished Books link in footer
- Dropdown font fixed to match other nav links

Admin:
- End Current Series & Start New Book wizard on Current Series tab
- Finished Books management tab with add/edit/remove and image asset picker

Data:
- FinishedBook type + finishedBooks[] field on SiteContent
- RSS parser extracts itunes:season per episode

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 10:34:43 -04:00
nmemmertandClaude Sonnet 4.6 2eb98b66d0 Add Finished Books feature with episode playlists
- New FinishedBook type in content.ts + finishedBooks[] field on SiteContent
- RSS parser now extracts itunes:season into each episode object
- /finished grid page and /finished/:id playlist page (filters episodes by season)
- Episodes nav link replaced with dropdown: Current Series / Finished Books
- Finished Books link added to footer
- Admin: "End Current Series & Start New Book" wizard on Current Series tab
- Admin: Finished Books management tab (add/edit/remove entries)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 10:22:37 -04:00
nmemmert dd43d0c3ea notes upgrade 2026-06-18 13:43:17 -04:00
nmemmertandClaude Sonnet 4.6 945a2e160e Redesign visitor log as readable cards replacing dense table
Each visit is now a card showing name/IP, page path, location, device,
visit count, new/returning tag, and timestamp at a glance. Logged-in users
show their display name prominently. Click to expand still shows full page
history and raw details. Adds a purple "Logged in" tag for study users.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 14:24:16 -04:00
nmemmertandClaude Sonnet 4.6 8450d81e7f Add per-episode play tracking with bar chart in admin analytics
- POST /api/analytics/play records a play event (title + date) on first
  play per player mount, skipping admin sessions
- Plays persisted to data/episode-plays.json with total + byDay buckets
- Admin stats response includes episodePlays sorted by total plays
- AnalyticsPanel shows horizontal bar chart + summary cards for all
  episodes dynamically — new episodes appear automatically as played

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 13:39:35 -04:00
nmemmertandClaude Sonnet 4.6 a1d5889711 Replace Spotify embeds with branded custom audio player backed by RSS
- Add /api/episode-audio route returning MP3 URLs from Anchor RSS feed
- Replace Spotify URL text inputs in admin with RSS episode dropdowns
- New EpisodeAudioPlayer component with podcast art, show name, progress
  bar, and Spotify icon link — full and compact sizes
- Backward-compatible: legacy Spotify embed URLs still render as iframes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 13:23:19 -04:00
nmemmertandClaude Sonnet 4.6 3d8f02d915 Scope external site link styles to homepage section only
The .section-resources CSS overrides were breaking the Downloads page
resource link layout. Added .section-external-sites class to the
ExternalSitesSection and scoped all image/layout overrides to it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 12:04:49 -04:00