fix: commit default campaign claim in ensure_admin_exists, surface setup errors to user
All checks were successful
Build and Push / build (push) Successful in 12m37s
All checks were successful
Build and Push / build (push) Successful in 12m37s
This commit is contained in:
@@ -102,6 +102,7 @@ def ensure_admin_exists():
|
|||||||
# Claim the "default" campaign for the admin so setup wizard works
|
# Claim the "default" campaign for the admin so setup wizard works
|
||||||
admin = db.get_user_by_username(ADMIN_USERNAME)
|
admin = db.get_user_by_username(ADMIN_USERNAME)
|
||||||
if admin:
|
if admin:
|
||||||
|
with db.tx():
|
||||||
conn.execute(
|
conn.execute(
|
||||||
"UPDATE campaigns SET created_by = ? WHERE id = 'default' AND created_by IS NULL",
|
"UPDATE campaigns SET created_by = ? WHERE id = 'default' AND created_by IS NULL",
|
||||||
(admin["id"],),
|
(admin["id"],),
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ const DEFAULT_SETTINGS: Record<string, string> = {
|
|||||||
export default function Setup({ onComplete }: { onComplete: () => void }) {
|
export default function Setup({ onComplete }: { onComplete: () => void }) {
|
||||||
const [step, setStep] = useState(1);
|
const [step, setStep] = useState(1);
|
||||||
const [settings, setSettings] = useState<Record<string, string>>(DEFAULT_SETTINGS);
|
const [settings, setSettings] = useState<Record<string, string>>(DEFAULT_SETTINGS);
|
||||||
|
const [saving, setSaving] = useState(false);
|
||||||
|
const [error, setError] = useState("");
|
||||||
|
|
||||||
// On first load, try to fetch existing settings from the "default" campaign
|
// On first load, try to fetch existing settings from the "default" campaign
|
||||||
// (which is always created by init_db).
|
// (which is always created by init_db).
|
||||||
@@ -36,9 +38,17 @@ export default function Setup({ onComplete }: { onComplete: () => void }) {
|
|||||||
const handleBack = () => setStep(prev => prev - 1);
|
const handleBack = () => setStep(prev => prev - 1);
|
||||||
|
|
||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
|
setSaving(true);
|
||||||
|
setError("");
|
||||||
|
try {
|
||||||
await api.updateCampaignSettings('default', settings);
|
await api.updateCampaignSettings('default', settings);
|
||||||
await api.updateSettings({ onboarding_completed: true });
|
await api.updateSettings({ onboarding_completed: true });
|
||||||
onComplete();
|
onComplete();
|
||||||
|
} catch (err: any) {
|
||||||
|
setError(err.message || "Failed to save settings");
|
||||||
|
} finally {
|
||||||
|
setSaving(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -213,12 +223,15 @@ export default function Setup({ onComplete }: { onComplete: () => void }) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{error && (
|
||||||
|
<div className="bg-red-900/50 border border-red-700 rounded px-4 py-3 text-red-200 text-sm">{error}</div>
|
||||||
|
)}
|
||||||
<div className="flex justify-between pt-4 border-t border-slate-700">
|
<div className="flex justify-between pt-4 border-t border-slate-700">
|
||||||
<button onClick={handleBack} className="bg-slate-700 hover:bg-slate-600 text-white px-5 py-2 rounded font-medium">
|
<button onClick={handleBack} disabled={saving} className="bg-slate-700 hover:bg-slate-600 disabled:opacity-50 text-white px-5 py-2 rounded font-medium">
|
||||||
Back
|
Back
|
||||||
</button>
|
</button>
|
||||||
<button onClick={handleSave} className="bg-emerald-600 hover:bg-emerald-500 text-white px-5 py-2 rounded font-medium">
|
<button onClick={handleSave} disabled={saving} className="bg-emerald-600 hover:bg-emerald-500 disabled:opacity-50 text-white px-5 py-2 rounded font-medium">
|
||||||
Complete Setup & Launch
|
{saving ? "Saving…" : "Complete Setup & Launch"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user