Skip to content

Commit 912a3c4

Browse files
committed
feat(admin-ui): edit flows with audit ui
Signed-off-by: Rakib Ansary <rakibansary@topcoder.com>
1 parent 06c3251 commit 912a3c4

File tree

15 files changed

+569
-72
lines changed

15 files changed

+569
-72
lines changed

src/apps/wallet-admin/src/home/tabs/payments/PaymentsTab.tsx

Lines changed: 103 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
/* eslint-disable max-len */
22
/* eslint-disable react/jsx-no-bind */
3+
import { toast } from 'react-toastify'
34
import React, { FC, useCallback, useEffect } from 'react'
45

56
import { Collapsible, ConfirmModal, LoadingCircles } from '~/libs/ui'
67
import { UserProfile } from '~/libs/core'
78

8-
import { getMemberHandle, getPayments } from '../../../lib/services/wallet'
9+
import { editPayment, getMemberHandle, getPayments } from '../../../lib/services/wallet'
910
import { Winning, WinningDetail } from '../../../lib/models/WinningDetail'
10-
import { FilterBar } from '../../../lib'
11+
import { FilterBar, PaymentView } from '../../../lib'
1112
import { ConfirmFlowData } from '../../../lib/models/ConfirmFlowData'
1213
import { PaginationInfo } from '../../../lib/models/PaginationInfo'
1314
import PaymentEditForm from '../../../lib/components/payment-edit/PaymentEdit'
@@ -84,6 +85,30 @@ const ListView: FC<ListViewProps> = (props: ListViewProps) => {
8485
totalItems: 0,
8586
totalPages: 0,
8687
})
88+
const [editState, setEditState] = React.useState<{
89+
netAmount?: number;
90+
releaseDate?: Date;
91+
paymentStatus?: string;
92+
auditNote?: string;
93+
}>({})
94+
95+
const editStateRef = React.useRef(editState)
96+
97+
useEffect(() => {
98+
editStateRef.current = editState
99+
}, [editState])
100+
101+
const handleValueUpdated = useCallback((updates: {
102+
auditNote?: string,
103+
netAmount?: number,
104+
paymentStatus?: string,
105+
releaseDate?: Date,
106+
}) => {
107+
setEditState(prev => ({
108+
...prev,
109+
...updates,
110+
}))
111+
}, [])
87112

88113
const convertToWinnings = useCallback(
89114
(payments: WinningDetail[], handleMap: Map<number, string>) => payments.map(payment => {
@@ -116,7 +141,9 @@ const ListView: FC<ListViewProps> = (props: ListViewProps) => {
116141
handle: handleMap.get(parseInt(payment.winnerId, 10)) ?? payment.winnerId,
117142
id: payment.id,
118143
netPayment: formatCurrency(payment.details[0].totalAmount, payment.details[0].currency),
144+
netPaymentNumber: parseFloat(payment.details[0].totalAmount),
119145
releaseDate: formattedReleaseDate,
146+
releaseDateObj: releaseDate,
120147
status: formatStatus(payment.details[0].status),
121148
type: payment.category.replaceAll('_', ' ')
122149
.toLowerCase(),
@@ -143,6 +170,7 @@ const ListView: FC<ListViewProps> = (props: ListViewProps) => {
143170
} finally {
144171
setIsLoading(false)
145172
}
173+
// eslint-disable-next-line react-hooks/exhaustive-deps
146174
}, [convertToWinnings, filters, pagination.currentPage, pagination.pageSize])
147175

148176
const renderConfirmModalContent = React.useMemo(() => {
@@ -157,10 +185,70 @@ const ListView: FC<ListViewProps> = (props: ListViewProps) => {
157185
return confirmFlow?.content
158186
}, [confirmFlow])
159187

188+
const updatePayment = async (paymentId: string): Promise<void> => {
189+
const currentEditState = editStateRef.current
190+
// Send to server only the fields that have changed
191+
const updateObj = {
192+
auditNote: currentEditState.auditNote !== undefined ? currentEditState.auditNote : undefined,
193+
netAmount: currentEditState.netAmount !== undefined ? currentEditState.netAmount : undefined,
194+
paymentStatus: currentEditState.paymentStatus !== undefined ? currentEditState.paymentStatus : undefined,
195+
releaseDate: currentEditState.releaseDate !== undefined ? currentEditState.releaseDate : undefined,
196+
}
197+
198+
let paymentStatus : 'ON_HOLD_ADMIN' | 'OWED' | undefined
199+
if (updateObj.paymentStatus !== undefined) paymentStatus = updateObj.paymentStatus.indexOf('Owed') > -1 ? 'OWED' : 'ON_HOLD_ADMIN'
200+
201+
const updates: {
202+
auditNote?: string
203+
paymentStatus?: 'ON_HOLD_ADMIN' | 'OWED'
204+
releaseDate?: string
205+
paymentAmount?: number
206+
winningsId: string
207+
} = {
208+
auditNote: updateObj.auditNote,
209+
winningsId: paymentId,
210+
}
211+
212+
if (paymentStatus) updates.paymentStatus = paymentStatus
213+
if (updateObj.releaseDate !== undefined) updates.releaseDate = updateObj.releaseDate.toISOString()
214+
if (updateObj.netAmount !== undefined) updates.paymentAmount = updateObj.netAmount
215+
216+
toast.success('Updating payment', { position: toast.POSITION.BOTTOM_RIGHT })
217+
try {
218+
const udpateMessage = await editPayment(updates)
219+
toast.success(udpateMessage, { position: toast.POSITION.BOTTOM_RIGHT })
220+
} catch (err) {
221+
toast.error('Failed to update payment', { position: toast.POSITION.BOTTOM_RIGHT })
222+
return
223+
}
224+
225+
setEditState({})
226+
227+
await fetchWinnings()
228+
}
229+
160230
useEffect(() => {
161231
fetchWinnings()
162232
}, [fetchWinnings])
163233

234+
const onPaymentEditCallback = useCallback((payment: Winning) => {
235+
setConfirmFlow({
236+
action: 'Save',
237+
callback: async () => {
238+
updatePayment(payment.id)
239+
},
240+
content: (
241+
<PaymentEditForm
242+
payment={payment}
243+
canSave={setIsConfirmFormValid}
244+
onValueUpdated={handleValueUpdated}
245+
/>
246+
),
247+
title: 'Edit Payment',
248+
})
249+
// eslint-disable-next-line react-hooks/exhaustive-deps
250+
}, [handleValueUpdated, editState])
251+
164252
return (
165253
<>
166254
<div className={styles.container}>
@@ -320,19 +408,23 @@ const ListView: FC<ListViewProps> = (props: ListViewProps) => {
320408
currentPage: pageNumber,
321409
})
322410
}}
323-
onPaymentEditClick={function onPaymentEditClicked(payment: Winning) {
411+
onPaymentEditClick={(payment: Winning) => {
412+
setEditState({})
413+
onPaymentEditCallback(payment)
414+
}}
415+
onPaymentViewClick={function onPaymentViewClicked(payment: Winning) {
324416
setConfirmFlow({
325417
action: 'Save',
326-
callback: () => console.log('Edit payment:', payment),
418+
callback: async () => {
419+
updatePayment(payment.id)
420+
},
327421
content: (
328-
<PaymentEditForm
422+
<PaymentView
329423
payment={payment}
330-
onErrorStateChanged={function onErrorStateChanged(error: boolean) {
331-
setIsConfirmFormValid(!error)
332-
}}
333424
/>
334425
),
335-
title: 'Edit Payment',
426+
showButtons: false,
427+
title: 'Payment Details',
336428
})
337429
}}
338430
/>
@@ -351,9 +443,11 @@ const ListView: FC<ListViewProps> = (props: ListViewProps) => {
351443
</div>
352444
{confirmFlow && (
353445
<ConfirmModal
446+
showButtons={confirmFlow.showButtons}
354447
title={confirmFlow.title}
355448
action={confirmFlow.action}
356449
onClose={function onClose() {
450+
setEditState({})
357451
setConfirmFlow(undefined)
358452
}}
359453
onConfirm={function onConfirm() {

src/apps/wallet-admin/src/lib/components/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ export * from './info-row'
33
export * from './chip'
44
export * from './filter-bar'
55
export * from './payment-edit'
6+
export * from './payment-view'
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
.formContainer {
2+
display: flex;
3+
flex-direction: column;
4+
}
5+
6+
.infoGroup {
7+
display: grid;
8+
grid-template-columns: repeat(3, 1fr);
9+
gap: 20px;
10+
margin-bottom: 20px;
11+
}
12+
13+
.infoItem {
14+
display: flex;
15+
flex-direction: column;
16+
}
17+
18+
.label {
19+
font-weight: bold;
20+
margin-bottom: 5px;
21+
}
22+
23+
.value {
24+
// Style for your value text
25+
}
26+
27+
.inputGroup {
28+
display: flex;
29+
flex-direction: column;
30+
gap: 20px;
31+
}
32+
33+
// @media (max-width: 768px) {
34+
// .infoGroup {
35+
// grid-template-columns: 1fr;
36+
// }
37+
// }

0 commit comments

Comments
 (0)