From daa199dfb093b905d686b3083ba08e6308b182d0 Mon Sep 17 00:00:00 2001 From: Ravinou Date: Mon, 21 Apr 2025 11:57:22 +0200 Subject: [PATCH] =?UTF-8?q?refactor:=20=E2=9A=A1=20remove=20spinners=20for?= =?UTF-8?q?=20nprogress?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Components/UI/Switch/Switch.tsx | 39 ++++---- Containers/RepoManage/RepoManage.tsx | 98 ++++++++++--------- .../AppriseAlertSettings.tsx | 54 ++++------ .../AppriseMode/AppriseMode.tsx | 35 +++---- .../AppriseURLs/AppriseURLs.tsx | 27 ++--- .../EmailAlertSettings/EmailAlertSettings.tsx | 31 +++--- .../EmailSettings/EmailSettings.tsx | 21 ++-- .../Integrations/Integrations.tsx | 46 ++++----- .../PasswordSettings/PasswordSettings.tsx | 42 +++----- .../UsernameSettings/UsernameSettings.tsx | 35 +++---- pages/api/v1/notif/apprise/test.ts | 2 +- pages/login.tsx | 14 +-- 12 files changed, 202 insertions(+), 242 deletions(-) diff --git a/Components/UI/Switch/Switch.tsx b/Components/UI/Switch/Switch.tsx index fe1531a..f32fa42 100644 --- a/Components/UI/Switch/Switch.tsx +++ b/Components/UI/Switch/Switch.tsx @@ -1,6 +1,7 @@ import { Optional } from '~/types'; import classes from './Switch.module.css'; -import { SpinnerCircularFixed } from 'spinners-react'; +import { useLoader } from '~/contexts/LoaderContext'; +import { useEffect } from 'react'; type SwitchProps = { switchName: string; @@ -12,29 +13,29 @@ type SwitchProps = { }; export default function Switch(props: SwitchProps) { + const { start, stop } = useLoader(); + + useEffect(() => { + if (props.loading) { + start(); + } else { + stop(); + } + }, [props.loading, start, stop]); + return (
diff --git a/Containers/RepoManage/RepoManage.tsx b/Containers/RepoManage/RepoManage.tsx index 6ee7407..6bd4f8b 100644 --- a/Containers/RepoManage/RepoManage.tsx +++ b/Containers/RepoManage/RepoManage.tsx @@ -1,15 +1,14 @@ -import classes from './RepoManage.module.css'; -import { IconAlertCircle, IconX } from '@tabler/icons-react'; -import { useState } from 'react'; +import { IconAlertCircle, IconExternalLink, IconX } from '@tabler/icons-react'; +import Link from 'next/link'; import { useRouter } from 'next/router'; +import { useState } from 'react'; +import { Controller, useForm } from 'react-hook-form'; +import Select from 'react-select'; import { toast, ToastOptions } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; -import { useForm, Controller } from 'react-hook-form'; -import { SpinnerDotted } from 'spinners-react'; -import Select from 'react-select'; -import Link from 'next/link'; -import { IconExternalLink } from '@tabler/icons-react'; -import { alertOptions, Repository, Optional } from '~/types'; +import { useLoader } from '~/contexts/LoaderContext'; +import { alertOptions, Optional, Repository } from '~/types'; +import classes from './RepoManage.module.css'; type RepoManageProps = { mode: 'add' | 'edit'; @@ -53,20 +52,25 @@ export default function RepoManage(props: RepoManageProps) { const [deleteDialog, setDeleteDialog] = useState(false); const [isLoading, setIsLoading] = useState(false); + const { start, stop } = useLoader(); //router.query.slug is undefined for few milliseconds on first render for a direct URL access (https://github.com/vercel/next.js/discussions/11484). //If I call repoManage with edit mode (props), i'm firstly waiting that router.query.slug being available before rendering. if (props.mode === 'edit') { if (!router.query.slug) { - return ; + start(); + return; } else if (!targetRepo) { + stop(); router.push('/404'); } } //Delete a repo const deleteHandler = async (repositoryName?: string) => { + start(); if (!repositoryName) { + stop(); toast.error('Repository name not found', toastOptions); router.replace('/'); return; @@ -105,6 +109,9 @@ export default function RepoManage(props: RepoManageProps) { toast.error('An error has occurred', toastOptions); router.replace('/'); console.log(error); + }) + .finally(() => { + stop(); }); }; @@ -141,10 +148,11 @@ export default function RepoManage(props: RepoManageProps) { //Form submit Handler for ADD or EDIT a repo const formSubmitHandler = async (dataForm: DataForm) => { - //Loading button on submit to avoid multiple send. setIsLoading(true); + start(); //Verify that the SSH key is unique if (!(await isSSHKeyUnique(dataForm.sshkey))) { + stop(); setIsLoading(false); return; } @@ -182,6 +190,10 @@ export default function RepoManage(props: RepoManageProps) { toast.error('An error has occurred', toastOptions); router.replace('/'); console.log(error); + }) + .finally(() => { + stop(); + setIsLoading(false); }); //EDIT a repo } else if (props.mode == 'edit') { @@ -219,6 +231,10 @@ export default function RepoManage(props: RepoManageProps) { toast.error('An error has occurred', toastOptions); router.replace('/'); console.log(error); + }) + .finally(() => { + stop(); + setIsLoading(false); }); } }; @@ -254,24 +270,24 @@ export default function RepoManage(props: RepoManageProps) {
The data will not be recoverable and it will not be possible to go back.
- {isLoading ? ( - - ) : ( - <> - - - - )} + <> + + +
) : ( @@ -450,21 +466,15 @@ export default function RepoManage(props: RepoManageProps) { /> - {isLoading ? ( -
- -
- ) : ( - - )} + + {props.mode == 'edit' ? ( - )} + {info && ( Notification successfully sent. @@ -173,7 +162,6 @@ export default function AppriseAlertSettings() { )} )} - {error && } diff --git a/Containers/UserSettings/AppriseAlertSettings/AppriseMode/AppriseMode.tsx b/Containers/UserSettings/AppriseAlertSettings/AppriseMode/AppriseMode.tsx index b36a92d..2da7af1 100644 --- a/Containers/UserSettings/AppriseAlertSettings/AppriseMode/AppriseMode.tsx +++ b/Containers/UserSettings/AppriseAlertSettings/AppriseMode/AppriseMode.tsx @@ -1,12 +1,11 @@ -import { useEffect } from 'react'; -import classes from '../../UserSettings.module.css'; -import { useState } from 'react'; -import { SpinnerCircularFixed } from 'spinners-react'; +import { useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; -import { Optional, AppriseModeEnum, AppriseModeDTO } from '~/types'; +import { AppriseModeDTO, AppriseModeEnum, Optional } from '~/types'; +import classes from '../../UserSettings.module.css'; //Components import Error from '~/Components/UI/Error/Error'; +import { useLoader } from '~/contexts/LoaderContext'; import { useFormStatus } from '~/hooks'; type AppriseModeDataForm = { @@ -19,10 +18,10 @@ export default function AppriseMode() { register, handleSubmit, formState: { errors }, - } = useForm({ mode: 'onBlur' }); + } = useForm({ mode: 'onChange' }); - const { isLoading, isSaved, error, setIsLoading, handleSuccess, handleError, clearError } = - useFormStatus(); + const { error, setIsLoading, handleSuccess, handleError, clearError } = useFormStatus(); + const { start, stop } = useLoader(); const [displayStatelessURL, setDisplayStatelessURL] = useState(false); const [appriseMode, setAppriseMode] = useState>( @@ -61,6 +60,7 @@ export default function AppriseMode() { const modeFormSubmitHandler = async (data: AppriseModeDataForm) => { clearError(); setIsLoading(true); + start(); try { const response = await fetch('/api/v1/notif/apprise/mode', { @@ -79,6 +79,9 @@ export default function AppriseMode() { } } catch (error) { handleError('The Apprise mode change has failed'); + } finally { + stop(); + setIsLoading(false); } }; @@ -87,23 +90,9 @@ export default function AppriseMode() { {/* APPRISE MODE SELECTION */}
Apprise mode
-
- {isLoading && ( - - )} - {isSaved && ( -
✅ Apprise mode has been saved.
- )} -
{error && } -
+