Adds a confirmation modal dialog that intercepts the "Buy Shares" action and displays a purchase summary — number of shares, price per share (fetched live from the contract), and total cost — before the user authorizes the transaction. This prevents accidental purchases by requiring an explicit confirmation step.
A minimal, reusable modal primitive built with React createPortal:
| Prop | Type | Description |
|---|---|---|
title |
string |
Heading rendered at the top of the modal |
children |
ReactNode |
Body content |
actions |
ReactNode |
Footer action buttons |
onClose |
() => void |
Called on Escape key or overlay click |
Accessibility: role="dialog", aria-modal="true", aria-label from title, keyboard-dismissible (Escape), click-outside-dismissible.
Files:
Modal.jsx— portal wrapper with overlay, keyboard & click-outside closeModal.module.css— overlay backdrop + slide-up animation
Uses Modal to display a structured purchase summary:
| Row | Value |
|---|---|
| Shares | The quantity entered by the user |
| Price per share | Live contract value, formatted from stroops → XLM (1 stroop = 10⁻⁷ XLM) |
| Total cost | pricePerShare × shares, same XLM formatting, highlighted in primary color |
Has Confirm (primary) and Cancel (secondary) buttons. The Confirm button shows a loading spinner while the transaction is in flight.
Files:
ConfirmPurchase.jsx— rendersModalwith the summary table and action buttonsConfirmPurchase.module.css— table layout, row separators, total row highlight
Three changes:
-
get_pricehook — addeduseSorobanRead('get_price', [])to fetch the current share price from the contract on mount. Result decoded via.retval.u64(). -
handleBuyShares→ modal gate — the function now only validates the amount and setsconfirmPending = true(opens the modal). It no longer fires the transaction directly. -
handleConfirmBuy— new async function that executes thebuy_sharestransaction (moved from the oldhandleBuyShares), then closes the modal on success or error. -
ConfirmPurchaserendered — conditionally rendered at the bottom of the JSX tree whenconfirmPendingistrue, receivingshares,pricePerShare,onConfirm,onCancel, andloadingprops.
User enters share amount → clicks "Buy Shares"
→ Modal opens showing:
Shares: 5
Price per share: 1.00 XLM
Total cost: 5.00 XLM
→ [Cancel] closes modal, no action
→ [Confirm] fires buy_shares transaction
button shows spinner while pending
modal closes after submit
toast shows tx status
- Create a reusable Modal component
- Create a ConfirmPurchase modal with share summary
- Wire it before handleBuyShares
- Show price per share and total cost
- Handle confirm and cancel actions
- Build passes (
vite build— 615 modules, no new errors)
| File | Change |
|---|---|
frontend/src/components/Modal/Modal.jsx |
New — reusable portal modal |
frontend/src/components/Modal/Modal.module.css |
New — overlay + animation styles |
frontend/src/components/ConfirmPurchase/ConfirmPurchase.jsx |
New — purchase summary modal |
frontend/src/components/ConfirmPurchase/ConfirmPurchase.module.css |
New — summary table styles |
frontend/src/App.jsx |
Modified — get_price hook, modal gate in handleBuyShares, handleConfirmBuy, modal render |
closes #93