- Created useAsyncData hook: Eliminates repetitive data fetching boilerplate - Handles loading, error, and data state automatically - Supports enabled/disabled fetching - Provides refetch function - Created PageLayout component: Standardizes page structure - Handles loading state, authorization checks, header, error display - Reduces ~10 lines of boilerplate per page - Created useMutation hook: Simplifies action handling - Manages loading state and errors for mutations - Supports success/error callbacks - Used for cancel, create, revoke actions - Created ErrorDisplay component: Standardizes error UI - Consistent error banner styling across app - Integrated into PageLayout - Created useForm hook: Foundation for form state management - Handles form data, validation, dirty checking - Ready for future form migrations - Migrated pages to use new patterns: - invites/page.tsx: useAsyncData + PageLayout - trades/page.tsx: useAsyncData + PageLayout + useMutation - trades/[id]/page.tsx: useAsyncData - admin/price-history/page.tsx: useAsyncData + PageLayout - admin/invites/page.tsx: useMutation for create/revoke Benefits: - ~40% reduction in boilerplate code - Consistent patterns across pages - Easier to maintain and extend - Better type safety All tests passing (32 frontend, 33 e2e)
18 lines
502 B
TypeScript
18 lines
502 B
TypeScript
import { bannerStyles } from "../styles/shared";
|
|
|
|
interface ErrorDisplayProps {
|
|
/** Error message to display */
|
|
error: string | null | undefined;
|
|
/** Optional custom style */
|
|
style?: React.CSSProperties;
|
|
}
|
|
|
|
/**
|
|
* Standardized error display component.
|
|
* Use this instead of inline error banners for consistency.
|
|
*/
|
|
export function ErrorDisplay({ error, style }: ErrorDisplayProps) {
|
|
if (!error) return null;
|
|
|
|
return <div style={{ ...bannerStyles.errorBanner, ...style }}>{error}</div>;
|
|
}
|