Description
src/App.tsx is a 958-line file in which the USDC deposit modal owns roughly 280 lines of JSX plus a dozen pieces of local state and the entire transaction state machine (src/App.tsx:281-451 for state/handlers, src/App.tsx:674-953 for the modal JSX). The deposit logic — DepositStage transitions, handleApproveTransaction, createMockHash, buildExplorerLink, timers in timersRef — is tightly interleaved with the landing page and routing concerns, which makes the file hard to test and review.
This issue extracts the modal into a self-contained src/components/DepositModal.tsx with a typed props contract, leaving App.tsx responsible only for opening/closing it and holding the shared vault balance.
Requirements and context
- Create
src/components/DepositModal.tsx exporting a DepositModal component that receives props such as isOpen, vaultBalance, walletBalance, onClose, and onConfirmed(amount: number).
- Move the deposit-only state (
amountInput, selectedPreset, depositStage, txHash, copied, submittedAmount, submittedStartingBalance, statusMessage) and helpers (handleApproveTransaction, handleRetry, handleDepositAnother, handleCopyHash, getStageLabel, createMockHash, buildExplorerLink) into the new component (src/App.tsx:123-143, src/App.tsx:344-455).
- Keep
vaultBalance lifted in App and update it through onConfirmed; preserve the existing PRESET_AMOUNTS, MIN_DEPOSIT, NETWORK_FEE, EXPLORER_BASE_URL behavior (src/App.tsx:94-97).
- Preserve the timer-cleanup effect so pending
window.setTimeout handles are cleared on unmount (src/App.tsx:327-342).
- Non-functional: no behavior change to the confirmed/failed demo flows, keep
role="dialog"/aria-modal/aria-labelledby and the backdrop click-to-close, and keep App.tsx free of the deposit state machine.
Acceptance criteria
Suggested execution
1. Fork the repo and create a branch — git checkout -b feature/extract-deposit-modal.
2. Implement changes — add src/components/DepositModal.tsx; slim down src/App.tsx.
3. Write/extend tests — this repo has no test runner configured. Add Vitest + @testing-library/react + jsdom, a config with environment: "jsdom", and a "test": "vitest run" script, then add a render test asserting the modal opens with isOpen and calls onConfirmed after the success timers (use fake timers).
4. Test and commit —
npm install
npm run build
npm run dev # verify deposit modal still opens from /billing and Dashboard
npm run test
Example commit message
refactor(deposit): extract DepositModal component out of App.tsx
Guidelines
- The extracted module must reach ≥90% line coverage once tests are added.
- Maintain modal accessibility (focus trap intent,
aria-modal, Escape/backdrop close) and update any docs/comments referencing the inline modal.
- Timeframe: 96 hours.
Description
src/App.tsxis a 958-line file in which the USDC deposit modal owns roughly 280 lines of JSX plus a dozen pieces of local state and the entire transaction state machine (src/App.tsx:281-451for state/handlers,src/App.tsx:674-953for the modal JSX). The deposit logic —DepositStagetransitions,handleApproveTransaction,createMockHash,buildExplorerLink, timers intimersRef— is tightly interleaved with the landing page and routing concerns, which makes the file hard to test and review.This issue extracts the modal into a self-contained
src/components/DepositModal.tsxwith a typed props contract, leavingApp.tsxresponsible only for opening/closing it and holding the shared vault balance.Requirements and context
src/components/DepositModal.tsxexporting aDepositModalcomponent that receives props such asisOpen,vaultBalance,walletBalance,onClose, andonConfirmed(amount: number).amountInput,selectedPreset,depositStage,txHash,copied,submittedAmount,submittedStartingBalance,statusMessage) and helpers (handleApproveTransaction,handleRetry,handleDepositAnother,handleCopyHash,getStageLabel,createMockHash,buildExplorerLink) into the new component (src/App.tsx:123-143,src/App.tsx:344-455).vaultBalancelifted inAppand update it throughonConfirmed; preserve the existingPRESET_AMOUNTS,MIN_DEPOSIT,NETWORK_FEE,EXPLORER_BASE_URLbehavior (src/App.tsx:94-97).window.setTimeouthandles are cleared on unmount (src/App.tsx:327-342).role="dialog"/aria-modal/aria-labelledbyand the backdrop click-to-close, and keepApp.tsxfree of the deposit state machine.Acceptance criteria
src/components/DepositModal.tsxencapsulates all deposit state and handlers behind a typed props interface.App.tsxno longer declaresdepositStage,txHash, orhandleApproveTransactionand shrinks by ~250 lines.npm run buildpasses withstrictTypeScript and no unused locals (tsconfig.json:15-16).Suggested execution
1. Fork the repo and create a branch —
git checkout -b feature/extract-deposit-modal.2. Implement changes — add
src/components/DepositModal.tsx; slim downsrc/App.tsx.3. Write/extend tests — this repo has no test runner configured. Add Vitest +
@testing-library/react+jsdom, a config withenvironment: "jsdom", and a"test": "vitest run"script, then add a render test asserting the modal opens withisOpenand callsonConfirmedafter the success timers (use fake timers).4. Test and commit —
Example commit message
Guidelines
aria-modal, Escape/backdrop close) and update any docs/comments referencing the inline modal.