components/bounty-detail/bounty-detail-sidebar-cta.tsx is around 680 lines and exports both SidebarCTA and MobileCTA from the same file. The two components duplicate state and event handlers (cancel dialog, dispute dialog, application dialog, copy logic) and any change to the apply or dispute flow has to be made in both places. The file is hard to read and a constant merge-conflict surface. We've already had merges drop handleApply from SidebarCTA and break the build.
What to do
Split into three files:
components/bounty-detail/bounty-detail-sidebar-cta.tsx exports SidebarCTA
components/bounty-detail/bounty-detail-mobile-cta.tsx exports MobileCTA
components/bounty-detail/use-bounty-cta-state.ts exports a shared hook returning everything both components need: walletAddress, hasJoined, isPastDeadline, handleJoin, handleApply, cancel dialog state, copy state, canRaiseDispute, etc.
Update bounty-detail-client.tsx to import MobileCTA from the new file. No behavioral change.
Acceptance criteria
- Both components render exactly as before
- No duplicated state or event handlers between the two files
- Each file is under 300 lines
- The shared hook owns all the data both components consume
Files
components/bounty-detail/bounty-detail-sidebar-cta.tsx
components/bounty-detail/bounty-detail-mobile-cta.tsx (new)
components/bounty-detail/use-bounty-cta-state.ts (new)
components/bounty-detail/bounty-detail-client.tsx
components/bounty-detail/bounty-detail-sidebar-cta.tsxis around 680 lines and exports bothSidebarCTAandMobileCTAfrom the same file. The two components duplicate state and event handlers (cancel dialog, dispute dialog, application dialog, copy logic) and any change to the apply or dispute flow has to be made in both places. The file is hard to read and a constant merge-conflict surface. We've already had merges drophandleApplyfromSidebarCTAand break the build.What to do
Split into three files:
components/bounty-detail/bounty-detail-sidebar-cta.tsxexportsSidebarCTAcomponents/bounty-detail/bounty-detail-mobile-cta.tsxexportsMobileCTAcomponents/bounty-detail/use-bounty-cta-state.tsexports a shared hook returning everything both components need:walletAddress,hasJoined,isPastDeadline,handleJoin,handleApply, cancel dialog state, copy state,canRaiseDispute, etc.Update
bounty-detail-client.tsxto importMobileCTAfrom the new file. No behavioral change.Acceptance criteria
Files
components/bounty-detail/bounty-detail-sidebar-cta.tsxcomponents/bounty-detail/bounty-detail-mobile-cta.tsx(new)components/bounty-detail/use-bounty-cta-state.ts(new)components/bounty-detail/bounty-detail-client.tsx