Skip to content

Commit

Permalink
Merge pull request #313 from 1Hive/retain-form-content
Browse files Browse the repository at this point in the history
done for challenge modal and schedule claim modal
  • Loading branch information
Corantin committed Jun 20, 2022
2 parents bb44e1d + cb60e86 commit f09a50e
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 17 deletions.
26 changes: 21 additions & 5 deletions packages/react-app/src/components/modals/challenge-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable no-nested-ternary */
import { Button, useToast, IconFlag } from '@1hive/1hive-ui';
import { noop, uniqueId } from 'lodash-es';
import { useState, useRef, useEffect, useMemo } from 'react';
import { debounce, noop, uniqueId } from 'lodash-es';
import { useState, useRef, useEffect, useMemo, useCallback } from 'react';
import styled from 'styled-components';
import { Formik, Form, FormikErrors } from 'formik';
import { ClaimModel } from 'src/models/claim.model';
Expand Down Expand Up @@ -64,17 +64,26 @@ const ButtonLinkStyled = styled(Button)`
type Props = {
claim: ClaimModel;
challengeDeposit: TokenAmountModel;
challengeData?: ChallengeModel;
onClose?: ModalCallback;
};

export default function ChallengeModal({ claim, challengeDeposit, onClose = noop }: Props) {
const emptyChallengeData = {} as ChallengeModel;

export default function ChallengeModal({
claim,
challengeData = emptyChallengeData,
challengeDeposit,
onClose = noop,
}: Props) {
const toast = useToast();
const [opened, setOpened] = useState(false);
const [isEnoughBalance, setIsEnoughBalance] = useState(false);
const [isFeeDepositSameToken, setIsFeeDepositSameToken] = useState<boolean>();
const [challengeFee, setChallengeFee] = useState<TokenAmountModel | undefined>(undefined);
const [isFormValid, setIsFormValid] = useState(false);
const [showPreview, setShowPreview] = useState(false);
const [challengeDataState, setChallengeDataState] = useState<ChallengeModel>(challengeData);
const { setTransaction } = useTransactionContext();
const formRef = useRef<HTMLFormElement>(null);
const { walletAddress } = useWallet();
Expand All @@ -88,6 +97,10 @@ export default function ChallengeModal({ claim, challengeDeposit, onClose = noop
};
fetchFee();
}, []);
const debounceSave = useCallback(
debounce((data: ChallengeModel) => setChallengeDataState(data), 500),
[],
);

useEffect(() => {
if (challengeFee)
Expand Down Expand Up @@ -175,6 +188,9 @@ export default function ChallengeModal({ claim, challengeDeposit, onClose = noop
: ENUM_TRANSACTION_STATUS.Failed,
});
if (!challengeTxReceipt?.status) throw new Error('Failed to challenge the quest');
if (isMountedRef.current) {
setChallengeDataState(emptyChallengeData);
}
} catch (e: any) {
setTransaction(
(oldTx) =>
Expand All @@ -192,7 +208,7 @@ export default function ChallengeModal({ claim, challengeDeposit, onClose = noop
const validate = (values: ChallengeModel) => {
const errors = {} as FormikErrors<ChallengeModel>;
if (!values.reason) errors.reason = 'Challenge reason is required';

debounceSave(values);
setIsFormValid(Object.keys(errors).length === 0);
return errors;
};
Expand Down Expand Up @@ -270,7 +286,7 @@ export default function ChallengeModal({ claim, challengeDeposit, onClose = noop
isOpen={opened}
>
<Formik
initialValues={{ reason: '' } as any}
initialValues={{ reason: challengeDataState.reason ?? '' } as any}
onSubmit={(values) => {
validate(values); // validate one last time before submiting
if (isFormValid) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@ export default function QuestModal({

if (data.expireTime.getTime() < Date.now())
errors.expireTime = 'Expiration have to be later than now';

debounceSave(data);

setIsFormValid(Object.keys(errors).length === 0);
Expand Down
42 changes: 31 additions & 11 deletions packages/react-app/src/components/modals/schedule-claim-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
/* eslint-disable no-nested-ternary */
import { Button } from '@1hive/1hive-ui';
import { noop, uniqueId } from 'lodash-es';
import { useState, useRef, useMemo } from 'react';
import { debounce, noop, uniqueId } from 'lodash-es';
import { useState, useRef, useMemo, useCallback } from 'react';
import styled from 'styled-components';
import { Formik, Form } from 'formik';
import { ENUM_TRANSACTION_STATUS, ENUM, DEFAULT_CLAIM_EXECUTION_DELAY_MS } from 'src/constants';
import {
ENUM_TRANSACTION_STATUS,
ENUM,
DEFAULT_CLAIM_EXECUTION_DELAY_MS,
ENUM_QUEST_STATE,
} from 'src/constants';
import { TokenAmountModel } from 'src/models/token-amount.model';
import { ClaimModel } from 'src/models/claim.model';
import { useTransactionContext } from 'src/contexts/transaction.context';
Expand Down Expand Up @@ -74,20 +79,25 @@ type Props = {
questAddress: string;
questTotalBounty?: TokenAmountModel | null;
claimDeposit: TokenAmountModel;
claimData?: ClaimModel;
onClose?: ModalCallback;
};

const emptyClaimData = {
state: ENUM_QUEST_STATE.Draft,
} as ClaimModel;
export default function ScheduleClaimModal({
questAddress,
questTotalBounty,
claimDeposit,
claimData = emptyClaimData,
onClose = noop,
}: Props) {
const { walletAddress } = useWallet();
const [opened, setOpened] = useState(false);
const [isFormValid, setIsFormValid] = useState(false);
const [isEnoughBalance, setIsEnoughBalance] = useState(false);
const [showPreview, setShowPreview] = useState(false);
const [claimDataState, setClaimDataState] = useState<ClaimModel>(claimData);
const formRef = useRef<HTMLFormElement>(null);
const { setTransaction } = useTransactionContext();
const modalId = useMemo(() => uniqueId('schedule-claim-modal'), []);
Expand All @@ -97,8 +107,12 @@ export default function ScheduleClaimModal({
setOpened(false);
onClose(succeed);
};
const debounceSave = useCallback(
debounce((data: ClaimModel) => setClaimDataState(data), 500),
[], // will be created only once initially
);

const validate = (values: ClaimModel & { claimAll: boolean }) => {
const validate = (values: ClaimModel) => {
const errors = {} as FormErrors<ClaimModel>;
if (!values.evidence) errors.evidence = 'Evidence of completion is required';
if (!values.claimAll) {
Expand All @@ -114,11 +128,12 @@ export default function ScheduleClaimModal({
errors.playerAddress = 'Player address is not valid';
}
}
debounceSave(values);
setIsFormValid(Object.keys(errors).length === 0);
return errors;
};

const onClaimSubmit = (values: ClaimModel & { claimAll: boolean }) => {
const onClaimSubmit = (values: ClaimModel) => {
validate(values); // Validate one last time before submitting
if (isFormValid) {
if (values.claimAll) {
Expand Down Expand Up @@ -176,6 +191,9 @@ export default function ScheduleClaimModal({
});
if (!scheduleReceipt?.status)
throw new Error('Failed to schedule the claim, please retry in a few seconds');
if (isMountedRef.current) {
setClaimDataState(emptyClaimData);
}
} catch (e: any) {
if (isMountedRef.current) {
setTransaction(
Expand Down Expand Up @@ -210,11 +228,13 @@ export default function ScheduleClaimModal({
<Formik
initialValues={
{
evidence: '',
claimedAmount: { parsedAmount: 0, token: questTotalBounty?.token } as TokenAmountModel,
claimAll: false,
contactInformation: undefined,
playerAddress: undefined,
evidence: claimDataState.evidence ?? '',
claimedAmount:
claimDataState.claimedAmount ??
({ parsedAmount: 0, token: questTotalBounty?.token } as TokenAmountModel),
claimAll: claimDataState.claimAll ?? false,
contactInformation: claimDataState.contactInformation,
playerAddress: claimDataState.playerAddress,
} as any
}
onSubmit={(values) => {
Expand Down

0 comments on commit f09a50e

Please sign in to comment.