Private
Public Access
1
0

Fix account settings: add invalidateAll, robust error handling

- Add invalidateAll() after profile save so nav bar updates immediately
- Wrap all async handlers in try/finally to prevent stuck loading states
- Make form onsubmit handlers async to properly propagate errors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Catherine Renelle
2026-02-26 19:31:02 -05:00
parent 1419300baa
commit 5f552a9883
+36 -25
View File
@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import { api } from '$lib/utils/api.js'; import { api } from '$lib/utils/api.js';
import { toast } from '$lib/stores/toasts.svelte.js'; import { toast } from '$lib/stores/toasts.svelte.js';
import { invalidateAll } from '$app/navigation';
let { data } = $props(); let { data } = $props();
@@ -21,14 +22,18 @@
async function saveProfile() { async function saveProfile() {
savingProfile = true; savingProfile = true;
const result = await api('/api/account', { try {
method: 'PATCH', const result = await api('/api/account', {
body: JSON.stringify({ name: name.trim(), email: email.trim() }) method: 'PATCH',
}); body: JSON.stringify({ name: name.trim(), email: email.trim() })
savingProfile = false; });
if (result.ok) { if (result.ok) {
toast.success('Profile updated'); toast.success('Profile updated');
await invalidateAll();
}
} finally {
savingProfile = false;
} }
} }
@@ -39,29 +44,35 @@
} }
savingPassword = true; savingPassword = true;
const result = await api('/api/account', { try {
method: 'PATCH', const result = await api('/api/account', {
body: JSON.stringify({ currentPassword, newPassword }) method: 'PATCH',
}); body: JSON.stringify({ currentPassword, newPassword })
savingPassword = false; });
if (result.ok) { if (result.ok) {
currentPassword = ''; currentPassword = '';
newPassword = ''; newPassword = '';
confirmPassword = ''; confirmPassword = '';
sessionCount = 1; // only current session remains sessionCount = 1;
toast.success('Password changed. Other sessions have been logged out.'); toast.success('Password changed. Other sessions have been logged out.');
}
} finally {
savingPassword = false;
} }
} }
async function revokeOtherSessions() { async function revokeOtherSessions() {
revokingSessions = true; revokingSessions = true;
const result = await api('/api/account', { method: 'DELETE' }); try {
revokingSessions = false; const result = await api('/api/account', { method: 'DELETE' });
if (result.ok) { if (result.ok) {
sessionCount = 1; sessionCount = 1;
toast.success(`Logged out of ${result.data.sessionsRevoked} other session(s)`); toast.success(`Logged out of ${result.data.sessionsRevoked} other session(s)`);
}
} finally {
revokingSessions = false;
} }
} }
</script> </script>
@@ -77,7 +88,7 @@
<section class="mb-8"> <section class="mb-8">
<h2 class="text-lg font-semibold text-gray-800 dark:text-gray-200 mb-3">Profile</h2> <h2 class="text-lg font-semibold text-gray-800 dark:text-gray-200 mb-3">Profile</h2>
<div class="rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 p-4"> <div class="rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 p-4">
<form onsubmit={(e) => { e.preventDefault(); saveProfile(); }} class="space-y-3"> <form onsubmit={async (e) => { e.preventDefault(); await saveProfile(); }} class="space-y-3">
<div> <div>
<label for="profile-name" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Name</label> <label for="profile-name" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Name</label>
<input <input
@@ -113,7 +124,7 @@
<section class="mb-8"> <section class="mb-8">
<h2 class="text-lg font-semibold text-gray-800 dark:text-gray-200 mb-3">Change Password</h2> <h2 class="text-lg font-semibold text-gray-800 dark:text-gray-200 mb-3">Change Password</h2>
<div class="rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 p-4"> <div class="rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 p-4">
<form onsubmit={(e) => { e.preventDefault(); changePassword(); }} class="space-y-3"> <form onsubmit={async (e) => { e.preventDefault(); await changePassword(); }} class="space-y-3">
<div> <div>
<label for="current-password" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Current Password</label> <label for="current-password" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Current Password</label>
<input <input