Nuggets: optional link (e.g. YouTube) on host profiles; v2.47.0
Publish Container / build (push) Successful in 19m22s

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 5.5 committed 2026-10-29 08:50:17 -04:00
1 parent 03c3dd72fe
commit 327c3354dc
6 files changed
+20 -1

No files matched your search

+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "siteforge", "name": "siteforge",
"private": true, "private": true,
"version": "2.46.1", "version": "2.47.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
+2
View File
@@ -402,6 +402,8 @@ function sanitizeNuggets(raw) {
role: typeof h.role === 'string' ? h.role.trim().slice(0, 120) : '', role: typeof h.role === 'string' ? h.role.trim().slice(0, 120) : '',
bio: typeof h.bio === 'string' ? h.bio.trim().slice(0, 4000) : '', bio: typeof h.bio === 'string' ? h.bio.trim().slice(0, 4000) : '',
imageUrl: sanitizeUrl(h.imageUrl) || '', imageUrl: sanitizeUrl(h.imageUrl) || '',
linkUrl: sanitizeUrl(h.linkUrl) || '',
linkLabel: typeof h.linkLabel === 'string' ? h.linkLabel.trim().slice(0, 80) : '',
archived: Boolean(h.archived), archived: Boolean(h.archived),
})) }))
: [] : []
+8
View File
@@ -6706,6 +6706,14 @@ const [dashboardNow, setDashboardNow] = useState(() => new Date())
<label>Bio</label> <label>Bio</label>
<textarea rows={8} value={host.bio} onChange={e => updateHost(host.id, { bio: e.target.value })} /> <textarea rows={8} value={host.bio} onChange={e => updateHost(host.id, { bio: e.target.value })} />
</div> </div>
<div className="admin-field">
<label>Link URL (optional)</label>
<input type="url" placeholder="https://youtube.com/@channel" value={host.linkUrl ?? ''} onChange={e => updateHost(host.id, { linkUrl: e.target.value })} />
</div>
<div className="admin-field">
<label>Link Label (optional)</label>
<input type="text" placeholder="Watch more on YouTube" value={host.linkLabel ?? ''} onChange={e => updateHost(host.id, { linkLabel: e.target.value })} />
</div>
<div className="admin-field"> <div className="admin-field">
<label>Photo</label> <label>Photo</label>
<input type="text" placeholder="/uploads/host-photo.jpg" value={host.imageUrl} onChange={e => updateHost(host.id, { imageUrl: e.target.value })} /> <input type="text" placeholder="/uploads/host-photo.jpg" value={host.imageUrl} onChange={e => updateHost(host.id, { imageUrl: e.target.value })} />
+1
View File
@@ -14050,6 +14050,7 @@ a.nl-featured:hover { transform: translateY(-2px); border-color: rgba(201, 168,
.hd-name { font-family: var(--brand-font-heading); font-size: clamp(2rem, 5vw, 3rem); color: #f0e9cc; margin: 0.2rem 0 0; line-height: 1.1; } .hd-name { font-family: var(--brand-font-heading); font-size: clamp(2rem, 5vw, 3rem); color: #f0e9cc; margin: 0.2rem 0 0; line-height: 1.1; }
.hd-body { padding: 2.5rem 0 4rem; } .hd-body { padding: 2.5rem 0 4rem; }
.hd-body-inner { } .hd-body-inner { }
.hd-link { margin: 0 0 1.5rem; }
.hd-bio { font-size: 1.08rem; line-height: 1.75; color: #c9bf9a; margin: 0 0 1.25rem; } .hd-bio { font-size: 1.08rem; line-height: 1.75; color: #c9bf9a; margin: 0 0 1.25rem; }
.hd-listen { margin-top: 2rem; padding: 1.4rem 1.5rem; background: #111; border: 1px solid rgba(201, 168, 76, 0.2); border-radius: 14px; } .hd-listen { margin-top: 2rem; padding: 1.4rem 1.5rem; background: #111; border: 1px solid rgba(201, 168, 76, 0.2); border-radius: 14px; }
.hd-listen .eyebrow { margin-bottom: 0.8rem; } .hd-listen .eyebrow { margin-bottom: 0.8rem; }
+5
View File
@@ -2587,6 +2587,11 @@ function NuggetsHostDetailPage({ content }: { content: SiteContent }) {
{host.bio && host.bio.split(/\n\n+/).map((para, i) => ( {host.bio && host.bio.split(/\n\n+/).map((para, i) => (
<p key={i} className="hd-bio">{para.replace(/\n/g, ' ')}</p> <p key={i} className="hd-bio">{para.replace(/\n/g, ' ')}</p>
))} ))}
{host.linkUrl && (
<p className="hd-link">
<a href={host.linkUrl} target="_blank" rel="noopener noreferrer" className="btn-secondary">{host.linkLabel || 'Watch more'} &rarr;</a>
</p>
)}
{(nuggets.spotifyUrl || nuggets.appleUrl) && ( {(nuggets.spotifyUrl || nuggets.appleUrl) && (
<div className="hd-listen"> <div className="hd-listen">
<p className="eyebrow">Listen to {nuggets.title}</p> <p className="eyebrow">Listen to {nuggets.title}</p>
+3
View File
@@ -180,6 +180,9 @@ export interface PodcastHost {
role: string role: string
bio: string bio: string
imageUrl: string imageUrl: string
// Optional external link (e.g. a YouTube channel) shown on the host's profile
linkUrl?: string
linkLabel?: string
// Removed hosts are archived, never deleted — kept out of public display but // Removed hosts are archived, never deleted — kept out of public display but
// preserved so past-episode credits and history stay intact. // preserved so past-episode credits and history stay intact.
archived: boolean archived: boolean