@intersect.mbo/govtool-delegation-pillar
Version:
Delegation Pillar of the GovTool project
127 lines (112 loc) • 3.46 kB
text/typescript
import { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useFormContext } from 'react-hook-form';
import { useModal, usePillarContext } from 'context';
import { downloadJson, ellipsizeText } from 'utils';
import { DRepDataFormValues, MetadataValidationStatus } from 'types';
import { useRegisterVoter } from '../actions/useRegisterVoter';
import { useUpdateVoter } from '../actions/useUpdateVoter';
import { useMetadataStorageErrorModal } from '../modal/useMetadataStorageErrorModal';
export const defaultDRepDataFormValues: DRepDataFormValues = {
doNotList: false,
givenName: '',
objectives: '',
motivations: '',
qualifications: '',
paymentAddress: '',
linkReferences: [{ '@type': 'Link', uri: '', label: '' }],
identityReferences: [{ '@type': 'Identity', uri: '', label: '' }],
storeData: false,
storingURL: '',
};
export const useDRepDataForm = ({
type,
onCancel,
}: {
type: 'register' | 'edit';
onCancel?: () => void;
}) => {
// Local state
const [isLoading, setIsLoading] = useState<boolean>(false);
const [hash, setHash] = useState<string | null>(null);
// App Management
const { validateMetadata, generateMetadata, createJsonLD, createHash } =
usePillarContext();
const { t } = useTranslation();
const { closeModal, openModal } = useModal();
const { registerVoter } = useRegisterVoter();
const { updateVoter } = useUpdateVoter();
const openMetadataStorageErrorModal = useMetadataStorageErrorModal();
// Form
const {
control,
getValues,
handleSubmit,
formState: { errors, isValid },
register,
reset,
watch,
} = useFormContext<DRepDataFormValues>();
const givenName = watch('givenName');
const isError = Object.keys(errors).length > 0;
// Navigation
const backToForm = useCallback(() => {
window.scrollTo(0, 0);
if (onCancel) onCancel();
closeModal();
}, [onCancel]);
const onClickDownloadJson = async () => {
const { linkReferences, identityReferences, ...rest } = getValues();
const json = createJsonLD({
...rest,
references: [...(linkReferences ?? []), ...(identityReferences ?? [])],
});
setHash(createHash(json));
downloadJson(json, ellipsizeText(givenName, 16, ''));
};
const showLoadingModal = useCallback(() => {
openModal({
type: 'loadingModal',
state: {
title: t('modals.pendingValidation.title'),
message: t('modals.pendingValidation.message'),
dataTestId: 'storing-information-loading',
},
});
}, []);
const onSubmit = useCallback(
async (data: DRepDataFormValues) => {
const uri = data.storingURL;
try {
if (!hash) throw MetadataValidationStatus.INVALID_HASH;
setIsLoading(true);
showLoadingModal();
await validateMetadata(uri, hash);
if (type === 'register') await registerVoter({ hash, uri });
else await updateVoter({ hash, uri });
} catch (error: any) {
openMetadataStorageErrorModal({
error,
onContinueAction: backToForm,
});
} finally {
setIsLoading(false);
}
},
[registerVoter, updateVoter, hash]
);
return {
control,
errors,
generateMetadata,
getValues,
isError,
isSubmitting: isLoading,
isValid,
onClickDownloadJson,
register,
onSubmit: handleSubmit(onSubmit),
watch,
reset,
};
};