diff --git a/frontend/src/routes/admin/+page.svelte b/frontend/src/routes/admin/+page.svelte index dc17fa7..cd6bae2 100644 --- a/frontend/src/routes/admin/+page.svelte +++ b/frontend/src/routes/admin/+page.svelte @@ -139,26 +139,28 @@ addBusy = false; } } + // Merge the server-returned candidate (keeps status/updated_at/preview in sync) + // while preserving the transient UI-only fields (_cat/_activate/_err). async function repreviewCandidate(c) { c._err = ''; - try { const u = await postJSON(`/api/admin/candidates/${c.id}/preview`); c.preview = u.preview; } + try { Object.assign(c, await postJSON(`/api/admin/candidates/${c.id}/preview`)); } catch (e) { c._err = e?.message || 'Re-preview failed.'; } } async function promoteCandidate(c) { c._err = ''; try { - await postJSON(`/api/admin/candidates/${c.id}/promote`, { + const res = await postJSON(`/api/admin/candidates/${c.id}/promote`, { default_category: (c._cat || '').trim() || null, active: !!c._activate, }); - c.status = 'promoted'; + Object.assign(c, res.candidate); await loadStats(); // surface the new (paused) source in the table below } catch (e) { c._err = e?.message || 'Promote failed.'; } } async function rejectCandidate(c) { - try { await postJSON(`/api/admin/candidates/${c.id}/reject`); c.status = 'rejected'; } + try { Object.assign(c, await postJSON(`/api/admin/candidates/${c.id}/reject`)); } catch { /* leave as-is */ } }