From 4a68c782246bab6a9a4cd0e37b246faeb22c8876 Mon Sep 17 00:00:00 2001 From: mrjvs Date: Sun, 16 Aug 2026 14:45:39 +0200 Subject: [PATCH] feat: add loading indicators to every async action --- src/assets/css/auth.css | 2 +- src/assets/css/forgot-password.css | 131 -------------------------- src/pages/account/forgot-password.vue | 5 +- src/pages/account/index.vue | 31 +++--- src/pages/account/login.vue | 6 +- src/pages/account/register.vue | 5 +- src/pages/account/reset-password.vue | 5 +- src/pages/account/upgrade.vue | 32 ++++--- 8 files changed, 52 insertions(+), 165 deletions(-) delete mode 100644 src/assets/css/forgot-password.css diff --git a/src/assets/css/auth.css b/src/assets/css/auth.css index bf06e6f..e2598a3 100644 --- a/src/assets/css/auth.css +++ b/src/assets/css/auth.css @@ -33,7 +33,7 @@ form.account p { margin: 12px 0; } -form.account div { +form.account > div { margin-top: 24px; } diff --git a/src/assets/css/forgot-password.css b/src/assets/css/forgot-password.css deleted file mode 100644 index 337d3d0..0000000 --- a/src/assets/css/forgot-password.css +++ /dev/null @@ -1,131 +0,0 @@ -.account-form-wrapper { - height: 80vh; - display: flex; - justify-content: center; - align-content: center; - flex-direction: column; - margin: 15vh auto; - width: fit-content; - overflow: hidden; -} - -form.account { - display: block; - padding: 40px 48px; - background-color: var(--bg-shade-2); - color: var(--text-shade-1); - border-radius: 12px; - width: min(480px, 90vw); - box-sizing: border-box; -} - -form.account h2 { - margin: 0; - color: var(--text-shade-3); -} - -form.account p { - margin: 12px 0; -} - -form.account div { - margin-top: 24px; -} - -form.account label { - display: block; - margin-bottom: 6px; - text-transform: uppercase; - font-size: 12px; -} - -form.account button { - width: 100%; - background: var(--accent-shade-0); -} - -form.account a { - text-decoration: none; - display: block; - color: var(--text-shade-1); - text-align: right; - margin: 6px 0; - width: fit-content; -} -form.account a:hover { - color: var(--text-shade-3); -} - -form.account a.pwdreset { - margin-left: auto; - font-size: 14px; -} - -form.account a.register { - margin: auto; - margin-top: 18px; -} - -@keyframes banner-notice { - 0% { - top: -150px; - } - 20% { - top: 35px; - } - 80% { - top: 35px; - } - 100% { - top: -150px; - } -} -.banner-notice { - display: flex; - justify-content: center; - position: fixed; - top: -150px; - width: 100%; - animation: banner-notice 5s; -} -.banner-notice div { - padding: 4px 36px; - border-radius: 5px; - z-index: 3; -} -.banner-notice.success div { - background: var(--green-shade-0); -} -.banner-notice.error div { - background: var(--red-shade-1); -} - -form.account.register { - display: grid; - grid-template-columns: repeat(2, 1fr); - width: min(780px, 90vw); - column-gap: 24px; - margin-bottom: 48px; -} -form.account.forgot-password div.h-captcha { - grid-column: 1 / span 2; - display: flex; - justify-content: center; -} -form.account.register p, -form.account.register div.email, -form.account.register div.buttons { - grid-column: 1 / span 2; -} - -@media screen and (max-width: 720px) { - form.account.register { - grid-template-columns: 1fr; - } - form.account.register div.h-captcha, - form.account.register p, - form.account.register div.email, - form.account.register div.buttons { - grid-column: unset; - } -} \ No newline at end of file diff --git a/src/pages/account/forgot-password.vue b/src/pages/account/forgot-password.vue index 31a8a8f..d75473c 100644 --- a/src/pages/account/forgot-password.vue +++ b/src/pages/account/forgot-password.vue @@ -7,7 +7,7 @@ const captchaRef = useTemplateRef('captcha'); const form = reactive({ emailOrUsername: '' }); -const { execute } = useAsync({ +const { execute, isLoading } = useAsync({ async handler() { let captchaResponse: string | null = null; if (captchaRef.value) { @@ -68,7 +68,8 @@ const { execute } = useAsync({ />
diff --git a/src/pages/account/index.vue b/src/pages/account/index.vue index e758a63..d6dccac 100644 --- a/src/pages/account/index.vue +++ b/src/pages/account/index.vue @@ -39,7 +39,7 @@ const dialogContainer = ref(null); const deleteModalOpen = ref(false); const editModalOpen = ref(false); -const { execute: executeUpdateServerEnvironment } = useAsync({ +const { execute: executeUpdateServerEnvironment, isLoading: isLoadingUpdateServerEnv } = useAsync({ async handler(env: ApiAccountUpdateRequest['environment']) { await apiFetch('/api/account/update', { method: 'PATCH', @@ -58,7 +58,7 @@ const { execute: executeUpdateServerEnvironment } = useAsync({ } }); -const { execute: executeDeleteAccount } = useAsync({ +const { execute: executeDeleteAccount, isLoading: isLoadingDelete } = useAsync({ async handler() { await apiFetch('/api/account/delete', { method: 'POST' @@ -75,7 +75,7 @@ const { execute: executeDeleteAccount } = useAsync({ } }); -const { execute: executeLinkDiscord } = useAsync({ +const { execute: executeLinkDiscord, isLoading: isLoadingLink } = useAsync({ async handler() { const result = await apiFetch('/api/account/discord-link', { method: 'GET' @@ -91,7 +91,7 @@ const { execute: executeLinkDiscord } = useAsync({ } }); -const { execute: executeUnlinkDiscord } = useAsync({ +const { execute: executeUnlinkDiscord, isLoading: isLoadingUnlink } = useAsync({ async handler() { await apiFetch('/api/account/discord-unlink', { method: 'POST' @@ -194,15 +194,19 @@ useHead({

@@ -338,7 +342,8 @@ useHead({ class="button secondary" @click.prevent="() => executeUpdateServerEnvironment(selectedServerEnv)" > - Save + + Save

- {{ $t("account.settings.settingCards.removeDiscord") }} + + {{ $t("account.settings.settingCards.removeDiscord") }}

{{ $t("account.settings.settingCards.noDiscordLinked") }} @@ -433,7 +439,8 @@ useHead({ :style="{cursor: 'pointer'}" @click="executeLinkDiscord" > - {{ $t("account.settings.settingCards.linkDiscord") }} + + {{ $t("account.settings.settingCards.linkDiscord") }}

diff --git a/src/pages/account/login.vue b/src/pages/account/login.vue index 0e824c1..a495277 100644 --- a/src/pages/account/login.vue +++ b/src/pages/account/login.vue @@ -16,7 +16,7 @@ const registerURI = computed(() => { const loginForm = reactive({ username: '', password: '' }); -const { execute } = useAsync({ +const { execute, isLoading } = useAsync({ async handler() { const res = await $fetch('/api/auth/login', { method: 'POST', @@ -75,8 +75,8 @@ const { execute } = useAsync({
{ const registerForm = reactive({ email: '', username: '', mii_name: '', password: '', password_confirm: '' }); const captchaRef = useTemplateRef('captcha'); -const { execute } = useAsync({ +const { execute, isLoading } = useAsync({ async handler() { let captchaResponse: string | null = null; if (captchaRef.value) { @@ -128,7 +128,8 @@ const { execute } = useAsync({ />
diff --git a/src/pages/account/upgrade.vue b/src/pages/account/upgrade.vue index 7bf9a20..445e538 100644 --- a/src/pages/account/upgrade.vue +++ b/src/pages/account/upgrade.vue @@ -1,7 +1,6 @@