Skip to content

Commit 3c180fd

Browse files
committed
feat(winnings): add filter bar
Signed-off-by: Rakib Ansary <rakibansary@topcoder.com>
1 parent 78d8ac1 commit 3c180fd

File tree

3 files changed

+42
-7
lines changed

3 files changed

+42
-7
lines changed

src/apps/wallet/src/home/tabs/winnings/Winnings.module.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,11 @@
2525
background-color: $tc-white;
2626
border-radius: 4px;
2727
margin-top: $sp-4;
28+
.centered {
29+
height: 200px;
30+
display: flex;
31+
justify-content: space-around;
32+
align-items: center;
33+
}
2834
}
2935
}

src/apps/wallet/src/home/tabs/winnings/WinningsTab.tsx

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable max-len */
12
/* eslint-disable react/jsx-no-bind */
23
import { toast } from 'react-toastify'
34
import { AxiosError } from 'axios'
@@ -72,6 +73,7 @@ const ListView: FC<ListViewProps> = (props: ListViewProps) => {
7273
const [confirmFlow, setConfirmFlow] = React.useState<ConfirmFlowData | undefined>(undefined)
7374
const [winnings, setWinnings] = React.useState<ReadonlyArray<Winning>>([])
7475
const [isLoading, setIsLoading] = React.useState<boolean>(false)
76+
const [filters, setFilters] = React.useState<Record<string, string[]>>({})
7577

7678
const convertToWinnings = useCallback(
7779
(payments: WinningDetail[]) => payments.map(payment => ({
@@ -94,15 +96,15 @@ const ListView: FC<ListViewProps> = (props: ListViewProps) => {
9496
const fetchWinnings = useCallback(async () => {
9597
setIsLoading(true)
9698
try {
97-
const payments = await getPayments(props.profile.userId.toString())
99+
const payments = await getPayments(props.profile.userId.toString(), filters)
98100
const winningsData = convertToWinnings(payments)
99101
setWinnings(winningsData)
100102
} catch (apiError) {
101103
console.error('Failed to fetch winnings:', apiError)
102104
} finally {
103105
setIsLoading(false)
104106
}
105-
}, [props.profile.userId, convertToWinnings])
107+
}, [props.profile.userId, convertToWinnings, filters])
106108

107109
const renderConfirmModalContent = React.useMemo(() => {
108110
if (confirmFlow?.content === undefined) {
@@ -192,6 +194,10 @@ const ListView: FC<ListViewProps> = (props: ListViewProps) => {
192194
label: 'Contest Payment',
193195
value: 'CONTEST_PAYMENT',
194196
},
197+
{
198+
label: 'Copilot Payment',
199+
value: 'COPILOT_PAYMENT',
200+
},
195201
{
196202
label: 'Review Board Payment',
197203
value: 'REVIEW_BOARD_PAYMENT',
@@ -224,15 +230,18 @@ const ListView: FC<ListViewProps> = (props: ListViewProps) => {
224230
},
225231
]}
226232
onFilterChange={(key: string, value: string[]) => {
227-
console.log(key, value)
233+
setFilters({
234+
...filters,
235+
[key]: value,
236+
})
228237
}}
229238
onResetFilters={() => {
230-
console.log('reset')
239+
setFilters({})
231240
}}
232241
/>
233242
{/* <PageDivider /> */}
234-
{isLoading && <LoadingCircles />}
235-
{!isLoading && (
243+
{isLoading && <LoadingCircles className={styles.centered} />}
244+
{!isLoading && winnings.length > 0 && (
236245
<PaymentsTable
237246
payments={winnings}
238247
onPayMeClick={async function onPayMeClicked(
@@ -248,6 +257,15 @@ const ListView: FC<ListViewProps> = (props: ListViewProps) => {
248257
}}
249258
/>
250259
)}
260+
{!isLoading && winnings.length === 0 && (
261+
<div className={styles.centered}>
262+
<p className='body-main'>
263+
{Object.keys(filters).length === 0
264+
? 'Your future earnings will appear here — explore Topcoder\'s opportunities to start making an impact!'
265+
: 'No payments match your filters.'}
266+
</p>
267+
</div>
268+
)}
251269
</Collapsible>
252270
</div>
253271
</div>

src/apps/wallet/src/lib/services/wallet.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,22 @@ export async function getUserTaxFormDetails(): Promise<TaxForm[]> {
4242
return response.data
4343
}
4444

45-
export async function getPayments(userId: string): Promise<WinningDetail[]> {
45+
export async function getPayments(userId: string, filters: Record<string, string[]>): Promise<WinningDetail[]> {
46+
const filteredFilters: Record<string, string> = {}
47+
48+
for (const key in filters) {
49+
if (filters[key].length > 0) {
50+
filteredFilters[key] = filters[key][0]
51+
}
52+
}
53+
4654
const body = JSON.stringify({
4755
winnerId: userId,
56+
...filteredFilters,
4857
})
4958

59+
console.log('Ignoring filters for now', filteredFilters)
60+
5061
const url = `${baseUrl}/user/winnings`
5162
const response = await xhrPostAsync<string, ApiResponse<WinningDetail[]>>(url, body)
5263

0 commit comments

Comments
 (0)