refactor: centralize frontend status message handling with useStatusToast

This commit is contained in:
2025-12-07 23:46:10 +01:00
parent b29e856225
commit 595c170c00
13 changed files with 149 additions and 175 deletions
+9 -9
View File
@@ -1,4 +1,5 @@
import { useState, useCallback } from 'react';
import { useStatusToast } from '../lib/context/StatusToastContext';
/* global PublicKeyCredentialCreationOptions, CredentialCreationOptions */
import {
@@ -14,7 +15,6 @@ import {
} from '../lib/api/apiClient';
import type { PasskeyId } from '../types/identifiers';
type StatusMessageFn = (message: string, variant?: string) => void;
type NotifyApiErrorFn = (error: unknown, message: string) => void;
type ApiError = {
@@ -71,7 +71,6 @@ type RevokePasskeyResult =
interface UsePasskeysArgs {
notifyApiError: NotifyApiErrorFn;
setStatusMessage: StatusMessageFn;
token?: string | null;
}
@@ -89,12 +88,13 @@ interface UsePasskeysResult {
) => Promise<RevokePasskeyResult>;
}
const usePasskeys = ({ notifyApiError, setStatusMessage, token }: UsePasskeysArgs): UsePasskeysResult => {
const usePasskeys = ({ notifyApiError, token }: UsePasskeysArgs): UsePasskeysResult => {
const [passkeys, setPasskeys] = useState<PasskeyRecord[]>([]);
const [passkeysSupported, setPasskeysSupported] = useState<boolean | null>(null);
const [passkeysLoading, setPasskeysLoading] = useState(false);
const [registeringPasskey, setRegisteringPasskey] = useState(false);
const [revokingPasskeyId, setRevokingPasskeyId] = useState<PasskeyId | null>(null);
const { showToast } = useStatusToast();
const refreshPasskeys = useCallback(async (): Promise<void> => {
if (!token) {
@@ -122,7 +122,7 @@ const usePasskeys = ({ notifyApiError, setStatusMessage, token }: UsePasskeysArg
async ({ nickname }: { nickname?: string } = {}): Promise<RegisterPasskeyResult> => {
if (!isWebAuthnAvailable()) {
setPasskeysSupported(false);
setStatusMessage('Passkeys are not supported in this browser.', 'error');
showToast('Passkeys are not supported in this browser.', 'error');
return { ok: false, reason: 'unsupported' };
}
if (registeringPasskey) {
@@ -166,12 +166,12 @@ const usePasskeys = ({ notifyApiError, setStatusMessage, token }: UsePasskeysArg
await finishPasskeyRegistration(payload);
await refreshPasskeys();
setPasskeysSupported(true);
setStatusMessage('Passkey registered.', 'success');
showToast('Passkey registered.', 'success');
return { ok: true };
} catch (error) {
const typedError = error as ApiError;
if (typedError?.name === 'NotAllowedError') {
setStatusMessage('Passkey registration cancelled.', 'info');
showToast('Passkey registration cancelled.', 'info');
return { ok: false, reason: 'cancelled' };
}
@@ -187,7 +187,7 @@ const usePasskeys = ({ notifyApiError, setStatusMessage, token }: UsePasskeysArg
setRegisteringPasskey(false);
}
},
[notifyApiError, refreshPasskeys, registeringPasskey, setStatusMessage],
[notifyApiError, refreshPasskeys, registeringPasskey, showToast],
);
const revokePasskey = useCallback(
@@ -202,7 +202,7 @@ const usePasskeys = ({ notifyApiError, setStatusMessage, token }: UsePasskeysArg
try {
await deletePasskey(passkeyId, { reason });
await refreshPasskeys();
setStatusMessage('Passkey revoked.', 'success');
showToast('Passkey revoked.', 'success');
return { ok: true };
} catch (error) {
const message = (error as ApiError)?.response?.data?.error || 'Failed to revoke passkey.';
@@ -212,7 +212,7 @@ const usePasskeys = ({ notifyApiError, setStatusMessage, token }: UsePasskeysArg
setRevokingPasskeyId(null);
}
},
[notifyApiError, refreshPasskeys, setStatusMessage],
[notifyApiError, refreshPasskeys, showToast],
);
return {