Skip to content

Extract the deposit modal out of App.tsx into a dedicated DepositModal component #135

@greatest0fallt1me

Description

@greatest0fallt1me

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

  • New src/components/DepositModal.tsx encapsulates all deposit state and handlers behind a typed props interface.
  • App.tsx no longer declares depositStage, txHash, or handleApproveTransaction and shrinks by ~250 lines.
  • Opening, approving (confirmed + failed paths), retry, "deposit another", copy-hash, and close all behave exactly as before.
  • Timers are cleared on unmount; no "setState on unmounted component" warnings.
  • npm run build passes with strict TypeScript and no unused locals (tsconfig.json:15-16).

Suggested execution

1. Fork the repo and create a branchgit 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GRANTFOX OSSGrantFox OSS programMAYBE REWARDEDGrantFox — potentially rewardedOFFICIAL CAMPAIGNGrantFox official campaigndxDeveloper experiencefrontendUI / frontendimprovementRefactor, performance, or tech-debtintermediateModerate complexity

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions