diff --git a/src/components/ErrorSnack.tsx b/src/components/ErrorSnack.tsx index f4d25d2..3742e67 100644 --- a/src/components/ErrorSnack.tsx +++ b/src/components/ErrorSnack.tsx @@ -10,6 +10,7 @@ export default function ErrorSnack({message}: ErrorSnackProps): ReactElement { const [open, setOpen] = useState(true) useEffect(() => { + setOpen(false) setOpen(Boolean(message)) }, [message]) diff --git a/src/components/SuccessSnack.tsx b/src/components/SuccessSnack.tsx index 0d72fd6..ae6d034 100644 --- a/src/components/SuccessSnack.tsx +++ b/src/components/SuccessSnack.tsx @@ -12,13 +12,14 @@ export default function SuccessSnack({ const [open, setOpen] = useState(true) useEffect(() => { + setOpen(false) setOpen(Boolean(message)) }, [message]) return ( setOpen(false)} > diff --git a/src/route-widgets/AliasDetailRoute/AliasNotesForm.tsx b/src/route-widgets/AliasDetailRoute/AliasNotesForm.tsx index 1c45668..13aa9a2 100644 --- a/src/route-widgets/AliasDetailRoute/AliasNotesForm.tsx +++ b/src/route-widgets/AliasDetailRoute/AliasNotesForm.tsx @@ -240,11 +240,12 @@ export default function AliasNotesForm({ + onClick={async () => { arrayHelpers.remove( index, ) - } + await formik.submitForm() + }} > @@ -260,7 +261,9 @@ export default function AliasNotesForm({ - + ) } diff --git a/src/route-widgets/AliasDetailRoute/ChangeAliasActivationStatusSwitch.tsx b/src/route-widgets/AliasDetailRoute/ChangeAliasActivationStatusSwitch.tsx new file mode 100644 index 0000000..8283a34 --- /dev/null +++ b/src/route-widgets/AliasDetailRoute/ChangeAliasActivationStatusSwitch.tsx @@ -0,0 +1,68 @@ +import {ReactElement, useEffect, useState} from "react" +import {AxiosError} from "axios" + +import {Switch} from "@mui/material" +import {useMutation} from "@tanstack/react-query" + +import {Alias} from "~/server-types" +import {UpdateAliasData, updateAlias} from "~/apis" +import {parseFastAPIError} from "~/utils" +import {ErrorSnack, SuccessSnack} from "~/components" + +export interface ChangeAliasActivationStatusSwitchProps { + id: string + isActive: boolean + + onChanged: () => void +} + +export default function ChangeAliasActivationStatusSwitch({ + id, + isActive, + onChanged, +}: ChangeAliasActivationStatusSwitchProps): ReactElement { + const [isActiveUIState, setIsActiveUIState] = useState(true) + + const [successMessage, setSuccessMessage] = useState("") + const [errorMessage, setErrorMessage] = useState("") + + const {mutateAsync, isLoading} = useMutation< + Alias, + AxiosError, + UpdateAliasData + >(values => updateAlias(id, values), { + onSuccess: onChanged, + onError: error => + setErrorMessage(parseFastAPIError(error).detail as string), + }) + + useEffect(() => { + setIsActiveUIState(isActive) + }, [isActive]) + + return ( + <> + { + setIsActiveUIState(!isActiveUIState) + + try { + await mutateAsync({ + isActive: !isActiveUIState, + }) + + if (!isActiveUIState) { + setSuccessMessage("Alias activated successfully!") + } else { + setSuccessMessage("Alias deactivated successfully!") + } + } catch {} + }} + /> + + + + ) +} diff --git a/src/routes/AliasDetailRoute.tsx b/src/routes/AliasDetailRoute.tsx index 22b474a..853e0a9 100644 --- a/src/routes/AliasDetailRoute.tsx +++ b/src/routes/AliasDetailRoute.tsx @@ -1,23 +1,18 @@ -import {ReactElement, useContext, useState} from "react" +import {ReactElement, useContext} from "react" import {useParams} from "react-router-dom" import {AxiosError} from "axios" -import {useMutation, useQuery} from "@tanstack/react-query" -import {Grid, Switch, Typography} from "@mui/material" +import {useQuery} from "@tanstack/react-query" +import {Grid, Typography} from "@mui/material" -import {UpdateAliasData, getAlias, updateAlias} from "~/apis" +import {getAlias} from "~/apis" import {Alias, DecryptedAlias} from "~/server-types" -import { - AliasTypeIndicator, - ErrorSnack, - QueryResult, - SimplePage, - SuccessSnack, -} from "~/components" -import {decryptAliasNotes, parseFastAPIError} from "~/utils" +import {AliasTypeIndicator, QueryResult, SimplePage} from "~/components" +import {decryptAliasNotes} from "~/utils" import AliasNotesForm from "~/route-widgets/AliasDetailRoute/AliasNotesForm" import AliasPreferencesForm from "~/route-widgets/AliasDetailRoute/AliasPreferencesForm" import AuthContext from "~/AuthContext/AuthContext" +import ChangeAliasActivationStatusSwitch from "~/route-widgets/AliasDetailRoute/ChangeAliasActivationStatusSwitch" import DecryptionPasswordMissingAlert from "~/components/DecryptionPasswordMissingAlert" export default function AliasDetailRoute(): ReactElement { @@ -25,10 +20,6 @@ export default function AliasDetailRoute(): ReactElement { const {user, _decryptUsingMasterPassword} = useContext(AuthContext) const address = atob(params.addressInBase64 as string) - const [successMessage, setSuccessMessage] = useState("") - const [errorMessage, setErrorMessage] = useState("") - - const [isActive, setIsActive] = useState(true) const query = useQuery( ["get_alias", params.addressInBase64], async () => { @@ -41,121 +32,87 @@ export default function AliasDetailRoute(): ReactElement { return getAlias(address) } }, - { - onSuccess: alias => setIsActive(alias.isActive), - }, - ) - const {mutateAsync} = useMutation( - values => updateAlias(query.data!.id, values), - { - onSuccess: () => query.refetch(), - onError: error => - setErrorMessage(parseFastAPIError(error).detail as string), - }, ) return ( - <> - - query={query}> - {alias => ( - - - - - - - - - {address} - - - - { - setIsActive(!isActive) - - try { - await mutateAsync({ - isActive, - }) - - if (isActive) { - setSuccessMessage( - "Alias activated successfully!", - ) - } else { - setSuccessMessage( - "Alias deactivated successfully!", - ) - } - } catch {} - }} - /> - + + query={query}> + {alias => ( + + + + + - - - - - - Notes - - - - {user?.encryptedPassword && - (alias as DecryptedAlias).notes ? ( - - ) : ( - - )} - + + + {address} + - - - - - - Settings - - - - - These settings apply to this alias - only. You can either set a value - manually or refer to your defaults - settings. Note that this does change - in behavior. When you set a value to - refer to your default setting, the - alias will always use the latest - value. So when you change your - default setting, the alias will - automatically use the new value. - - - - - + + - )} - - - - - + + + + + Notes + + + + {user?.encryptedPassword && + (alias as DecryptedAlias).notes ? ( + + ) : ( + + )} + + + + + + + + Settings + + + + + These settings apply to this alias only. + You can either set a value manually or + refer to your defaults settings. Note + that this does change in behavior. When + you set a value to refer to your default + setting, the alias will always use the + latest value. So when you change your + default setting, the alias will + automatically use the new value. + + + + + + + + + )} + + ) }