Add per-download Amazon button settings for current and archived downloads
This commit is contained in:
+33
-1
@@ -993,7 +993,7 @@ export default function AdminPage({ content, onSave, onLogout }: Props) {
|
||||
...series,
|
||||
resourceLinks: [
|
||||
...(series.resourceLinks ?? []),
|
||||
{ id: `${seriesId}-${Date.now().toString(36)}`, label: '', description: '', url: '' },
|
||||
{ id: `${seriesId}-${Date.now().toString(36)}`, label: '', description: '', url: '', amazonUrl: '', amazonLabel: '' },
|
||||
],
|
||||
}
|
||||
: series),
|
||||
@@ -1048,6 +1048,8 @@ export default function AdminPage({ content, onSave, onLogout }: Props) {
|
||||
label: source.label,
|
||||
description: source.description ?? '',
|
||||
url: source.url,
|
||||
amazonUrl: source.amazonUrl ?? '',
|
||||
amazonLabel: source.amazonLabel ?? '',
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -1075,6 +1077,8 @@ export default function AdminPage({ content, onSave, onLogout }: Props) {
|
||||
label: link.label,
|
||||
description: link.description ?? '',
|
||||
url: link.url,
|
||||
amazonUrl: link.amazonUrl ?? '',
|
||||
amazonLabel: link.amazonLabel ?? '',
|
||||
}))
|
||||
|
||||
if (toAdd.length === 0) return series
|
||||
@@ -1646,6 +1650,14 @@ export default function AdminPage({ content, onSave, onLogout }: Props) {
|
||||
<label htmlFor={`archive-link-url-${link.id}`}>URL</label>
|
||||
<input id={`archive-link-url-${link.id}`} type="url" value={link.url} placeholder="https://..." onChange={e => updateArchivedSeriesLink(series.id, link.id, 'url', e.target.value)} />
|
||||
</div>
|
||||
<div className="admin-field">
|
||||
<label htmlFor={`archive-link-amazon-url-${link.id}`}>Amazon URL (optional)</label>
|
||||
<input id={`archive-link-amazon-url-${link.id}`} type="url" value={link.amazonUrl ?? ''} placeholder="https://amazon.com/..." onChange={e => updateArchivedSeriesLink(series.id, link.id, 'amazonUrl', e.target.value)} />
|
||||
</div>
|
||||
<div className="admin-field">
|
||||
<label htmlFor={`archive-link-amazon-label-${link.id}`}>Amazon Button Label</label>
|
||||
<input id={`archive-link-amazon-label-${link.id}`} type="text" value={link.amazonLabel ?? ''} placeholder="Get it on Amazon" onChange={e => updateArchivedSeriesLink(series.id, link.id, 'amazonLabel', e.target.value)} />
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" className="btn-admin-remove" onClick={() => removeArchivedSeriesLink(series.id, link.id)}>Remove</button>
|
||||
</div>
|
||||
@@ -1724,6 +1736,10 @@ export default function AdminPage({ content, onSave, onLogout }: Props) {
|
||||
<label htmlFor="resources-study-guide-url">Printed Copy URL (Amazon button)</label>
|
||||
<input id="resources-study-guide-url" type="url" value={form.studyGuideUrl} placeholder="https://..." onChange={e => handleChange('studyGuideUrl', e.target.value)} />
|
||||
</div>
|
||||
<div className="admin-field">
|
||||
<label htmlFor="resources-study-guide-amazon-label">Amazon Button Label</label>
|
||||
<input id="resources-study-guide-amazon-label" type="text" value={form.studyGuideAmazonButtonLabel} placeholder="Get it on Amazon" onChange={e => handleChange('studyGuideAmazonButtonLabel', e.target.value)} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1756,6 +1772,14 @@ export default function AdminPage({ content, onSave, onLogout }: Props) {
|
||||
<label htmlFor={`resource-description-${link.id}`}>Description</label>
|
||||
<textarea id={`resource-description-${link.id}`} rows={3} value={link.description ?? ''} placeholder="Description shown on the download page" onChange={e => updateLink(link.id, 'description', e.target.value)} />
|
||||
</div>
|
||||
<div className="admin-field">
|
||||
<label htmlFor={`resource-amazon-url-${link.id}`}>Amazon URL (optional)</label>
|
||||
<input id={`resource-amazon-url-${link.id}`} type="url" value={link.amazonUrl ?? ''} placeholder="https://amazon.com/..." onChange={e => updateLink(link.id, 'amazonUrl', e.target.value)} />
|
||||
</div>
|
||||
<div className="admin-field">
|
||||
<label htmlFor={`resource-amazon-label-${link.id}`}>Amazon Button Label</label>
|
||||
<input id={`resource-amazon-label-${link.id}`} type="text" value={link.amazonLabel ?? ''} placeholder="Get it on Amazon" onChange={e => updateLink(link.id, 'amazonLabel', e.target.value)} />
|
||||
</div>
|
||||
<div className="admin-field">
|
||||
<label htmlFor={`resource-image-${link.id}`}>Image URL</label>
|
||||
<input id={`resource-image-${link.id}`} type="text" value={link.imageUrl ?? ''} placeholder="/uploads/example.png" onChange={e => updateLink(link.id, 'imageUrl', e.target.value)} />
|
||||
@@ -1820,6 +1844,14 @@ export default function AdminPage({ content, onSave, onLogout }: Props) {
|
||||
<label htmlFor={`resources-archive-link-description-${link.id}`}>Description</label>
|
||||
<textarea id={`resources-archive-link-description-${link.id}`} rows={3} value={link.description ?? ''} placeholder="Description shown on the download page" onChange={e => updateArchivedSeriesLink(series.id, link.id, 'description', e.target.value)} />
|
||||
</div>
|
||||
<div className="admin-field">
|
||||
<label htmlFor={`resources-archive-link-amazon-url-${link.id}`}>Amazon URL (optional)</label>
|
||||
<input id={`resources-archive-link-amazon-url-${link.id}`} type="url" value={link.amazonUrl ?? ''} placeholder="https://amazon.com/..." onChange={e => updateArchivedSeriesLink(series.id, link.id, 'amazonUrl', e.target.value)} />
|
||||
</div>
|
||||
<div className="admin-field">
|
||||
<label htmlFor={`resources-archive-link-amazon-label-${link.id}`}>Amazon Button Label</label>
|
||||
<input id={`resources-archive-link-amazon-label-${link.id}`} type="text" value={link.amazonLabel ?? ''} placeholder="Get it on Amazon" onChange={e => updateArchivedSeriesLink(series.id, link.id, 'amazonLabel', e.target.value)} />
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" className="btn-admin-remove" onClick={() => removeArchivedSeriesLink(series.id, link.id)}>Remove</button>
|
||||
</div>
|
||||
|
||||
+12
-1
@@ -281,6 +281,8 @@ interface DownloadPageResource {
|
||||
tags: string[]
|
||||
buttonText: string
|
||||
resourceId: string
|
||||
amazonUrl?: string
|
||||
amazonLabel?: string
|
||||
}
|
||||
|
||||
function resolveDownloadPageResource(content: SiteContent, pageId: string | undefined): DownloadPageResource | null {
|
||||
@@ -299,6 +301,8 @@ function resolveDownloadPageResource(content: SiteContent, pageId: string | unde
|
||||
tags: resource.tags ?? [],
|
||||
buttonText: `Download ${resource.label}`,
|
||||
resourceId: buildCustomResourceDownloadId(resource.id),
|
||||
amazonUrl: resource.amazonUrl,
|
||||
amazonLabel: resource.amazonLabel,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,6 +320,8 @@ function resolveDownloadPageResource(content: SiteContent, pageId: string | unde
|
||||
tags: [],
|
||||
buttonText: `Download ${link.label || series.title || 'Resource'}`,
|
||||
resourceId: buildArchivedResourceDownloadId(series.id, link.id),
|
||||
amazonUrl: link.amazonUrl,
|
||||
amazonLabel: link.amazonLabel,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -587,7 +593,7 @@ function StudyGuideSection({ content }: { content: SiteContent }) {
|
||||
rel="noreferrer"
|
||||
className="btn-secondary"
|
||||
>
|
||||
Get Printed Copy on Amazon
|
||||
{content.studyGuideAmazonButtonLabel || 'Get it on Amazon'}
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
@@ -819,6 +825,11 @@ function DownloadDetailPage({ content }: { content: SiteContent }) {
|
||||
</div>
|
||||
|
||||
<div className="download-detail-actions">
|
||||
{resource.amazonUrl && (
|
||||
<a href={resource.amazonUrl} target="_blank" rel="noreferrer" className="btn-secondary">
|
||||
{resource.amazonLabel || 'Get it on Amazon'}
|
||||
</a>
|
||||
)}
|
||||
<Link to="/resources" className="btn-secondary">Back to Downloads</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,6 +5,8 @@ export interface CustomLink {
|
||||
placement: 'platforms' | 'footer' | 'resources'
|
||||
imageUrl?: string
|
||||
description?: string
|
||||
amazonUrl?: string
|
||||
amazonLabel?: string
|
||||
tags?: string[]
|
||||
}
|
||||
|
||||
@@ -27,6 +29,8 @@ export interface ArchivedSeriesResourceLink {
|
||||
label: string
|
||||
description?: string
|
||||
url: string
|
||||
amazonUrl?: string
|
||||
amazonLabel?: string
|
||||
}
|
||||
|
||||
export interface ArchivedSeriesNote {
|
||||
@@ -140,6 +144,7 @@ export interface SiteContent {
|
||||
studyGuideDescription: string
|
||||
studyGuideDownloadUrl: string
|
||||
studyGuideUrl: string
|
||||
studyGuideAmazonButtonLabel: string
|
||||
// ── Share ──
|
||||
shareHeading: string
|
||||
shareP: string
|
||||
@@ -250,6 +255,7 @@ export const DEFAULTS: SiteContent = {
|
||||
'Go deeper in your study with the official Verse by Verse companion guide — now available on Amazon.',
|
||||
studyGuideDownloadUrl: '',
|
||||
studyGuideUrl: 'https://a.co/d/01sG2tOJ',
|
||||
studyGuideAmazonButtonLabel: 'Get it on Amazon',
|
||||
shareHeading: 'Help one more person hear the Word this week.',
|
||||
shareP: 'Scan the QR code or text the show link to a friend who needs encouragement today.',
|
||||
whereToNextEyebrow: 'Where to Next',
|
||||
|
||||
Reference in New Issue
Block a user