Commit Graph
368 Commits
Author SHA1 Message Date
nmemmertandClaude Sonnet 4.6 0bf2d92b1f Apply master-detail pattern to Ep. Highlights and Download Library; v1.1.52
Publish Container / docker (push) Successful in 13m55s
Episode Highlights and the Downloads Library section now use the same compact
list → click to edit pattern as Studies. Both sections show a scannable row
list (title, key meta, edit/delete buttons) and open a focused editor for a
single item. Testimonials and Finished Books remain as collapsible cards since
they have few fields and grow slowly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-03 09:31: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 a072076818 Rename Downloads→Resources throughout, fix audit bugs, add /subscribe to footer; v1.1.49
Publish Container / docker (push) Successful in 14m2s
- Rename all user-facing "Downloads" text to "Resources" (nav, page eyebrows, buttons, admin labels, page title, content defaults)
- Add usePageMeta to ContactPage, EpisodeDetailPage, DownloadDetailPage, StartHerePage for correct social share previews
- Wire contactEyebrow and aboutShowEyebrow fields to the UI (were editable in admin but never rendered)
- Wrap StartHerePage in full site chrome (header, search, footer); fix Step 2 link from /#qa to /questions
- Fix admin "View All Contacts" link (was 404); now navigates to Contact admin panel
- Remove broken "Previous Studies" jump nav entry (no matching anchor)
- Remove /studys typo route
- Make dashboard "Top Resource Downloads" stat dynamic instead of hardcoded to titus-study key
- Add Newsletter link (/subscribe) to footer legal nav
- Fix server.js startup log ("Portfolio app" → "Siteforge")

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-03 08:37:23 -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 d2829e610e Add Ko-fi integration: footer link, floating widget, and admin field; v1.1.46
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-02 11:57:09 -04:00
nmemmertandClaude Sonnet 4.6 0d830d6e79 Remove dead admin routes and broken UI elements; v1.1.45
Publish Container / docker (push) Successful in 14m54s
- Deleted ~24 unused API routes from contact.js (email inbox/CRM feature
  never wired to frontend): reply, compose, draft, broadcast, webhooks,
  audit-log, contact CRUD, merge, import, and health endpoints
- Removed dead imports from contact.js (config, data, email modules)
- Removed broken /email Link from admin dashboard Inbox card
- Cleaned up AdminView type: removed unreachable 'current-series' and
  'episode-highlights' top-level values (only valid as podcast sub-tabs)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-31 12:48:24 -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 943674e7f3 Fix server sanitizer to persist appleBooksUrl/Label on customLinks; v1.1.43
Publish Container / docker (push) Successful in 15m7s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-27 11:56:53 -04:00
nmemmertandClaude Sonnet 4.6 1db0a919c2 Add optional Apple Books button to downloads and book cards; v1.1.42
Publish Container / docker (push) Successful in 15m16s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-27 11:34:55 -04:00
nmemmertandClaude Sonnet 4.6 1097cb425c Fix docker-compose to use Gitea registry image; v1.1.41
Publish Container / docker (push) Successful in 15m13s
docker-compose.yml was still pointing to the old GHCR image
(ghcr.io/nmemmert/siteforge:latest) after CI was switched to push
to git.necloud.us/nate/siteforge:latest, so servers were pulling
a stale build that predated the download/header changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-26 13:53:37 -04:00
nmemmertandClaude Sonnet 4.6 75c82dc8fc Fix CI: use REGISTRY_USER and REGISTRY_TOKEN secrets for Gitea login
Publish Container / docker (push) Successful in 16m15s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-26 13:22:32 -04:00
nmemmertandClaude Sonnet 4.6 53405dad9b Fix CI: use email address as Gitea registry username
Publish Container / docker (push) Failing after 11m6s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-26 12:59:18 -04:00
nmemmertandClaude Sonnet 4.6 2d1c28b467 Fix CI: use Gitea username 'nate' for container registry login
Publish Container / docker (push) Has been cancelled
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-26 12:44:59 -04:00
nmemmertandClaude Sonnet 4.6 a4a1fdd891 Fix CI: hardcode Gitea username for container registry login
Publish Container / docker (push) Has been cancelled
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-26 12:26:59 -04:00
nmemmertandClaude Sonnet 4.6 6d4bcb2ae2 Fix CI: use github.actor context for Gitea registry login
Publish Container / docker (push) Failing after 11m20s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-26 12:24:36 -04:00
nmemmertandClaude Sonnet 4.6 293d9bee4e Switch CI to Gitea container registry; drop GHCR
Publish Container / docker (push) Failing after 10m54s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-26 12:11:09 -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 0fdf7f0f50 v1.1.39
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-26 08:49:32 -04:00
nmemmertandClaude Sonnet 4.6 005da43738 Default book button label to 'Learn More' when using url instead of amazonUrl; v1.1.38
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-26 08:47:25 -04:00
nmemmertandClaude Sonnet 4.6 24d7fd7cec Fix book card button to render when url is set but amazonUrl is not; v1.1.38
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-26 08:42:09 -04:00
nmemmertandClaude Sonnet 4.6 889baf23ca Fix server sanitizer to allow books/recommended placements and linkUrl/linkLabel fields; v1.1.38
- Add 'books' and 'recommended' to the placement whitelist in sanitizeCustomLinks
- Allow items with no url when placement is books/recommended (they use amazonUrl)
- Preserve linkUrl and linkLabel through sanitizeCustomBlocks

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-26 08:23:59 -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 a35e04320a Remove production checklist and email/calendar/contacts app; v1.1.37
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-20 09:30:19 -04:00
nmemmertandClaude Sonnet 4.6 2ba9c9f7f4 Add Fetch from BSB button to admin lesson editor; v1.1.36
Adds a one-click "Fetch from BSB" button in the lesson passage text field
that calls the BSB API and overwrites the field with verse-numbered text.
Also fixes reference parsing to tolerate leading book abbreviations like
t:1-2 or col:1-2 by stripping letters before the chapter:verse pattern.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-10 10:23:48 -04:00
nmemmertandClaude Sonnet 4.6 9e602e29ec Fetch BSB passage text from Bolls.life API in study lesson view; v1.1.35
Adds /api/bible-passage server route that proxies the Berean Standard Bible
from Bolls.life per-verse, with in-memory caching. Study lesson scripture
block now displays live BSB text instead of static passageText. Adds
bibleBook field to StudyProgram so admins can set the book name explicitly
when the study slug doesn't match (e.g. a study titled "ephesians-part-2").

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-10 10:12:25 -04:00
nmemmertandClaude Sonnet 4.6 6acc3f1d04 Analytics: 3-tab layout + fix geographic data loss; v1.1.34
Splits the analytics panel into Traffic / Engagement / System tabs so
episode plays, engagement metrics, and contact/study data are no longer
buried under the visitor log.

Fixes a bug where topCountries, topStates, topCities, device breakdown,
and referrers were computed from only the 100 most-recent visitor rows
instead of all rows in the selected range — causing older geographic data
(e.g. visits from India, Texas, Georgia) to silently disappear from the
aggregate totals.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-10 09:22:47 -04:00
nmemmertandClaude Sonnet 4.6 bf3154378b Track all link clicks (internal + external) in analytics; v1.1.33
Replaces outbound-only tracking with a useLinkClickTracking hook that
captures every <a> click on the site. Stores as link_click events keyed
by destination URL, with an internal flag. Admin analytics page gains a
Link Clicks table sorted by count, showing type (internal/external).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-10 09:11:53 -04:00
nmemmertandClaude Sonnet 4.6 abb4c87c41 Update runtime data: analytics events, episode plays, study user state
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-10 09:03:00 -04:00
nmemmertandClaude Sonnet 4.6 441b907ae1 Fancy 404 page with book icon, action buttons, and broken-link report form; v1.1.32
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-10 08:56:10 -04:00
nmemmertandClaude Sonnet 4.6 76239ee83b Fix redirects broken by service worker navigate fallback; v1.1.31
The SW's navigateFallback was using a denylist, so any path not explicitly
excluded (e.g. /spotify, /apple, /amazon, custom admin redirects) got served
the cached index.html instead of reaching the server's redirect handler.

Switch to navigateFallbackAllowlist: the SW only intercepts known SPA routes;
all other paths hit the network so server-side 301/302 redirects work correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-10 08:49:15 -04:00
nmemmert c56e468115 Revert "Add student birthday tracking with celebration banners and admin notification; v1.1.31"
This reverts commit c0a79b9ed0.
2026-08-10 08:43:53 -04:00
nmemmertandClaude Sonnet 4.6 c0a79b9ed0 Add student birthday tracking with celebration banners and admin notification; v1.1.31
- Admin can set birthday (month/day) per student in Study Users panel
- Summer birthdays (Jun–Aug) prompt admin to set an alternate school-year date
- 🎂 badge on student card header during birthday week
- Dismissible happy birthday banner shown to student on their study hub
- Admin receives email notification on the celebration day, once per year

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-10 08:42:52 -04:00
nmemmertandClaude Sonnet 4.6 6a4399f7a6 Fix missing queueStudyUsersWrite import causing crash-restart loop; v1.1.30
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-05 11:42:17 -04:00
nmemmertandClaude Sonnet 4.6 78f0988d75 Narrow reminder window to exact day to prevent re-fires on restart; v1.1.29
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-05 11:29:14 -04:00
nmemmertandClaude Sonnet 4.6 f53dcdec4f Add admin control for hero podcast art image; v1.1.28
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-05 11:18:49 -04:00
nmemmertandClaude Sonnet 4.6 4c9bbee58a Copy package.json into Docker runtime image so APP_VERSION reads correctly; v1.1.27
package.json was missing from the runtime stage, causing readPackageVersion()
to throw and fall back to 'unknown'. The git commit hash (from COMMIT_SHA env)
was the only identifier shown.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-29 08:12:42 -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 57fe34ba47 Make re-engagement email tiers configurable from admin; v1.1.20
Day thresholds and per-tier subject/body/CTA are now editable in the
Email Templates panel. Tier keys are position-based (t1/t2/t3) so
changing day values never re-sends emails already fired.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-28 16:13:25 -04:00
nmemmertandClaude Sonnet 4.6 2732730f5e Add study user re-engagement reminder emails; v1.1.19
Sends 7/14/30-day inactivity emails to study users who haven't logged in,
with one-click HMAC-signed unsubscribe and automatic re-arm on next login.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-28 15:56:09 -04:00
nmemmertandClaude Sonnet 4.6 d0c949070f Fix base64-encoded HTML email bodies not rendering; v1.1.18
Inbound emails from some clients (Outlook, mobile) send htmlBody as
base64. Decode it on the server before storing (future emails) and on
the client before passing to the iframe srcDoc (existing stored emails).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-28 12:28:21 -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