mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-07-25 02:25:41 +00:00
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 });
}
```
This commit is contained in:
@@ -22,6 +22,7 @@ import {
|
|||||||
type StakingInfo
|
type StakingInfo
|
||||||
} from '@pezkuwi/lib/staking';
|
} from '@pezkuwi/lib/staking';
|
||||||
import { LoadingState } from '@pezkuwi/components/AsyncComponent';
|
import { LoadingState } from '@pezkuwi/components/AsyncComponent';
|
||||||
|
import { handleBlockchainError, handleBlockchainSuccess } from '@pezkuwi/lib/error-handler';
|
||||||
|
|
||||||
export const StakingDashboard: React.FC = () => {
|
export const StakingDashboard: React.FC = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -120,22 +121,10 @@ export const StakingDashboard: React.FC = () => {
|
|||||||
console.log('Transaction in block:', status.asInBlock.toHex());
|
console.log('Transaction in block:', status.asInBlock.toHex());
|
||||||
|
|
||||||
if (dispatchError) {
|
if (dispatchError) {
|
||||||
let errorMessage = 'Transaction failed';
|
handleBlockchainError(dispatchError, api, toast);
|
||||||
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',
|
|
||||||
});
|
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
} else {
|
} else {
|
||||||
toast({
|
handleBlockchainSuccess('staking.bonded', toast, { amount: bondAmount });
|
||||||
title: 'Success',
|
|
||||||
description: `Bonded ${bondAmount} HEZ successfully`,
|
|
||||||
});
|
|
||||||
setBondAmount('');
|
setBondAmount('');
|
||||||
refreshBalances();
|
refreshBalances();
|
||||||
// Refresh staking data after a delay
|
// Refresh staking data after a delay
|
||||||
@@ -184,22 +173,10 @@ export const StakingDashboard: React.FC = () => {
|
|||||||
({ status, dispatchError }) => {
|
({ status, dispatchError }) => {
|
||||||
if (status.isInBlock) {
|
if (status.isInBlock) {
|
||||||
if (dispatchError) {
|
if (dispatchError) {
|
||||||
let errorMessage = 'Nomination failed';
|
handleBlockchainError(dispatchError, api, toast);
|
||||||
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',
|
|
||||||
});
|
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
} else {
|
} else {
|
||||||
toast({
|
handleBlockchainSuccess('staking.nominated', toast, { count: selectedValidators.length.toString() });
|
||||||
title: 'Success',
|
|
||||||
description: `Nominated ${selectedValidators.length} validator(s)`,
|
|
||||||
});
|
|
||||||
// Refresh staking data
|
// Refresh staking data
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (api && selectedAccount) {
|
if (api && selectedAccount) {
|
||||||
@@ -242,21 +219,12 @@ export const StakingDashboard: React.FC = () => {
|
|||||||
({ status, dispatchError }) => {
|
({ status, dispatchError }) => {
|
||||||
if (status.isInBlock) {
|
if (status.isInBlock) {
|
||||||
if (dispatchError) {
|
if (dispatchError) {
|
||||||
let errorMessage = 'Unbond failed';
|
handleBlockchainError(dispatchError, api, toast);
|
||||||
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',
|
|
||||||
});
|
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
} else {
|
} else {
|
||||||
toast({
|
handleBlockchainSuccess('staking.unbonded', toast, {
|
||||||
title: 'Success',
|
amount: unbondAmount,
|
||||||
description: `Unbonded ${unbondAmount} HEZ. Withdrawal available in ${bondingDuration} eras`,
|
duration: bondingDuration.toString()
|
||||||
});
|
});
|
||||||
setUnbondAmount('');
|
setUnbondAmount('');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user