Skip to content

Commit d87c6f3

Browse files
[Human App] Add modal for Thirstyfi info (#3580)
Co-authored-by: portuu3 <[email protected]>
1 parent 29d7a04 commit d87c6f3

File tree

13 files changed

+420
-28
lines changed

13 files changed

+420
-28
lines changed

packages/apps/human-app/frontend/src/modules/worker/jobs/available-jobs/components/mobile/available-jobs-assign-job-button-mobile.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
import { t } from 'i18next';
2+
import { useParams } from 'react-router-dom';
23
import { TableButton } from '@/shared/components/ui/table-button';
34
import { useJobsNotifications } from '../../../hooks';
45
import { useAssignJobMutation } from '../../hooks/use-assign-job';
56
import { type AssignJobBody } from '../../../types';
7+
import { useAddThirstyfiInfoModal } from '../../hooks/use-add-thirstyfi-info-modal';
8+
9+
const THIRSTYFI_ADDRESS = '0x5C08438d7d18734c5ee42ECAf81FB1D6A922A9cC';
610

711
export function AvailableJobsAssignJobButtonMobile({
812
assignJobPayload,
913
}: Readonly<{
1014
assignJobPayload: AssignJobBody;
1115
}>) {
16+
const { address: oracleAddress } = useParams<{ address: string }>();
17+
const { openModal } = useAddThirstyfiInfoModal();
1218
const { onJobAssignmentError, onJobAssignmentSuccess } =
1319
useJobsNotifications();
1420

@@ -20,13 +26,17 @@ export function AvailableJobsAssignJobButtonMobile({
2026
[`assignJob-${assignJobPayload.escrow_address}`]
2127
);
2228

29+
const isThirstyfi = oracleAddress === THIRSTYFI_ADDRESS;
30+
2331
return (
2432
<TableButton
2533
color="secondary"
2634
fullWidth
2735
loading={isPending}
2836
onClick={() => {
29-
assignJobMutation(assignJobPayload);
37+
isThirstyfi
38+
? openModal({ ...assignJobPayload })
39+
: assignJobMutation(assignJobPayload);
3040
}}
3141
size="small"
3242
sx={{

packages/apps/human-app/frontend/src/modules/worker/jobs/available-jobs/components/mobile/available-jobs-list-mobile.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ export function AvailableJobsListMobile() {
7272
sx={{
7373
textOverflow: 'ellipsis',
7474
overflow: 'hidden',
75-
whiteSpace: 'wrap',
75+
whiteSpace: 'normal',
76+
wordBreak: 'break-word',
77+
overflowWrap: 'anywhere',
7678
}}
7779
variant="subtitle1"
7880
>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/* eslint-disable camelcase -- ...*/
2+
import { useModal } from '@/shared/contexts/modal-context';
3+
import { ThirstyfiInfoModal } from '../thirstyfi-info-modal';
4+
5+
interface AddThirstyfiInfoModalProps {
6+
escrow_address: string;
7+
chain_id: number;
8+
}
9+
10+
export function useAddThirstyfiInfoModal() {
11+
const { openModal, closeModal } = useModal();
12+
13+
return {
14+
openModal: ({ escrow_address, chain_id }: AddThirstyfiInfoModalProps) => {
15+
openModal({
16+
content: (
17+
<ThirstyfiInfoModal
18+
escrow_address={escrow_address}
19+
chain_id={chain_id}
20+
onClose={closeModal}
21+
/>
22+
),
23+
});
24+
},
25+
};
26+
}

packages/apps/human-app/frontend/src/modules/worker/jobs/available-jobs/hooks/use-get-available-jobs-columns.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { MRT_ColumnDef } from 'material-react-table';
33
import { t } from 'i18next';
44
import { Grid } from '@mui/material';
55
import { useMemo } from 'react';
6+
import { useParams } from 'react-router-dom';
67
import { getNetworkName } from '@/modules/smart-contracts/get-network-name';
78
import { Chip } from '@/shared/components/ui/chip';
89
import { TableButton } from '@/shared/components/ui/table-button';
@@ -17,13 +18,18 @@ import {
1718
} from '../components';
1819
import { type AvailableJob } from '../../types';
1920
import { useAssignJobMutation } from './use-assign-job';
21+
import { useAddThirstyfiInfoModal } from './use-add-thirstyfi-info-modal';
2022

2123
const COL_SIZE = 100;
2224
const COL_SIZE_LG = 200;
25+
const THIRSTYFI_ADDRESS = '0x5C08438d7d18734c5ee42ECAf81FB1D6A922A9cC';
2326

2427
export const useGetAvailableJobsColumns = (
2528
chainIdsEnabled: number[]
2629
): MRT_ColumnDef<AvailableJob>[] => {
30+
const { openModal } = useAddThirstyfiInfoModal();
31+
const { address: oracleAddress } = useParams<{ address: string }>();
32+
2733
return useMemo(
2834
() => [
2935
{
@@ -122,15 +128,17 @@ export const useGetAvailableJobsColumns = (
122128
[`assignJob-${escrow_address}`]
123129
);
124130

131+
const isThirstyfi = oracleAddress === THIRSTYFI_ADDRESS;
132+
125133
return (
126134
<Grid sx={{ display: 'flex', justifyContent: 'flex-end' }}>
127135
<TableButton
136+
sx={{ width: '94px' }}
128137
loading={isPending}
129138
onClick={() => {
130-
assignJobMutation({ escrow_address, chain_id });
131-
}}
132-
sx={{
133-
width: '94px',
139+
isThirstyfi
140+
? openModal({ escrow_address, chain_id })
141+
: assignJobMutation({ escrow_address, chain_id });
134142
}}
135143
>
136144
{t('worker.jobs.selectJob')}
@@ -140,6 +148,6 @@ export const useGetAvailableJobsColumns = (
140148
},
141149
},
142150
],
143-
[chainIdsEnabled]
151+
[chainIdsEnabled, openModal, oracleAddress]
144152
);
145153
};
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/* eslint-disable camelcase -- ...*/
2+
import { z } from 'zod';
3+
import { FormProvider, useForm } from 'react-hook-form';
4+
import Stack from '@mui/material/Stack';
5+
import Typography from '@mui/material/Typography';
6+
import { useTranslation } from 'react-i18next';
7+
import { zodResolver } from '@hookform/resolvers/zod';
8+
import { useQueryClient } from '@tanstack/react-query';
9+
import Link from '@mui/material/Link';
10+
import { Button } from '@/shared/components/ui/button';
11+
import { Input } from '@/shared/components/data-entry/input';
12+
import { useIsMobile } from '@/shared/hooks/use-is-mobile';
13+
import { useJobsNotifications } from '../hooks';
14+
import { useAssignJobMutation } from './hooks/use-assign-job';
15+
16+
interface ThirstyfiInfoModalProps {
17+
escrow_address: string;
18+
chain_id: number;
19+
onClose?: () => void;
20+
}
21+
22+
export function ThirstyfiInfoModal({
23+
escrow_address,
24+
chain_id,
25+
onClose,
26+
}: ThirstyfiInfoModalProps) {
27+
const { t } = useTranslation();
28+
const isMobile = useIsMobile();
29+
30+
const methods = useForm({
31+
defaultValues: {
32+
wallet_address: '',
33+
api_key: '',
34+
api_secret: '',
35+
},
36+
resolver: zodResolver(
37+
z.object({
38+
wallet_address: z
39+
.string()
40+
.trim()
41+
.length(42, t('thirstyfiModal.walletAddressError'))
42+
.regex(/^0x/, t('thirstyfiModal.walletAddressRegexError')),
43+
api_key: z.string().trim().min(1, t('validation.required')),
44+
api_secret: z.string().trim().min(1, t('validation.required')),
45+
})
46+
),
47+
});
48+
49+
const { onJobAssignmentError, onJobAssignmentSuccess } =
50+
useJobsNotifications();
51+
const queryClient = useQueryClient();
52+
53+
const { mutate: assignJobMutation, isPending } = useAssignJobMutation(
54+
{
55+
onSuccess: () => {
56+
const queryKey = isMobile
57+
? ['availableJobsInfinite']
58+
: ['availableJobs'];
59+
onJobAssignmentSuccess();
60+
void queryClient.invalidateQueries({ queryKey }).then(() => {
61+
methods.reset();
62+
onClose?.();
63+
});
64+
},
65+
onError: onJobAssignmentError,
66+
},
67+
[`assignJob-${escrow_address}`]
68+
);
69+
70+
const onSubmit = (data: {
71+
wallet_address: string;
72+
api_key: string;
73+
api_secret: string;
74+
}) => {
75+
assignJobMutation({ escrow_address, chain_id, ...data });
76+
};
77+
78+
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
79+
void methods.handleSubmit(onSubmit)(event);
80+
};
81+
82+
return (
83+
<FormProvider {...methods}>
84+
<form onSubmit={handleSubmit}>
85+
<Stack gap={3}>
86+
<Typography variant="h4" textAlign="center">
87+
{t('thirstyfiModal.title')}
88+
</Typography>
89+
<Typography variant="h6" textAlign="center">
90+
{t('thirstyfiModal.tutorialText1')}
91+
<Link
92+
href="https://thirsty.fi"
93+
target="_blank"
94+
rel="noopener noreferrer"
95+
>
96+
{t('thirstyfiModal.tutorialLink')}
97+
</Link>
98+
{t('thirstyfiModal.tutorialText2')}
99+
</Typography>
100+
<Stack gap={0.5}>
101+
<Input
102+
fullWidth
103+
label={t('thirstyfiModal.walletAddress')}
104+
name="wallet_address"
105+
/>
106+
<Typography variant="caption" color="text.secondary">
107+
{t('thirstyfiModal.walletAddressHelp', {
108+
defaultValue: t('thirstyfiModal.walletAddressTooltip'),
109+
})}
110+
</Typography>
111+
</Stack>
112+
<Stack gap={0.5}>
113+
<Input
114+
fullWidth
115+
label={t('thirstyfiModal.apiKey')}
116+
name="api_key"
117+
/>
118+
<Typography variant="caption" color="text.secondary">
119+
{t('thirstyfiModal.apiKeyHelp', {
120+
defaultValue: t('thirstyfiModal.apiKeyTooltip'),
121+
})}
122+
</Typography>
123+
</Stack>
124+
<Stack gap={0.5}>
125+
<Input
126+
fullWidth
127+
label={t('thirstyfiModal.apiSecret')}
128+
name="api_secret"
129+
/>
130+
<Typography variant="caption" color="text.secondary">
131+
{t('thirstyfiModal.apiSecretHelp', {
132+
defaultValue: t('thirstyfiModal.apiSecretTooltip'),
133+
})}
134+
</Typography>
135+
</Stack>
136+
<Button variant="contained" type="submit" loading={isPending}>
137+
{t('thirstyfiModal.submitBtn')}
138+
</Button>
139+
</Stack>
140+
</form>
141+
</FormProvider>
142+
);
143+
}

packages/apps/human-app/frontend/src/modules/worker/jobs/components/my-jobs-table-actions.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ export function MyJobsTableActions({
3535
>
3636
{t('worker.jobs.solve')}
3737
</TableButton>
38-
<MoreButton job={job} isDisabled={isDisabled} />
38+
{job.escrow_address !== 'thirstyfi-task' && (
39+
<MoreButton job={job} isDisabled={isDisabled} />
40+
)}
3941
</>
4042
);
4143
}

packages/apps/human-app/frontend/src/modules/worker/jobs/components/reward-amount.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,21 @@ export function RewardAmount({
1414
if (!(reward_amount !== undefined && reward_token)) {
1515
return '';
1616
}
17-
const hasDecimals =
18-
Number(reward_amount) - Math.floor(Number(reward_amount)) !== 0;
17+
const parsedReward = Number(reward_amount);
18+
const isNumeric = Number.isFinite(parsedReward);
19+
if (!isNumeric) {
20+
return (
21+
<Typography color={color} variant="body2">
22+
{`${reward_amount} ${reward_token}`}
23+
</Typography>
24+
);
25+
}
26+
const hasDecimals = parsedReward - Math.floor(parsedReward) !== 0;
1927
if (hasDecimals) {
2028
return (
2129
<Tooltip title={`${reward_amount} ${reward_token}`}>
2230
<Typography color={color} variant="body2">
23-
{`${Number(reward_amount).toFixed(2)} ${reward_token}`}
31+
{`${parsedReward.toFixed(2)} ${reward_token}`}
2432
</Typography>
2533
</Tooltip>
2634
);

packages/apps/human-app/frontend/src/shared/i18n/en.json

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,22 @@
438438
"image_skeletons_from_boxes": "Skeletons from Bounding Boxes",
439439
"image_polygons": "Polygons",
440440
"audio_transcription": "Audio Transcription",
441-
"audio_attribute_annotation": "Audio Attribute Annotation"
441+
"audio_attribute_annotation": "Audio Attribute Annotation",
442+
"thirstyfi": "ThirstyFi"
443+
},
444+
"thirstyfiModal": {
445+
"title": "This information is required to participate in this task",
446+
"tutorialText1": "Before filling out the form below, please checkout ",
447+
"tutorialText2": " for instructions.",
448+
"tutorialLink": "thirsty.fi",
449+
"walletAddress": "Wallet address",
450+
"walletAddressTooltip": "Your EVM wallet address on Polygon network. Used to receive the rewards.",
451+
"apiKey": "API key",
452+
"apiKeyTooltip": "Your exchange API key (read account details is enough). Stored encrypted and only used server-side to fetch your balance.",
453+
"apiSecret": "API secret",
454+
"apiSecretTooltip": "Your exchange API secret. Stored encrypted and only used server-side to fetch your balance.",
455+
"submitBtn": "Submit",
456+
"walletAddressError": "Wallet address must be exactly 42 characters",
457+
"walletAddressRegexError": "Wallet address must start with 0x"
442458
}
443459
}

0 commit comments

Comments
 (0)