Podcast workflow: assign lanes by hand, match by season, unique keys for unseasoned episodes; drop old checklist data file; v2.16.0
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ac1b06f945
commit
900a3efee3
6 files changed
+69
-698
No files matched your search
+21
-2
@@ -1816,6 +1816,7 @@ interface PodcastWorkflowItem {
|
||||
episodeNumber: string
|
||||
title: string
|
||||
lane: 'A' | 'B' | 'other'
|
||||
laneOverride?: '' | 'A' | 'B' | 'other'
|
||||
released: boolean
|
||||
releaseDate?: string
|
||||
spotifyUrl?: string
|
||||
@@ -1874,7 +1875,7 @@ function PodcastWorkflowAdmin({ laneA, laneB }: { laneA: { title: string; season
|
||||
const r = await fetch('/api/admin/podcast-workflow/planned', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ season: laneSeason ? String(laneSeason) : '', episodeNumber: newNumber, title: newTitle }),
|
||||
body: JSON.stringify({ season: laneSeason ? String(laneSeason) : '', episodeNumber: newNumber, title: newTitle, lane }),
|
||||
})
|
||||
const d = await r.json()
|
||||
if (!r.ok) { setError(d.message ?? 'Could not add episode.'); return }
|
||||
@@ -1882,6 +1883,15 @@ function PodcastWorkflowAdmin({ laneA, laneB }: { laneA: { title: string; season
|
||||
await reload()
|
||||
setSelectedKey(d.key)
|
||||
}
|
||||
const setLaneFor = async (key: string, value: string) => {
|
||||
await fetch(`/api/admin/podcast-workflow/${encodeURIComponent(key)}/lane`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ lane: value }),
|
||||
})
|
||||
setSelectedKey('')
|
||||
reload()
|
||||
}
|
||||
const removePlanned = async (key: string) => {
|
||||
if (!confirm('Remove this planned episode and its progress?')) return
|
||||
await fetch(`/api/admin/podcast-workflow/planned/${encodeURIComponent(key)}`, { method: 'DELETE' })
|
||||
@@ -1932,7 +1942,7 @@ function PodcastWorkflowAdmin({ laneA, laneB }: { laneA: { title: string; season
|
||||
)}
|
||||
</div>
|
||||
{lane !== 'other' && !laneSeason && (
|
||||
<p className="admin-stats-note">Set this lane’s Podcast Season Number in Current Series so its episodes can be matched.</p>
|
||||
<p className="admin-stats-note">Set this lane’s Podcast Season Number in Current Series to match episodes automatically, or assign episodes to this lane by hand.</p>
|
||||
)}
|
||||
|
||||
{loading ? <p className="admin-stats-note">Loading…</p> : (
|
||||
@@ -1970,6 +1980,15 @@ function PodcastWorkflowAdmin({ laneA, laneB }: { laneA: { title: string; season
|
||||
{selected.hasScript ? 'Script uploaded.' : 'No script yet.'} This moves to Released on its own once it shows up in the feed.
|
||||
</p>
|
||||
)}
|
||||
<div className="admin-field" style={{ maxWidth: 360, margin: '8px 0 12px' }}>
|
||||
<label htmlFor="pw-lane">Lane</label>
|
||||
<select id="pw-lane" value={selected.laneOverride || 'auto'} onChange={e => setLaneFor(selected.key, e.target.value)}>
|
||||
<option value="auto">Automatic (by season number{selected.season ? ` ${selected.season}` : ''})</option>
|
||||
<option value="A">Lane A — {laneA.title || 'Primary series'}</option>
|
||||
<option value="B">Lane B — {laneB.title || 'Second series'}</option>
|
||||
<option value="other">Other</option>
|
||||
</select>
|
||||
</div>
|
||||
<ol style={{ paddingLeft: 0, listStyle: 'none', margin: 0 }}>
|
||||
{PODCAST_STEP_DEFS.map((s, idx) => {
|
||||
const completedAt = selected.state.steps[s.key]
|
||||
|
||||
Reference in new issue
Block a user