diff --git a/web-components/src/components/fixed-footer/SaveFooter.tsx b/web-components/src/components/fixed-footer/SaveFooter.tsx index d7a5b1c2a5..834ecb4add 100644 --- a/web-components/src/components/fixed-footer/SaveFooter.tsx +++ b/web-components/src/components/fixed-footer/SaveFooter.tsx @@ -1,8 +1,6 @@ import React from 'react'; -import { useTheme } from '@mui/material'; import Grid from '@mui/material/Grid'; import LinearProgress from '@mui/material/LinearProgress'; -import { Theme } from '@mui/material/styles'; import { makeStyles, withStyles } from 'tss-react/mui'; import { TextButton } from '../buttons/TextButton'; @@ -68,7 +66,6 @@ const SaveFooter: React.FC> = ({ ...props }) => { const { classes } = useStyles({ hideProgress }); - const theme: Theme = useTheme(); return ( diff --git a/web-marketplace/src/components/molecules/MetadataJSONField.tsx b/web-marketplace/src/components/molecules/MetadataJSONField.tsx index afe07624a5..1f8ca2f846 100644 --- a/web-marketplace/src/components/molecules/MetadataJSONField.tsx +++ b/web-marketplace/src/components/molecules/MetadataJSONField.tsx @@ -1,4 +1,3 @@ -import React, { useEffect, useState } from 'react'; import { Trans } from '@lingui/macro'; import { Box } from '@mui/material'; import { Field, useFormikContext } from 'formik'; @@ -8,16 +7,11 @@ import InputLabel from 'web-components/src/components/inputs/InputLabel'; import { Body } from 'web-components/src/components/typography'; import { CreditBasicsFormValues } from '../../features/ecocredit/CreateBatchBySteps/CreateBatchMultiStepForm/CreditBasics'; -import { ClassID } from '../../types/ledger/ecocredit'; - -// TODO -// Make this component more generic, so that it doesn't depend -// on specific types/interfaces of a particular form. interface FieldProps { name?: string; required?: boolean; - classId: ClassID; + classId: string; } export function MetadataJSONField({ @@ -27,27 +21,12 @@ export function MetadataJSONField({ ...props }: FieldProps): JSX.Element { const { - setFieldValue, - setFieldTouched, values: { metadata }, } = useFormikContext(); - const [formikName, setFormikName] = useState('loading'); - - useEffect(() => { - // reset metadata if classId changes and still in Object form - if (typeof metadata !== 'string' || formikName === 'loading') { - setFieldValue(name, ''); - // using this timeout fixes a timing bug when transitioning from metadata Object - setTimeout(() => { - setFormikName(name); - setFieldTouched(name, false); - }, 700); - } - }, [classId, formikName, metadata, name, setFieldTouched, setFieldValue]); return ( - {formikName === name && typeof metadata === 'string' ? ( + {typeof metadata === 'string' ? ( <> Metadata @@ -60,7 +39,7 @@ export function MetadataJSONField({ 0 ? handleBack : undefined} onSave={submitForm} - saveText={activeStep === 2 ? _(SUBMIT_TEXT) : ''} + saveText={activeStep === 2 ? _(SUBMIT_TEXT) : _(SAVE_TEXT)} saveExitText={activeStep === 2 ? _(SAVE_EXIT_TEXT) : ''} saveDisabled={!isValid || isSubmitting} percentComplete={percentComplete} diff --git a/web-marketplace/src/features/ecocredit/CreateBatchBySteps/CreateBatchMultiStepForm/CreditBasics.tsx b/web-marketplace/src/features/ecocredit/CreateBatchBySteps/CreateBatchMultiStepForm/CreditBasics.tsx index 19bdaf46a4..0adbc12d9d 100644 --- a/web-marketplace/src/features/ecocredit/CreateBatchBySteps/CreateBatchMultiStepForm/CreditBasics.tsx +++ b/web-marketplace/src/features/ecocredit/CreateBatchBySteps/CreateBatchMultiStepForm/CreditBasics.tsx @@ -30,7 +30,6 @@ import { MetadataJSONField } from '../../../../components/molecules'; import useQueryProjectsByIssuer from '../../../../hooks/useQueryProjectsByIssuer'; import { useWallet } from '../../../../lib/wallet/wallet'; import useSaveProjectSelectedOption from '../hooks/useSaveProjectSelectedOption'; -import useUpdateProjectClass from '../hooks/useUpdateProjectClass'; import useUpdateProjectOptions from '../hooks/useUpdateProjectOptions'; export interface CreditBasicsFormValues { @@ -163,13 +162,15 @@ export default function CreditBasics({ const { values, validateForm } = useFormikContext(); const { projectId } = values; - const { classId, isVCS } = useUpdateProjectClass(projectId); + + const classId = projectId.split('-')[0]; + const isVCS = classId === 'C01'; + const projectOptions = useUpdateProjectOptions(projects); useSaveProjectSelectedOption({ projectId, projectOptions, - projects, saveProjectOptionSelected, }); diff --git a/web-marketplace/src/features/ecocredit/CreateBatchBySteps/hooks/useSaveProjectSelectedOption.ts b/web-marketplace/src/features/ecocredit/CreateBatchBySteps/hooks/useSaveProjectSelectedOption.ts index 699f154b1d..8800c7fa58 100644 --- a/web-marketplace/src/features/ecocredit/CreateBatchBySteps/hooks/useSaveProjectSelectedOption.ts +++ b/web-marketplace/src/features/ecocredit/CreateBatchBySteps/hooks/useSaveProjectSelectedOption.ts @@ -2,27 +2,25 @@ import { useEffect } from 'react'; import type { Option } from 'web-components/src/components/inputs/SelectTextField'; -import type { ProjectWithMetadataObj as Project } from '../../../../types/ledger/ecocredit'; - interface Props { projectId: string; projectOptions: Option[]; - projects: Project[]; saveProjectOptionSelected: (isFound: Option) => void; } export default function useSaveProjectSelectedOption({ projectId, projectOptions, - projects, saveProjectOptionSelected, }: Props): void { useEffect(() => { - if (!projectId || !projects.length) return; - + if (!projectId) return; const isFound = projectOptions?.find( item => item.value.toString() === projectId.toString(), ); if (isFound) saveProjectOptionSelected(isFound); - }, [projectId, projectOptions, projects, saveProjectOptionSelected]); + // adding projectOptions to dep array would cause infinite re-renders because it's an array, + // it's ok since at the time projectId changes, projectOptions has became stable + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [projectId, saveProjectOptionSelected]); } diff --git a/web-marketplace/src/features/ecocredit/CreateBatchBySteps/hooks/useUpdateProjectClass.ts b/web-marketplace/src/features/ecocredit/CreateBatchBySteps/hooks/useUpdateProjectClass.ts deleted file mode 100644 index d95cdcb426..0000000000 --- a/web-marketplace/src/features/ecocredit/CreateBatchBySteps/hooks/useUpdateProjectClass.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { useEffect, useState } from 'react'; - -import type { ClassID } from 'types/ledger/ecocredit'; - -export default function useUpdateProjectClass(projectId: string): { - classId: ClassID | undefined; - isVCS: boolean | undefined; -} { - const [classId, setClassId] = useState(); - const [isVCS, setIsVCS] = useState(); - - useEffect(() => { - if (!projectId) return; - const _classId = projectId.split('-')[0] as ClassID; - setClassId(_classId); - setIsVCS(_classId === 'C01'); - }, [projectId]); - - return { classId, isVCS }; -} diff --git a/web-marketplace/src/features/ecocredit/CreateBatchBySteps/hooks/useUpdateProjectOptions.ts b/web-marketplace/src/features/ecocredit/CreateBatchBySteps/hooks/useUpdateProjectOptions.ts index cda6794399..df807c7e57 100644 --- a/web-marketplace/src/features/ecocredit/CreateBatchBySteps/hooks/useUpdateProjectOptions.ts +++ b/web-marketplace/src/features/ecocredit/CreateBatchBySteps/hooks/useUpdateProjectOptions.ts @@ -1,4 +1,4 @@ -import { useEffect, useMemo, useState } from 'react'; +import { useMemo } from 'react'; import { msg } from '@lingui/macro'; import { useLingui } from '@lingui/react'; import { startCase } from 'lodash'; @@ -16,25 +16,28 @@ const getDefaultProjectOption = (_: TranslatorType) => ({ export default function useUpdateProjectOptions(projects: Project[]): Option[] { const { _ } = useLingui(); - const [projectOptions, setProjectOptions] = useState([]); const defaultProjectOption = useMemo(() => getDefaultProjectOption(_), [_]); - useEffect(() => { - if (!projects.length) return; - - const options = - projects.map((project: Project) => { - const projectId = project.id; - const projectName = startCase(project?.metadata?.['schema:name'] || ''); - const projectNameWithId = `${projectName} (${projectId})`; - return { - label: projectName ? projectNameWithId : projectId, - value: projectId, - }; - }) || []; - - setProjectOptions([defaultProjectOption, ...options]); - }, [defaultProjectOption, projects, setProjectOptions]); + const projectOptions = useMemo( + () => + projects.length + ? [ + defaultProjectOption, + ...(projects.map((project: Project) => { + const projectId = project.id; + const projectName = startCase( + project?.metadata?.['schema:name'] || '', + ); + const projectNameWithId = `${projectName} (${projectId})`; + return { + label: projectName ? projectNameWithId : projectId, + value: projectId, + }; + }) || []), + ] + : [], + [defaultProjectOption, projects], + ); return projectOptions; } diff --git a/web-marketplace/src/hooks/useQueryProjectsByIssuer.ts b/web-marketplace/src/hooks/useQueryProjectsByIssuer.ts index 6aa3f33b4c..c154a1a599 100644 --- a/web-marketplace/src/hooks/useQueryProjectsByIssuer.ts +++ b/web-marketplace/src/hooks/useQueryProjectsByIssuer.ts @@ -42,11 +42,13 @@ export default function useQueryProjectsByIssuer(issuer?: string): Project[] { }), ) || [], }); + const projects = projectsResults .map(res => { return res.data?.projects; }) .flat(); + const projectsLoading = projectsResults.some(res => res.isLoading); const projectsMetadatasResults = useQueries({ queries: projects.map(project => @@ -62,8 +64,10 @@ export default function useQueryProjectsByIssuer(issuer?: string): Project[] { queryResult => queryResult.data, ); - return projects.map((project, i) => ({ - ...(project as ProjectInfo), - metadata: projectsMetadata[i], - })); + return projectsLoading + ? [] + : projects.map((project, i) => ({ + ...(project as ProjectInfo), + metadata: projectsMetadata[i], + })); } diff --git a/web-marketplace/src/types/ledger/ecocredit.ts b/web-marketplace/src/types/ledger/ecocredit.ts index f8323cca5c..cb656c7dc8 100644 --- a/web-marketplace/src/types/ledger/ecocredit.ts +++ b/web-marketplace/src/types/ledger/ecocredit.ts @@ -38,8 +38,6 @@ export interface BatchInfoWithSupply txhash?: string; } -export type ClassID = 'C01' | 'C02' | 'C03'; - type GenericObject = { [key: string]: any }; export interface ProjectWithMetadataObj extends Omit {