refactor(frontend): improve code quality and maintainability
- Extract API error handling utility (utils/error-handling.ts) - Centralize error message extraction logic - Add type guards for API errors - Replace duplicated error handling across components - Create reusable Toast component (components/Toast.tsx) - Extract toast notification logic from profile page - Support auto-dismiss functionality - Consistent styling with shared styles - Extract form validation debouncing hook (hooks/useDebouncedValidation.ts) - Reusable debounced validation logic - Clean timeout management - Used in profile page for form validation - Consolidate duplicate styles (styles/auth-form.ts) - Use shared style tokens instead of duplicating values - Reduce code duplication between auth-form and shared styles - Extract loading state component (components/LoadingState.tsx) - Standardize loading UI across pages - Replace duplicated loading JSX patterns - Used in profile, exchange, and trades pages - Fix useRequireAuth dependency array - Remove unnecessary hasPermission from dependencies - Add eslint-disable comment with explanation - Improve hook stability and performance All frontend tests pass. Linting passes.
This commit is contained in:
parent
db181b338c
commit
3beb23a765
10 changed files with 231 additions and 143 deletions
|
|
@ -3,9 +3,11 @@
|
|||
import { useEffect, useState, useCallback, useMemo, ChangeEvent, CSSProperties } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Permission } from "../auth-context";
|
||||
import { api, ApiError } from "../api";
|
||||
import { api } from "../api";
|
||||
import { extractApiErrorMessage } from "../utils/error-handling";
|
||||
import { Header } from "../components/Header";
|
||||
import { SatsDisplay } from "../components/SatsDisplay";
|
||||
import { LoadingState } from "../components/LoadingState";
|
||||
import { useRequireAuth } from "../hooks/useRequireAuth";
|
||||
import { components } from "../generated/api";
|
||||
import { formatDate, formatTime, getDateRange } from "../utils/date";
|
||||
|
|
@ -325,18 +327,7 @@ export default function ExchangePage() {
|
|||
// Redirect to trades page after successful booking
|
||||
router.push("/trades");
|
||||
} catch (err) {
|
||||
let errorMessage = "Failed to book trade";
|
||||
if (err instanceof ApiError) {
|
||||
// Extract detail from API error response
|
||||
if (err.data && typeof err.data === "object") {
|
||||
const data = err.data as { detail?: string };
|
||||
errorMessage = data.detail || err.message;
|
||||
} else {
|
||||
errorMessage = err.message;
|
||||
}
|
||||
} else if (err instanceof Error) {
|
||||
errorMessage = err.message;
|
||||
}
|
||||
const errorMessage = extractApiErrorMessage(err, "Failed to book trade");
|
||||
setError(errorMessage);
|
||||
|
||||
// Check if it's a "same day" error and extract trade public_id (UUID)
|
||||
|
|
@ -352,11 +343,7 @@ export default function ExchangePage() {
|
|||
};
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<main style={layoutStyles.main}>
|
||||
<div style={layoutStyles.loader}>Loading...</div>
|
||||
</main>
|
||||
);
|
||||
return <LoadingState />;
|
||||
}
|
||||
|
||||
if (!isAuthorized) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue