Skip to content

feat: add top-up investment button for open invoice positions - #126

Open
Oluwasuyi-Oluwatimilehin-Daniel wants to merge 3 commits into
StellarState:devfrom
Oluwasuyi-Oluwatimilehin-Daniel:feature/top-up-investment-button
Open

feat: add top-up investment button for open invoice positions#126
Oluwasuyi-Oluwatimilehin-Daniel wants to merge 3 commits into
StellarState:devfrom
Oluwasuyi-Oluwatimilehin-Daniel:feature/top-up-investment-button

Conversation

@Oluwasuyi-Oluwatimilehin-Daniel

Copy link
Copy Markdown

Summary

Investors can now increase their committed amount on open invoices directly from the investor dashboard using a new "Top Up" button. This feature provides a clear and direct way to add to existing positions without navigating back to the marketplace.

Closes #121

Changes Made

1. API Layer (lib/api/index.ts)

  • Added topUpInvoice() function to handle top-up requests
  • Fixed incomplete distributeDividend() function that had syntax errors
  • Fixed incomplete approveKeyPause() function that had syntax errors

2. Hooks (hooks/useInvestments.ts)

  • Added useTopUpMutation() hook with:
    • Error handling with toast notifications
    • Success toast showing new total position amount
    • Automatic cache invalidation for portfolio and invoice queries

3. Data Types (lib/portfolio.ts)

  • Extended InvestmentPosition interface to include remaining_capacity field
  • This allows the UI to determine if top-up is available for a position

4. Components

New Component: TopUpModal (components/invoices/TopUpModal.tsx)

  • Modal component for top-up functionality with:
    • Display of current committed amount
    • Input field for additional amount
    • Real-time validation:
      • Ensures amount is positive
      • Ensures amount does not exceed remaining capacity
      • Shows "Exceeds remaining capacity" error when appropriate
    • Live preview of new total position after top-up
    • Confirm/Cancel buttons
    • Loading state during processing

Updated Component: PositionCard (components/dashboard/PositionCard.tsx)

  • Added "Top Up" button to position cards
  • Button only shows when:
    • Position status is "active"
    • Remaining capacity is greater than 0
  • Integrated TopUpModal component
  • Maintains existing layout and functionality

5. Tests (components/dashboard/__tests__/PositionCard.test.tsx)

  • Added test cases for Top Up button visibility:
    • Renders for active positions with remaining capacity
    • Does not render for settled positions
    • Does not render when remaining capacity is zero

Acceptance Criteria Met

Top-up modal opens from the open position row

  • Top Up button appears on active position rows with remaining capacity
  • Clicking the button opens the TopUpModal popover

Amount that would exceed remaining invoice capacity shows 'Exceeds remaining capacity'

  • Validation logic in TopUpModal checks against remaining_capacity
  • Error message displayed when amount exceeds capacity

Preview shows new total position correctly

  • Modal displays current committed amount
  • Live preview shows new total (current + additional) when valid amount entered

Success toast shown with new total position after confirmation

  • useTopUpMutation shows success toast with format: "Top-up of {amount} XLM successful. New total: {new_total} XLM"

Position amount updated in dashboard list after top-up

  • Mutation invalidates portfolio cache on success
  • React Query refetches updated position data
  • UI automatically reflects new committed amount

Technical Details

API Endpoint

  • POST /api/invoices/{invoiceId}/top_up
  • Request body: { amount: number }
  • Response: { success: boolean, new_total: number }

State Management

  • Uses React Query mutations for optimistic updates
  • Invalidates relevant caches (PORTFOLIO_QUERY_KEY, INVOICES_QUERY_KEY)
  • Automatic UI refresh after successful top-up

Validation

  • Client-side validation for immediate feedback
  • Server-side validation via API endpoint
  • Prevents negative amounts and amounts exceeding capacity

Testing

  • Added unit tests for PositionCard Top Up button visibility
  • Tests cover edge cases (settled positions, zero capacity)
  • Manual testing recommended for full user flow

Dependencies

  • No new dependencies added
  • Uses existing UI components (Button, Input, Label, Popover)
  • Uses existing hooks (useMutation, useQueryClient)
  • Uses existing toast library (sonner)

Backward Compatibility

  • Fully backward compatible
  • remaining_capacity is optional in InvestmentPosition interface
  • Positions without this field will not show Top Up button (graceful degradation)
  • Existing functionality unchanged

Future Enhancements

  • Consider adding minimum top-up amount validation
  • Consider adding top-up history tracking
  • Consider batch top-up for multiple positions

Screenshots

(To be added during manual testing)

  1. Position card with Top Up button
  2. Top Up modal with amount input
  3. Validation error for exceeding capacity
  4. Success toast after top-up
  5. Updated position amount in dashboard

Checklist

  • Branch created: feature/top-up-investment-button
  • API function added
  • Hook created with proper error handling
  • Modal component with validation
  • Position card updated with Top Up button
  • Tests added
  • TypeScript types updated
  • Success toast implemented
  • Cache invalidation configured
  • Code follows existing patterns
  • No breaking changes

@drips-wave

drips-wave Bot commented Aug 27, 2026

Copy link
Copy Markdown

@Oluwasuyi-Oluwatimilehin-Daniel Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a top-up investment button allowing investors to increase their committed amount on an open invoice

1 participant