|
1 | 1 | /* eslint-disable max-len */ |
2 | 2 | /* eslint-disable react/jsx-no-bind */ |
3 | | -import { toast } from 'react-toastify' |
4 | | -import { AxiosError } from 'axios' |
5 | | -import { Link } from 'react-router-dom' |
6 | 3 | import React, { FC, useCallback, useEffect } from 'react' |
7 | 4 |
|
8 | | -import { Collapsible, ConfirmModal, LoadingCircles } from '~/libs/ui' |
| 5 | +import { Collapsible, LoadingCircles } from '~/libs/ui' |
9 | 6 | import { UserProfile } from '~/libs/core' |
10 | 7 |
|
11 | | -import { getPayments, processWinningsPayments } from '../../../lib/services/wallet' |
| 8 | +import { getPayments } from '../../../lib/services/wallet' |
12 | 9 | import { Winning, WinningDetail } from '../../../lib/models/WinningDetail' |
13 | 10 | import { FilterBar } from '../../../lib' |
14 | | -import { ConfirmFlowData } from '../../../lib/models/ConfirmFlowData' |
15 | 11 | import { PaginationInfo } from '../../../lib/models/PaginationInfo' |
16 | 12 | import { useWalletDetails, WalletDetailsResponse } from '../../../lib/hooks/use-wallet-details' |
17 | | -import { nullToZero } from '../../../lib/util' |
| 13 | +import { WalletDetails } from '../../../lib/models/WalletDetails' |
18 | 14 | import PaymentsTable from '../../../lib/components/payments-table/PaymentTable' |
19 | 15 |
|
| 16 | +import ConfirmPaymentModal from './ConfirmPayment.modal' |
20 | 17 | import styles from './Winnings.module.scss' |
21 | 18 |
|
22 | 19 | interface ListViewProps { |
@@ -78,7 +75,7 @@ const formatCurrency = (amountStr: string, currency: string): string => { |
78 | 75 | } |
79 | 76 |
|
80 | 77 | const ListView: FC<ListViewProps> = (props: ListViewProps) => { |
81 | | - const [confirmFlow, setConfirmFlow] = React.useState<ConfirmFlowData | undefined>(undefined) |
| 78 | + const [confirmPayments, setConfirmPayments] = React.useState<Winning[]>() |
82 | 79 | const [winnings, setWinnings] = React.useState<ReadonlyArray<Winning>>([]) |
83 | 80 | const [selectedPayments, setSelectedPayments] = React.useState<{ [paymentId: string]: Winning }>({}) |
84 | 81 | const [isLoading, setIsLoading] = React.useState<boolean>(false) |
@@ -146,133 +143,22 @@ const ListView: FC<ListViewProps> = (props: ListViewProps) => { |
146 | 143 | } |
147 | 144 | }, [props.profile.userId, convertToWinnings, filters, pagination.currentPage, pagination.pageSize]) |
148 | 145 |
|
149 | | - const renderConfirmModalContent = React.useMemo(() => { |
150 | | - if (confirmFlow?.content === undefined) { |
151 | | - return undefined |
152 | | - } |
153 | | - |
154 | | - if (typeof confirmFlow?.content === 'function') { |
155 | | - return confirmFlow?.content() |
156 | | - } |
157 | | - |
158 | | - return confirmFlow?.content |
159 | | - }, [confirmFlow]) |
160 | | - |
161 | 146 | useEffect(() => { |
162 | 147 | fetchWinnings() |
163 | 148 | }, [fetchWinnings]) |
164 | 149 |
|
165 | | - const processPayouts = async (winningIds: string[]): Promise<void> => { |
166 | | - setSelectedPayments({}) |
167 | | - |
168 | | - toast.info('Processing payments...', { |
169 | | - position: toast.POSITION.BOTTOM_RIGHT, |
170 | | - }) |
171 | | - try { |
172 | | - await processWinningsPayments(winningIds) |
173 | | - toast.success('Payments processed successfully!', { |
174 | | - position: toast.POSITION.BOTTOM_RIGHT, |
175 | | - }) |
176 | | - } catch (error) { |
177 | | - let message = 'Failed to process payments. Please try again later.' |
178 | | - |
179 | | - if (error instanceof AxiosError) { |
180 | | - message = error.response?.data?.error?.message ?? error.response?.data?.message ?? error.message ?? '' |
181 | | - |
182 | | - message = message.charAt(0) |
183 | | - .toUpperCase() + message.slice(1) |
184 | | - } |
185 | | - |
186 | | - toast.error(message, { |
187 | | - position: toast.POSITION.BOTTOM_RIGHT, |
188 | | - }) |
189 | | - } |
190 | | - |
191 | | - fetchWinnings() |
192 | | - } |
193 | | - |
194 | 150 | function handlePayMeClick( |
195 | | - paymentIds: { [paymentId: string]: Winning }, |
196 | | - totalAmountStr: string, |
| 151 | + payments: { [paymentId: string]: Winning }, |
197 | 152 | ): void { |
198 | | - const totalAmount = parseFloat(totalAmountStr) |
199 | | - const taxWithholdAmount = (parseFloat(nullToZero(walletDetails?.taxWithholdingPercentage ?? '0')) * totalAmount) / 100 |
200 | | - const feesAmount = parseFloat(nullToZero(walletDetails?.estimatedFees ?? '0')) |
201 | | - const netAmount = totalAmount - taxWithholdAmount - feesAmount |
| 153 | + setConfirmPayments(Object.values(payments)) |
| 154 | + } |
202 | 155 |
|
203 | | - setConfirmFlow({ |
204 | | - action: 'Confirm Payment', |
205 | | - callback: () => processPayouts(Object.keys(paymentIds)), |
206 | | - content: ( |
207 | | - <> |
208 | | - <div className={`${styles.processing} body-medium-normal`}> |
209 | | - Processing Payment: $ |
210 | | - {totalAmountStr} |
211 | | - {' '} |
212 | | - </div> |
213 | | - {walletDetails && ( |
214 | | - <> |
215 | | - <div className={styles.breakdown}> |
216 | | - <h4>Payment Breakdown:</h4> |
217 | | - <ul className={`${styles.breakdownList} body-main`}> |
218 | | - <li> |
219 | | - <span>Base amount:</span> |
220 | | - <span> |
221 | | - $ |
222 | | - {totalAmountStr} |
223 | | - </span> |
224 | | - </li> |
225 | | - <li> |
226 | | - <span> |
227 | | - Tax Witholding ( |
228 | | - {nullToZero(walletDetails.taxWithholdingPercentage)} |
229 | | - %): |
230 | | - </span> |
231 | | - <span> |
232 | | - $ |
233 | | - {taxWithholdAmount.toFixed(2)} |
234 | | - </span> |
235 | | - </li> |
236 | | - <li> |
237 | | - <span>Processing fee:</span> |
238 | | - <span> |
239 | | - $ |
240 | | - {feesAmount.toFixed(2)} |
241 | | - </span> |
242 | | - </li> |
243 | | - </ul> |
244 | | - <hr /> |
245 | | - <div className={`${styles.summary} body-main-bold`}> |
246 | | - <span>Net amount after fees:</span> |
247 | | - <span> |
248 | | - $ |
249 | | - {netAmount.toFixed(2)} |
250 | | - </span> |
251 | | - </div> |
252 | | - {walletDetails?.primaryCurrency && walletDetails.primaryCurrency !== 'USD' && ( |
253 | | - <div className={`${styles.alert} body-main-medium`}> |
254 | | - Net amount will be converted to |
255 | | - {' '} |
256 | | - {walletDetails.primaryCurrency} |
257 | | - {' '} |
258 | | - with a 2% conversion fee applied. |
259 | | - </div> |
260 | | - )} |
261 | | - </div> |
262 | | - <div className={`${styles.taxesFooterRow} body-main`}> |
263 | | - You can adjust your payout settings to customize your estimated payment fee |
264 | | - and tax withholding percentage in the |
265 | | - {' '} |
266 | | - <Link to='#payout'>Payout</Link> |
267 | | - {' '} |
268 | | - section. |
269 | | - </div> |
270 | | - </> |
271 | | - )} |
272 | | - </> |
273 | | - ), |
274 | | - title: 'Payment Confirmation', |
275 | | - }) |
| 156 | + function handleCloseConfirmModal(isDone?: boolean): void { |
| 157 | + setConfirmPayments(undefined) |
| 158 | + setSelectedPayments({}) |
| 159 | + if (isDone) { |
| 160 | + fetchWinnings() |
| 161 | + } |
276 | 162 | } |
277 | 163 |
|
278 | 164 | return ( |
@@ -461,23 +347,13 @@ const ListView: FC<ListViewProps> = (props: ListViewProps) => { |
461 | 347 | </Collapsible> |
462 | 348 | </div> |
463 | 349 | </div> |
464 | | - {confirmFlow && ( |
465 | | - <ConfirmModal |
466 | | - size='lg' |
467 | | - maxWidth='610px' |
468 | | - title={confirmFlow.title} |
469 | | - action={confirmFlow.action} |
470 | | - onClose={function onClose() { |
471 | | - setConfirmFlow(undefined) |
472 | | - }} |
473 | | - onConfirm={function onConfirm() { |
474 | | - confirmFlow.callback?.() |
475 | | - setConfirmFlow(undefined) |
476 | | - }} |
477 | | - open={confirmFlow !== undefined} |
478 | | - > |
479 | | - <div>{renderConfirmModalContent}</div> |
480 | | - </ConfirmModal> |
| 350 | + {confirmPayments && ( |
| 351 | + <ConfirmPaymentModal |
| 352 | + userEmail={props.profile.email} |
| 353 | + payments={confirmPayments} |
| 354 | + walletDetails={walletDetails as WalletDetails} |
| 355 | + onClose={handleCloseConfirmModal} |
| 356 | + /> |
481 | 357 | )} |
482 | 358 | </> |
483 | 359 | ) |
|
0 commit comments