diff --git a/data/analytics-events.json b/data/analytics-events.json index bdd0bde..87db1ef 100644 --- a/data/analytics-events.json +++ b/data/analytics-events.json @@ -5,12 +5,24 @@ "50": 4, "75": 2, "90": 0 + }, + "/": { + "25": 2, + "50": 2, + "75": 2, + "90": 2 + }, + "/about": { + "25": 6, + "50": 6, + "75": 6, + "90": 6 } }, "timeOnPage": { "/": { - "totalSeconds": 51, - "count": 4 + "totalSeconds": 64, + "count": 5 }, "/episodes": { "totalSeconds": 318967, @@ -19,10 +31,27 @@ "/episodes/movn6tk3": { "totalSeconds": 445, "count": 3 + }, + "/about": { + "totalSeconds": 63497, + "count": 128 } }, "outboundClicks": {}, - "linkClicks": {}, + "linkClicks": { + "https://ko-fi.com/versebyversewithnate": { + "count": 1, + "internal": false + }, + "/": { + "count": 1, + "internal": true + }, + "/about": { + "count": 1, + "internal": true + } + }, "utmSources": {}, "searchQueries": {}, "notFound": {}, diff --git a/data/study-reminders.json b/data/study-reminders.json index aa12d92..979f5c8 100644 --- a/data/study-reminders.json +++ b/data/study-reminders.json @@ -1,4 +1,4 @@ { "users": {}, - "updatedAt": "2026-08-26T15:41:55.120Z" + "updatedAt": "2026-09-02T17:00:36.458Z" } \ No newline at end of file diff --git a/package.json b/package.json index 0bc9bd9..8fd49ba 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "siteforge", "private": true, - "version": "1.1.48", + "version": "1.1.49", "type": "module", "scripts": { "dev": "vite", diff --git a/server.js b/server.js index 2f659f7..6536faa 100644 --- a/server.js +++ b/server.js @@ -196,6 +196,6 @@ Promise.all([ app.listen(PORT, () => { logResendEmailAlignmentWarnings() - console.log(`Portfolio app listening on http://localhost:${PORT}`) + console.log(`Siteforge listening on http://localhost:${PORT}`) }) }) diff --git a/src/AdminPage.tsx b/src/AdminPage.tsx index d0f66fa..22cd919 100644 --- a/src/AdminPage.tsx +++ b/src/AdminPage.tsx @@ -728,7 +728,7 @@ const ADMIN_VIEW_OPTIONS: Array<{ group: string; options: Array<{ value: AdminVi options: [ { value: 'podcast', label: 'Podcast Hub' }, { value: 'colossians-study', label: 'Studies' }, - { value: 'downloads', label: 'Downloads' }, + { value: 'downloads', label: 'Resources' }, { value: 'custom-links', label: 'Custom Links' }, { value: 'content-blocks', label: 'Content Blocks' }, { value: 'books', label: 'Books' }, @@ -798,7 +798,6 @@ const ADMIN_SECTION_LINKS: Partial> = { downloads: [ { id: 'downloads-study-guide', label: 'Study Guide' }, { id: 'downloads-library', label: 'Download Library' }, - { id: 'downloads-previous-studies', label: 'Previous Studies' }, ], global: [ { id: 'global-footer', label: 'Footer' }, @@ -903,7 +902,7 @@ const FIELDS: Array<{ key: StringField; label: string; multiline?: boolean; sect { key: 'seriesImageUrl', label: 'Series Cover Image URL', section: 'series' }, { key: 'seriesListenUrl', label: 'Series Listen URL', section: 'series' }, { key: 'seriesListenBtnLabel', label: 'Series — Listen Button Label', section: 'series' }, - { key: 'seriesDownloadsBtnLabel', label: 'Series — Downloads Button Label', section: 'series' }, + { key: 'seriesDownloadsBtnLabel', label: 'Series — Resources Button Label', section: 'series' }, { key: 'studyGuideTitle', label: 'Study Guide Title', section: 'series' }, { key: 'studyGuideDescription', label: 'Study Guide Description', multiline: true, section: 'series' }, { key: 'studyGuideUrl', label: 'Study Guide URL (Amazon link)', section: 'series' }, @@ -2000,9 +1999,9 @@ async function handleAssetUpload(event: ChangeEvent) { if (placement === 'footer') return 'Footer navigation links' if (placement === 'otherSites') return 'Other site links in footer dropdown' if (placement === 'externalSites') return 'Homepage external site links' - if (placement === 'books') return 'Downloads page (Reading List)' - if (placement === 'recommended') return 'Downloads page (Recommended Resources)' - return 'Downloads page (More Resources)' + if (placement === 'books') return 'Resources page (Reading List)' + if (placement === 'recommended') return 'Resources page (Recommended Resources)' + return 'Resources page (More Resources)' } function getCustomLinkPreviewPath(placement: CustomLink['placement']) { @@ -2016,7 +2015,7 @@ async function handleAssetUpload(event: ChangeEvent) { if (page === 'homepage') return 'Homepage' if (page === 'start-here') return 'Start Here' if (page === 'episodes') return 'Episodes' - if (page === 'downloads') return 'Downloads' + if (page === 'downloads') return 'Resources' if (page === 'about') return 'About' if (page === 'contact') return 'Contact' return 'Q&A' @@ -2832,8 +2831,8 @@ async function handleAssetUpload(event: ChangeEvent) {
-
{downloadStats['titus-study'] ?? 0}
-
Titus Study Downloads
+
{Math.max(0, ...Object.values(downloadStats))}
+
Top Resource Downloads
{Object.values(downloadStats).reduce((a, b) => a + b, 0)} total resource downloads
@@ -2864,7 +2863,7 @@ async function handleAssetUpload(event: ChangeEvent) { {c.message &&
{c.message.slice(0, 100)}{c.message.length > 100 ? '…' : ''}
}
))} - View All Contacts → + ) } @@ -3341,7 +3340,7 @@ async function handleAssetUpload(event: ChangeEvent) { )} ))} -

Companion study guide title, description, and Amazon link are now managed in Downloads.

+

Companion study guide title, description, and Amazon link are now managed in Resources.

{renderSaveStatus()}

@@ -3520,7 +3519,7 @@ async function handleAssetUpload(event: ChangeEvent) { {adminView === 'downloads' && (
-

Downloads

+

Resources

Manage the featured study guide, current download library, and previous series downloads.

@@ -3533,7 +3532,7 @@ async function handleAssetUpload(event: ChangeEvent) {

Companion Study Guide

-

This is the featured primary download at the top of the Downloads page.

+

This is the featured primary download at the top of the Resources page.

@@ -3782,7 +3781,7 @@ async function handleAssetUpload(event: ChangeEvent) {

More Resources Links

-

These create cards in Downloads → More guides, worksheets, and past study downloads.

+

These create cards in Resources → More guides, worksheets, and past study downloads.

{(form.customLinks ?? []).filter(link => link.placement === 'resources').length === 0 && (

No resource links yet.

@@ -3863,7 +3862,7 @@ async function handleAssetUpload(event: ChangeEvent) { - + @@ -3901,7 +3900,7 @@ async function handleAssetUpload(event: ChangeEvent) {

Books

-

Amazon books shown in the Reading List section on the Downloads page. Add a cover image, description, and Amazon link for each book.

+

Amazon books shown in the Reading List section on the Resources page. Add a cover image, description, and Amazon link for each book.

{(form.customLinks ?? []).filter(l => l.placement === 'books').length === 0 &&

No books yet.

} {(form.customLinks ?? []).filter(l => l.placement === 'books').map(book => ( @@ -3955,7 +3954,7 @@ async function handleAssetUpload(event: ChangeEvent) {

Recommended Resources

-

Curated resources shown at the bottom of the Downloads page. When at least one is added, it replaces the default Truth For Life widget. Add a title, image, link, and description for each resource.

+

Curated resources shown at the bottom of the Resources page. When at least one is added, it replaces the default Truth For Life widget. Add a title, image, link, and description for each resource.

{(form.customLinks ?? []).filter(l => l.placement === 'recommended').length === 0 && (

No custom recommended resources yet — the Truth For Life widget shows by default.

diff --git a/src/App.tsx b/src/App.tsx index 4277d0c..c70431c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -428,7 +428,7 @@ function SiteHeader({ content }: { content: SiteContent }) { `header-nav-link${isActive ? ' header-nav-link--active' : ''}`} onClick={() => setMenuOpen(false)}>Q&A `header-nav-link${isActive ? ' header-nav-link--active' : ''}`} onClick={() => setMenuOpen(false)}>Studies `header-nav-link${isActive ? ' header-nav-link--active' : ''}`} onClick={() => setMenuOpen(false)}>My Account - `header-nav-link${isActive ? ' header-nav-link--active' : ''}`} onClick={() => setMenuOpen(false)}>Downloads + `header-nav-link${isActive ? ' header-nav-link--active' : ''}`} onClick={() => setMenuOpen(false)}>Resources `header-nav-link${isActive ? ' header-nav-link--active' : ''}`} onClick={() => setMenuOpen(false)}>About `header-nav-link${isActive ? ' header-nav-link--active' : ''}`} onClick={() => setMenuOpen(false)}>Contact Finished Books + Newsletter + Privacy Policy Terms @@ -601,6 +603,7 @@ function AboutSection({ content }: { content: SiteContent }) {
+ {content.aboutShowEyebrow &&

{content.aboutShowEyebrow}

}

{content.aboutShowHeading}

{content.aboutShowP1}

{content.aboutShowP2}

@@ -841,7 +844,7 @@ function DownloadLibrarySection({ content }: { content: SiteContent }) { ))}
) : ( -

No downloads tagged "{activeTag}".

+

No resources tagged "{activeTag}".

)} )} @@ -853,15 +856,20 @@ function DownloadLibrarySection({ content }: { content: SiteContent }) { function DownloadDetailPage({ content }: { content: SiteContent }) { const { id } = useParams<{ id: string }>() const resource = resolveDownloadPageResource(content, id) + const siteTitle = content.seo?.title || DEFAULTS.seo.title + usePageMeta( + resource ? `${resource.label} | ${siteTitle}` : `Resource | ${siteTitle}`, + resource?.summary || 'Free study guides and resources from Verse by Verse with Nate.', + ) if (!resource) { return (
-

Downloads

+

Resources

Download not found

The download you requested is not available right now.

- Back to Downloads + Back to Resources
) @@ -870,7 +878,7 @@ function DownloadDetailPage({ content }: { content: SiteContent }) { return (
@@ -1289,7 +1297,7 @@ function LandingPage({ content }: { content: SiteContent }) { {content.seriesListenBtnLabel || 'Listen to Series'} - {content.seriesDownloadsBtnLabel || 'View Downloads'} + {content.seriesDownloadsBtnLabel || 'View Resources'} @@ -1422,6 +1430,12 @@ function EpisodeDetailPage({ content }: { content: SiteContent }) { } }, [episode]) + const siteTitle = content.seo?.title || DEFAULTS.seo.title + usePageMeta( + episode ? `${episode.title} | ${siteTitle}` : `Episode | ${siteTitle}`, + episode?.summary || 'Expository Bible teaching from Verse by Verse with Nate.', + ) + if (!episode) { return (
@@ -1894,14 +1908,14 @@ function BooksAndResourcesSection({ content }: { content: SiteContent }) { function ResourcesPage({ content }: { content: SiteContent }) { const siteTitle = content.seo?.title || DEFAULTS.seo.title usePageMeta( - `Resources & Downloads | ${siteTitle}`, + `Resources | ${siteTitle}`, 'Study guides, sermon notes, and free resources from Verse by Verse with Nate.', ) return (
- + @@ -1933,12 +1947,18 @@ function AboutPage({ content }: { content: SiteContent }) { } function ContactPage({ content }: { content: SiteContent }) { + const siteTitle = content.seo?.title || DEFAULTS.seo.title + usePageMeta( + `Contact | ${siteTitle}`, + 'Get in touch with Nate — submit a Bible question, testimony, or topic request.', + ) return (
- + + @@ -1947,38 +1967,49 @@ function ContactPage({ content }: { content: SiteContent }) { } function StartHerePage({ content }: { content: SiteContent }) { + const siteTitle = content.seo?.title || DEFAULTS.seo.title + usePageMeta( + `Start Here | ${siteTitle}`, + content.startHereIntro || 'A beginner\'s guide to Verse by Verse with Nate.', + ) return ( -
-
-

Verse by Verse with Nate

-

{content.startHereHeading}

-

- {content.startHereIntro} -

+
+ + +
+
+

Verse by Verse with Nate

+

{content.startHereHeading}

+

+ {content.startHereIntro} +

-
-
-

{content.startHereStep1Title}

-

{content.startHereStep1Body}

- {content.startHereStep1Cta} -
- -
-

{content.startHereStep3Title}

-

{content.startHereStep3Body}

- {content.startHereStep3Cta} -
-
+
+
+

{content.startHereStep1Title}

+

{content.startHereStep1Body}

+ {content.startHereStep1Cta} +
+
+

{content.startHereStep2Title}

+

{content.startHereStep2Body}

+ {content.startHereStep2Cta} +
+
+

{content.startHereStep3Title}

+

{content.startHereStep3Body}

+ {content.startHereStep3Cta} +
+
-
- Back to Site +
+ Back to Site +
-
-
+
+ + +
) } @@ -2664,8 +2695,7 @@ export default function App() { } /> } /> } />} /> - } />} /> - } />} /> + } />} /> } />} /> } />} /> } />} /> diff --git a/src/content.ts b/src/content.ts index fbf9f64..fc6ace5 100644 --- a/src/content.ts +++ b/src/content.ts @@ -336,7 +336,7 @@ export const DEFAULTS: SiteContent = { seriesImageUrl: '/images/titus-cover.png', seriesListenUrl: '/spotify', seriesListenBtnLabel: 'Listen to Series', - seriesDownloadsBtnLabel: 'View Downloads', + seriesDownloadsBtnLabel: 'View Resources', studyGuideTitle: 'Companion Study Guide', studyGuideDescription: 'Go deeper in your study with the official Verse by Verse companion guide — now available on Amazon.', @@ -402,7 +402,7 @@ export const DEFAULTS: SiteContent = { whereToNextHeading: 'Choose the page you need.', whereToNextCards: [ { id: 'episodes', title: 'Episodes', description: 'Listen to latest episodes and platform links.', path: '/episodes' }, - { id: 'downloads', title: 'Downloads', description: 'Main guide, extra downloads, and past study files.', path: '/resources' }, + { id: 'downloads', title: 'Resources', description: 'Main guide, extra downloads, and past study files.', path: '/resources' }, { id: 'qa', title: 'Q&A', description: 'Browse Bible questions and approved answers.', path: '/questions' }, { id: 'about', title: 'About', description: 'Learn about Nate and the mission of the show.', path: '/about' }, { id: 'contact', title: 'Contact', description: 'Submit a Bible question, testimony, or topic.', path: '/contact' },