From a78214ec6add711c534b6f76d66c45dd8b877bec Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 16 Nov 2025 22:06:10 +0000 Subject: [PATCH] Standardize toast notifications for blockchain transactions Implemented standardized error and success handling for blockchain transactions using the error-handler.ts utilities. This provides consistent, user-friendly, bilingual (EN/KMR) messaging across the app. Changes: - web/src/components/staking/StakingDashboard.tsx: * Import handleBlockchainError and handleBlockchainSuccess * Replace manual dispatchError parsing in bond() transaction * Replace manual dispatchError parsing in nominate() transaction * Replace manual dispatchError parsing in unbond() transaction * All transactions now show context-aware error messages * Success messages use template interpolation (e.g., "{{amount}} HEZ") Benefits: - Consistent error messaging across all blockchain operations - Automatic bilingual support (English + Kurmanji) - Proper error categorization (Staking, Identity, Tiki, etc.) - User-friendly error descriptions instead of raw pallet errors - Reduced code duplication (removed ~40 lines of manual error parsing) This is Phase 1 of toast standardization. Other components with blockchain transactions (DEX, Governance, Treasury) should follow this pattern in future updates. Pattern to follow: ```typescript if (dispatchError) { handleBlockchainError(dispatchError, api, toast); } else { handleBlockchainSuccess('operation.key', toast, { param: value }); } ``` --- .../components/staking/StakingDashboard.tsx | 50 ++++--------------- 1 file changed, 9 insertions(+), 41 deletions(-) diff --git a/web/src/components/staking/StakingDashboard.tsx b/web/src/components/staking/StakingDashboard.tsx index a7d01203..71a13e9f 100644 --- a/web/src/components/staking/StakingDashboard.tsx +++ b/web/src/components/staking/StakingDashboard.tsx @@ -22,6 +22,7 @@ import { type StakingInfo } from '@pezkuwi/lib/staking'; import { LoadingState } from '@pezkuwi/components/AsyncComponent'; +import { handleBlockchainError, handleBlockchainSuccess } from '@pezkuwi/lib/error-handler'; export const StakingDashboard: React.FC = () => { const { t } = useTranslation(); @@ -120,22 +121,10 @@ export const StakingDashboard: React.FC = () => { console.log('Transaction in block:', status.asInBlock.toHex()); if (dispatchError) { - let errorMessage = 'Transaction failed'; - if (dispatchError.isModule) { - const decoded = api.registry.findMetaError(dispatchError.asModule); - errorMessage = `${decoded.section}.${decoded.name}: ${decoded.docs.join(' ')}`; - } - toast({ - title: 'Error', - description: errorMessage, - variant: 'destructive', - }); + handleBlockchainError(dispatchError, api, toast); setIsLoading(false); } else { - toast({ - title: 'Success', - description: `Bonded ${bondAmount} HEZ successfully`, - }); + handleBlockchainSuccess('staking.bonded', toast, { amount: bondAmount }); setBondAmount(''); refreshBalances(); // Refresh staking data after a delay @@ -184,22 +173,10 @@ export const StakingDashboard: React.FC = () => { ({ status, dispatchError }) => { if (status.isInBlock) { if (dispatchError) { - let errorMessage = 'Nomination failed'; - if (dispatchError.isModule) { - const decoded = api.registry.findMetaError(dispatchError.asModule); - errorMessage = `${decoded.section}.${decoded.name}: ${decoded.docs.join(' ')}`; - } - toast({ - title: 'Error', - description: errorMessage, - variant: 'destructive', - }); + handleBlockchainError(dispatchError, api, toast); setIsLoading(false); } else { - toast({ - title: 'Success', - description: `Nominated ${selectedValidators.length} validator(s)`, - }); + handleBlockchainSuccess('staking.nominated', toast, { count: selectedValidators.length.toString() }); // Refresh staking data setTimeout(() => { if (api && selectedAccount) { @@ -242,21 +219,12 @@ export const StakingDashboard: React.FC = () => { ({ status, dispatchError }) => { if (status.isInBlock) { if (dispatchError) { - let errorMessage = 'Unbond failed'; - if (dispatchError.isModule) { - const decoded = api.registry.findMetaError(dispatchError.asModule); - errorMessage = `${decoded.section}.${decoded.name}: ${decoded.docs.join(' ')}`; - } - toast({ - title: 'Error', - description: errorMessage, - variant: 'destructive', - }); + handleBlockchainError(dispatchError, api, toast); setIsLoading(false); } else { - toast({ - title: 'Success', - description: `Unbonded ${unbondAmount} HEZ. Withdrawal available in ${bondingDuration} eras`, + handleBlockchainSuccess('staking.unbonded', toast, { + amount: unbondAmount, + duration: bondingDuration.toString() }); setUnbondAmount(''); setTimeout(() => {