Commit aaf56ae0 authored by tom's avatar tom

error and disabled state

parent aa344285
......@@ -5,6 +5,8 @@ import { useForm, FormProvider } from 'react-hook-form';
import type { FormFields } from './types';
import delay from 'lib/delay';
import ContractVerificationFieldMethod from './fields/ContractVerificationFieldMethod';
import ContractVerificationFlattenSourceCode from './methods/ContractVerificationFlattenSourceCode';
import ContractVerificationMultiPartFile from './methods/ContractVerificationMultiPartFile';
......@@ -12,26 +14,29 @@ import ContractVerificationSourcify from './methods/ContractVerificationSourcify
import ContractVerificationStandardInput from './methods/ContractVerificationStandardInput';
import ContractVerificationVyperContract from './methods/ContractVerificationVyperContract';
const METHODS = {
flatten_source_code: <ContractVerificationFlattenSourceCode/>,
standard_input: <ContractVerificationStandardInput/>,
sourcify: <ContractVerificationSourcify/>,
multi_part_file: <ContractVerificationMultiPartFile/>,
vyper_contract: <ContractVerificationVyperContract/>,
};
const ContractVerificationForm = () => {
const formApi = useForm<FormFields>();
const { control, handleSubmit, watch } = formApi;
const formApi = useForm<FormFields>({
mode: 'onBlur',
});
const { control, handleSubmit, watch, formState } = formApi;
const onFormSubmit: SubmitHandler<FormFields> = React.useCallback((data) => {
const onFormSubmit: SubmitHandler<FormFields> = React.useCallback(async(data) => {
// eslint-disable-next-line no-console
console.log('__>__', data);
await delay(5_000);
}, []);
const methods = React.useMemo(() => ({
flatten_source_code: <ContractVerificationFlattenSourceCode control={ control }/>,
standard_input: <ContractVerificationStandardInput control={ control }/>,
sourcify: <ContractVerificationSourcify control={ control }/>,
multi_part_file: <ContractVerificationMultiPartFile control={ control }/>,
vyper_contract: <ContractVerificationVyperContract control={ control }/>,
}), [ control ]);
const method = watch('method');
const content = methods[method] || null;
const content = METHODS[method] || null;
return (
<FormProvider { ...formApi }>
......@@ -40,7 +45,7 @@ const ContractVerificationForm = () => {
onSubmit={ handleSubmit(onFormSubmit) }
mt={ 12 }
>
<ContractVerificationFieldMethod control={ control }/>
<ContractVerificationFieldMethod control={ control } isDisabled={ Boolean(method) }/>
{ content }
{ Boolean(method) && (
<Button
......@@ -48,6 +53,9 @@ const ContractVerificationForm = () => {
size="lg"
type="submit"
mt={ 12 }
isDisabled={ !formState.isValid || !formState.isDirty }
isLoading={ formState.isSubmitting }
loadingText="Verify & publish"
>
Verify & publish
</Button>
......
......@@ -7,8 +7,14 @@ interface Props {
}
const ContractVerificationMethod = ({ title, children }: Props) => {
const ref = React.useRef<HTMLDivElement>(null);
React.useEffect(() => {
ref.current?.scrollIntoView({ behavior: 'smooth' });
}, []);
return (
<section>
<section ref={ ref }>
<Text variant="secondary" mt={ 12 } mb={ 5 } fontSize="sm">{ title }</Text>
<Grid columnGap="30px" rowGap={{ base: 2, lg: 4 }} templateColumns={{ base: '1fr', lg: 'minmax(auto, 680px) minmax(0, 340px)' }}>
{ children }
......
import { FormControl, Link, Textarea } from '@chakra-ui/react';
import React from 'react';
import type { ControllerRenderProps, Control } from 'react-hook-form';
import { Controller } from 'react-hook-form';
import type { ControllerRenderProps } from 'react-hook-form';
import { Controller, useFormContext } from 'react-hook-form';
import type { FormFields } from '../types';
......@@ -9,22 +9,21 @@ import InputPlaceholder from 'ui/shared/InputPlaceholder';
import ContractVerificationFormRow from '../ContractVerificationFormRow';
interface Props {
control: Control<FormFields>;
}
const ContractVerificationFieldAbiEncodedArgs = () => {
const { formState, control } = useFormContext<FormFields>();
const ContractVerificationFieldAbiEncodedArgs = ({ control }: Props) => {
const renderControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, 'abi_encoded_args'>}) => {
return (
<FormControl variant="floating" id={ field.name } size={{ base: 'md', lg: 'lg' }}>
<Textarea
{ ...field }
maxLength={ 255 }
isDisabled={ formState.isSubmitting }
/>
<InputPlaceholder text="ABI-encoded Constructor Arguments"/>
</FormControl>
);
}, []);
}, [ formState.isSubmitting ]);
return (
<ContractVerificationFormRow>
......
import { FormControl, Link, Textarea } from '@chakra-ui/react';
import React from 'react';
import type { ControllerRenderProps, Control } from 'react-hook-form';
import { Controller } from 'react-hook-form';
import type { ControllerRenderProps } from 'react-hook-form';
import { useFormContext, Controller } from 'react-hook-form';
import type { FormFields } from '../types';
......@@ -10,23 +10,28 @@ import InputPlaceholder from 'ui/shared/InputPlaceholder';
import ContractVerificationFormRow from '../ContractVerificationFormRow';
interface Props {
control: Control<FormFields>;
isVyper?: boolean;
}
const ContractVerificationFieldCode = ({ control, isVyper }: Props) => {
const ContractVerificationFieldCode = ({ isVyper }: Props) => {
const { formState, control } = useFormContext<FormFields>();
const renderControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, 'code'>}) => {
const error = 'code' in formState.errors ? formState.errors.code : undefined;
return (
<FormControl variant="floating" id={ field.name } isRequired size={{ base: 'md', lg: 'lg' }}>
<Textarea
{ ...field }
isInvalid={ Boolean(error) }
isDisabled={ formState.isSubmitting }
required
maxLength={ 255 }
/>
<InputPlaceholder text="Contract code"/>
<InputPlaceholder text="Contract code" error={ error }/>
</FormControl>
);
}, []);
}, [ formState.errors, formState.isSubmitting ]);
return (
<ContractVerificationFormRow>
......
import { Code, Select, Checkbox } from '@chakra-ui/react';
import React from 'react';
import type { ControllerRenderProps, Control } from 'react-hook-form';
import { Controller } from 'react-hook-form';
import type { ControllerRenderProps } from 'react-hook-form';
import { useFormContext, Controller } from 'react-hook-form';
import type { FormFields } from '../types';
......@@ -20,28 +20,32 @@ const COMPILERS_NIGHTLY = [
];
interface Props {
control: Control<FormFields>;
isVyper?: boolean;
}
const ContractVerificationFieldCompiler = ({ control, isVyper }: Props) => {
const ContractVerificationFieldCompiler = ({ isVyper }: Props) => {
const [ isNightly, setIsNightly ] = React.useState(false);
const { formState, control } = useFormContext<FormFields>();
const handleCheckboxChange = React.useCallback(() => {
setIsNightly(prev => !prev);
}, []);
const renderControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, 'compiler'>}) => {
const error = 'compiler' in formState.errors ? formState.errors.compiler : undefined;
return (
<Select
{ ...field }
size={{ base: 'md', lg: 'lg' }}
placeholder="Compiler"
isInvalid={ Boolean(error) }
isDisabled={ formState.isSubmitting }
>
{ [ ...COMPILERS, ...(isNightly ? COMPILERS_NIGHTLY : []) ].map((option) => <option key={ option } value={ option }>{ option }</option>) }
</Select>
);
}, [ isNightly ]);
}, [ formState.errors, formState.isSubmitting, isNightly ]);
return (
<ContractVerificationFormRow>
......@@ -57,6 +61,7 @@ const ContractVerificationFieldCompiler = ({ control, isVyper }: Props) => {
size="lg"
mt={ 3 }
onChange={ handleCheckboxChange }
isDisabled={ formState.isSubmitting }
>
Include nightly builds
</Checkbox>
......
import React from 'react';
import type { ControllerRenderProps, Control } from 'react-hook-form';
import { Controller } from 'react-hook-form';
import type { ControllerRenderProps } from 'react-hook-form';
import { Controller, useFormContext } from 'react-hook-form';
import type { FormFields } from '../types';
......@@ -8,14 +8,16 @@ import CheckboxInput from 'ui/shared/CheckboxInput';
import ContractVerificationFormRow from '../ContractVerificationFormRow';
interface Props {
control: Control<FormFields>;
}
const ContractVerificationFieldConstArgs = () => {
const { formState, control } = useFormContext<FormFields>();
const ContractVerificationFieldConstArgs = ({ control }: Props) => {
const renderControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, 'constructor_args'>}) => (
<CheckboxInput<FormFields, 'constructor_args'> text="Try to fetch constructor arguments automatically" field={ field }/>
), []);
<CheckboxInput<FormFields, 'constructor_args'>
text="Try to fetch constructor arguments automatically"
field={ field }
isDisabled={ formState.isSubmitting }
/>
), [ formState.isSubmitting ]);
return (
<ContractVerificationFormRow>
......
import { Link, Select } from '@chakra-ui/react';
import React from 'react';
import type { ControllerRenderProps, Control } from 'react-hook-form';
import { Controller } from 'react-hook-form';
import type { ControllerRenderProps } from 'react-hook-form';
import { useFormContext, Controller } from 'react-hook-form';
import type { FormFields } from '../types';
......@@ -13,22 +13,24 @@ const VERSIONS = [
'berlin',
];
interface Props {
control: Control<FormFields>;
}
const ContractVerificationFieldEvmVersion = () => {
const { formState, control } = useFormContext<FormFields>();
const ContractVerificationFieldEvmVersion = ({ control }: Props) => {
const renderControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, 'evm_version'>}) => {
const error = 'evm_version' in formState.errors ? formState.errors.evm_version : undefined;
return (
<Select
{ ...field }
size={{ base: 'md', lg: 'lg' }}
placeholder="EVM Version"
isInvalid={ Boolean(error) }
isDisabled={ formState.isSubmitting }
>
{ VERSIONS.map((option) => <option key={ option } value={ option }>{ option }</option>) }
</Select>
);
}, [ ]);
}, [ formState.errors, formState.isSubmitting ]);
return (
<ContractVerificationFormRow>
......
import React from 'react';
import type { ControllerRenderProps, Control } from 'react-hook-form';
import { Controller } from 'react-hook-form';
import type { ControllerRenderProps } from 'react-hook-form';
import { useFormContext, Controller } from 'react-hook-form';
import type { FormFields } from '../types';
......@@ -8,14 +8,12 @@ import CheckboxInput from 'ui/shared/CheckboxInput';
import ContractVerificationFormRow from '../ContractVerificationFormRow';
interface Props {
control: Control<FormFields>;
}
const ContractVerificationFieldIsYul = () => {
const { formState, control } = useFormContext<FormFields>();
const ContractVerificationFieldIsYul = ({ control }: Props) => {
const renderControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, 'is_yul'>}) => (
<CheckboxInput<FormFields, 'is_yul'> text="Is Yul contract" field={ field }/>
), []);
<CheckboxInput<FormFields, 'is_yul'> text="Is Yul contract" field={ field } isDisabled={ formState.isSubmitting }/>
), [ formState.isSubmitting ]);
return (
<ContractVerificationFormRow>
......
import { Checkbox } from '@chakra-ui/react';
import React from 'react';
import type { Control } from 'react-hook-form';
import { useFieldArray } from 'react-hook-form';
import { useFieldArray, useFormContext } from 'react-hook-form';
import type { FormFields } from '../types';
import ContractVerificationFormRow from '../ContractVerificationFormRow';
import ContractVerificationFieldLibraryItem from './ContractVerificationFieldLibraryItem';
interface Props {
control: Control<FormFields>;
}
const ContractVerificationFieldLibraries = ({ control }: Props) => {
const [ isEnabled, setIsEnabled ] = React.useState(false);
const ContractVerificationFieldLibraries = () => {
const { formState, control } = useFormContext<FormFields>();
const { fields, append, remove, insert } = useFieldArray({
name: 'libraries',
control,
});
const [ isEnabled, setIsEnabled ] = React.useState(fields.length > 0);
const handleCheckboxChange = React.useCallback(() => {
if (!isEnabled) {
......@@ -56,6 +51,7 @@ const ContractVerificationFieldLibraries = ({ control }: Props) => {
fieldsLength={ fields.length }
onAddFieldClick={ handleAddFieldClick }
onRemoveFieldClick={ handleRemoveFieldClick }
error={ 'libraries' in formState.errors ? formState.errors.libraries?.[index] : undefined }
/>
)) }
</>
......
import { Flex, FormControl, Icon, IconButton, Input, Text } from '@chakra-ui/react';
import React from 'react';
import type { Control, ControllerRenderProps } from 'react-hook-form';
import type { Control, ControllerRenderProps, FieldError } from 'react-hook-form';
import { Controller } from 'react-hook-form';
import type { FormFields } from '../types';
......@@ -18,11 +18,15 @@ interface Props {
control: Control<FormFields>;
index: number;
fieldsLength: number;
error?: {
name?: FieldError;
address?: FieldError;
};
onAddFieldClick: (index: number) => void;
onRemoveFieldClick: (index: number) => void;
}
const ContractVerificationFieldLibraryItem = ({ control, index, fieldsLength, onAddFieldClick, onRemoveFieldClick }: Props) => {
const ContractVerificationFieldLibraryItem = ({ control, index, fieldsLength, onAddFieldClick, onRemoveFieldClick, error }: Props) => {
const ref = React.useRef<HTMLDivElement>(null);
const renderNameControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, `libraries.${ number }.name`>}) => {
......@@ -31,24 +35,26 @@ const ContractVerificationFieldLibraryItem = ({ control, index, fieldsLength, on
<Input
{ ...field }
required
isInvalid={ Boolean(error?.name) }
maxLength={ 255 }
/>
<InputPlaceholder text="Library name (.sol file)"/>
<InputPlaceholder text="Library name (.sol file)" error={ error?.name }/>
</FormControl>
);
}, []);
}, [ error?.name ]);
const renderAddressControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, `libraries.${ number }.address`>}) => {
return (
<FormControl variant="floating" id={ field.name } isRequired size={{ base: 'md', lg: 'lg' }}>
<Input
{ ...field }
isInvalid={ Boolean(error?.address) }
required
/>
<InputPlaceholder text="Library address (0x...)"/>
<InputPlaceholder text="Library address (0x...)" error={ error?.address }/>
</FormControl>
);
}, []);
}, [ error?.address ]);
const handleAddButtonClick = React.useCallback(() => {
onAddFieldClick(index);
......
import { chakra, Code, FormControl, Input } from '@chakra-ui/react';
import React from 'react';
import type { ControllerRenderProps, Control } from 'react-hook-form';
import { Controller } from 'react-hook-form';
import type { ControllerRenderProps } from 'react-hook-form';
import { Controller, useFormContext } from 'react-hook-form';
import type { FormFields } from '../types';
......@@ -10,23 +10,28 @@ import InputPlaceholder from 'ui/shared/InputPlaceholder';
import ContractVerificationFormRow from '../ContractVerificationFormRow';
interface Props {
control: Control<FormFields>;
hint?: string;
}
const ContractVerificationFieldName = ({ control, hint }: Props) => {
const ContractVerificationFieldName = ({ hint }: Props) => {
const { formState, control } = useFormContext<FormFields>();
const renderControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, 'name'>}) => {
const error = 'name' in formState.errors ? formState.errors.name : undefined;
return (
<FormControl variant="floating" id={ field.name } isRequired size={{ base: 'md', lg: 'lg' }}>
<Input
{ ...field }
required
isInvalid={ Boolean(error) }
maxLength={ 255 }
isDisabled={ formState.isSubmitting }
/>
<InputPlaceholder text="Contract name"/>
<InputPlaceholder text="Contract name" error={ error }/>
</FormControl>
);
}, []);
}, [ formState.errors, formState.isSubmitting ]);
return (
<ContractVerificationFormRow>
......
import { FormControl, Input } from '@chakra-ui/react';
import React from 'react';
import type { ControllerRenderProps, Control } from 'react-hook-form';
import { Controller } from 'react-hook-form';
import type { ControllerRenderProps } from 'react-hook-form';
import { Controller, useFormContext } from 'react-hook-form';
import type { FormFields } from '../types';
......@@ -10,20 +10,22 @@ import InputPlaceholder from 'ui/shared/InputPlaceholder';
import ContractVerificationFormRow from '../ContractVerificationFormRow';
interface Props {
control: Control<FormFields>;
}
const ContractVerificationFieldOptimization = ({ control }: Props) => {
const ContractVerificationFieldOptimization = () => {
const [ isEnabled, setIsEnabled ] = React.useState(false);
const { formState, control } = useFormContext<FormFields>();
const handleCheckboxChange = React.useCallback(() => {
setIsEnabled(prev => !prev);
}, []);
const renderCheckboxControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, 'is_optimization_enabled'>}) => (
<CheckboxInput<FormFields, 'is_optimization_enabled'> text="Optimization enabled" field={ field } onChange={ handleCheckboxChange }/>
), [ handleCheckboxChange ]);
<CheckboxInput<FormFields, 'is_optimization_enabled'>
text="Optimization enabled"
field={ field }
onChange={ handleCheckboxChange }
isDisabled={ formState.isSubmitting }
/>
), [ formState.isSubmitting, handleCheckboxChange ]);
const renderInputControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, 'optimization_runs'>}) => {
return (
......@@ -32,11 +34,12 @@ const ContractVerificationFieldOptimization = ({ control }: Props) => {
{ ...field }
required
maxLength={ 255 }
isDisabled={ formState.isSubmitting }
/>
<InputPlaceholder text="Optimization runs"/>
</FormControl>
);
}, []);
}, [ formState.isSubmitting ]);
return (
<>
......@@ -53,6 +56,7 @@ const ContractVerificationFieldOptimization = ({ control }: Props) => {
name="optimization_runs"
control={ control }
render={ renderInputControl }
rules={{ required: true }}
/>
</ContractVerificationFormRow>
) }
......
import { Text, Button, Box, chakra } from '@chakra-ui/react';
import React from 'react';
import type { ControllerRenderProps, Control } from 'react-hook-form';
import type { ControllerRenderProps } from 'react-hook-form';
import { Controller, useFormContext } from 'react-hook-form';
import type { FormFields } from '../types';
......@@ -11,7 +11,6 @@ import FileSnippet from 'ui/shared/forms/FileSnippet';
import ContractVerificationFormRow from '../ContractVerificationFormRow';
interface Props {
control: Control<FormFields>;
accept?: string;
multiple?: boolean;
title: string;
......@@ -19,8 +18,8 @@ interface Props {
hint: string;
}
const ContractVerificationFieldSources = ({ control, accept, multiple, title, className, hint }: Props) => {
const { setValue, getValues } = useFormContext();
const ContractVerificationFieldSources = ({ accept, multiple, title, className, hint }: Props) => {
const { setValue, getValues, control, formState } = useFormContext<FormFields>();
const handleFileRemove = React.useCallback((index?: number) => {
if (index === undefined) {
......@@ -43,11 +42,12 @@ const ContractVerificationFieldSources = ({ control, accept, multiple, title, cl
maxW="initial"
onRemove={ handleFileRemove }
index={ index }
isDisabled={ formState.isSubmitting }
/>
)) }
</Box>
);
}, [ handleFileRemove ]);
}, [ formState.isSubmitting, handleFileRemove ]);
const renderControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, 'sources'>}) => (
<>
......@@ -70,6 +70,7 @@ const ContractVerificationFieldSources = ({ control, accept, multiple, title, cl
name="sources"
control={ control }
render={ renderControl }
rules={{ required: true }}
/>
{ hint ? <span>{ hint }</span> : null }
</ContractVerificationFormRow>
......
import React from 'react';
import type { Control } from 'react-hook-form';
import type { FormFields } from '../types';
import ContractVerificationMethod from '../ContractVerificationMethod';
import ContractVerificationFieldCode from '../fields/ContractVerificationFieldCode';
......@@ -13,21 +10,17 @@ import ContractVerificationFieldLibraries from '../fields/ContractVerificationFi
import ContractVerificationFieldName from '../fields/ContractVerificationFieldName';
import ContractVerificationFieldOptimization from '../fields/ContractVerificationFieldOptimization';
interface Props {
control: Control<FormFields>;
}
const ContractVerificationFlattenSourceCode = ({ control }: Props) => {
const ContractVerificationFlattenSourceCode = () => {
return (
<ContractVerificationMethod title="New Solidity/Yul Smart Contract Verification">
<ContractVerificationFieldIsYul control={ control }/>
<ContractVerificationFieldName control={ control }/>
<ContractVerificationFieldCompiler control={ control }/>
<ContractVerificationFieldEvmVersion control={ control }/>
<ContractVerificationFieldOptimization control={ control }/>
<ContractVerificationFieldCode control={ control }/>
<ContractVerificationFieldConstArgs control={ control }/>
<ContractVerificationFieldLibraries control={ control }/>
<ContractVerificationFieldIsYul/>
<ContractVerificationFieldName/>
<ContractVerificationFieldCompiler/>
<ContractVerificationFieldEvmVersion/>
<ContractVerificationFieldOptimization/>
<ContractVerificationFieldCode/>
<ContractVerificationFieldConstArgs/>
<ContractVerificationFieldLibraries/>
</ContractVerificationMethod>
);
};
......
import React from 'react';
import type { Control } from 'react-hook-form';
import type { FormFields } from '../types';
import ContractVerificationMethod from '../ContractVerificationMethod';
import ContractVerificationFieldCompiler from '../fields/ContractVerificationFieldCompiler';
......@@ -10,24 +7,19 @@ import ContractVerificationFieldLibraries from '../fields/ContractVerificationFi
import ContractVerificationFieldOptimization from '../fields/ContractVerificationFieldOptimization';
import ContractVerificationFieldSources from '../fields/ContractVerificationFieldSources';
interface Props {
control: Control<FormFields>;
}
const ContractVerificationMultiPartFile = ({ control }: Props) => {
const ContractVerificationMultiPartFile = () => {
return (
<ContractVerificationMethod title="New Solidity/Yul Smart Contract Verification">
<ContractVerificationFieldCompiler control={ control }/>
<ContractVerificationFieldEvmVersion control={ control }/>
<ContractVerificationFieldOptimization control={ control }/>
<ContractVerificationFieldCompiler/>
<ContractVerificationFieldEvmVersion/>
<ContractVerificationFieldOptimization/>
<ContractVerificationFieldSources
control={ control }
accept=".sol,.yul"
multiple
title="Sources *.sol or *.yul files"
hint="Upload all Solidity or Yul contract source files."
/>
<ContractVerificationFieldLibraries control={ control }/>
<ContractVerificationFieldLibraries/>
</ContractVerificationMethod>
);
};
......
import React from 'react';
import type { Control } from 'react-hook-form';
import type { FormFields } from '../types';
import ContractVerificationMethod from '../ContractVerificationMethod';
import ContractVerificationFieldSources from '../fields/ContractVerificationFieldSources';
interface Props {
control: Control<FormFields>;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const ContractVerificationSourcify = ({ control }: Props) => {
const ContractVerificationSourcify = () => {
return (
<ContractVerificationMethod title="New Smart Contract Verification">
<ContractVerificationFieldSources
control={ control }
accept=".json"
multiple
title="Sources and Metadata JSON" mt={ 0 }
......
import React from 'react';
import type { Control } from 'react-hook-form';
import type { FormFields } from '../types';
import ContractVerificationMethod from '../ContractVerificationMethod';
import ContractVerificationFieldCompiler from '../fields/ContractVerificationFieldCompiler';
......@@ -9,23 +6,17 @@ import ContractVerificationFieldConstArgs from '../fields/ContractVerificationFi
import ContractVerificationFieldName from '../fields/ContractVerificationFieldName';
import ContractVerificationFieldSources from '../fields/ContractVerificationFieldSources';
interface Props {
control: Control<FormFields>;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const ContractVerificationStandardInput = ({ control }: Props) => {
const ContractVerificationStandardInput = () => {
return (
<ContractVerificationMethod title="New Smart Contract Verification">
<ContractVerificationFieldName control={ control }/>
<ContractVerificationFieldCompiler control={ control }/>
<ContractVerificationFieldName/>
<ContractVerificationFieldCompiler/>
<ContractVerificationFieldSources
control={ control }
accept=".json"
title="Standard Input JSON"
hint="Upload the standard input JSON file created during contract compilation."
/>
<ContractVerificationFieldConstArgs control={ control }/>
<ContractVerificationFieldConstArgs/>
</ContractVerificationMethod>
);
};
......
import React from 'react';
import type { Control } from 'react-hook-form';
import type { FormFields } from '../types';
import ContractVerificationMethod from '../ContractVerificationMethod';
import ContractVerificationFieldAbiEncodedArgs from '../fields/ContractVerificationFieldAbiEncodedArgs';
......@@ -9,18 +6,13 @@ import ContractVerificationFieldCode from '../fields/ContractVerificationFieldCo
import ContractVerificationFieldCompiler from '../fields/ContractVerificationFieldCompiler';
import ContractVerificationFieldName from '../fields/ContractVerificationFieldName';
interface Props {
control: Control<FormFields>;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const ContractVerificationVyperContract = ({ control }: Props) => {
const ContractVerificationVyperContract = () => {
return (
<ContractVerificationMethod title="New Vyper Smart Contract Verification">
<ContractVerificationFieldName control={ control } hint="Must match the name specified in the code."/>
<ContractVerificationFieldCompiler control={ control } isVyper/>
<ContractVerificationFieldCode control={ control } isVyper/>
<ContractVerificationFieldAbiEncodedArgs control={ control }/>
<ContractVerificationFieldName hint="Must match the name specified in the code."/>
<ContractVerificationFieldCompiler isVyper/>
<ContractVerificationFieldCode isVyper/>
<ContractVerificationFieldAbiEncodedArgs/>
</ContractVerificationMethod>
);
};
......
......@@ -8,6 +8,7 @@ type Props<TInputs extends FieldValues, TInputName extends Path<TInputs>> = {
field: ControllerRenderProps<TInputs, TInputName>;
text: string;
onChange?: () => void;
isDisabled?: boolean;
}
export default function CheckboxInput<Inputs extends FieldValues, Name extends Path<Inputs>>(
......@@ -15,6 +16,7 @@ export default function CheckboxInput<Inputs extends FieldValues, Name extends P
field,
text,
onChange,
isDisabled,
}: Props<Inputs, Name>) {
const handleChange: typeof field.onChange = React.useCallback((...args) => {
......@@ -29,6 +31,7 @@ export default function CheckboxInput<Inputs extends FieldValues, Name extends P
ref={ field.ref }
colorScheme="blue"
size="lg"
isDisabled={ isDisabled }
>
{ text }
</Checkbox>
......
......@@ -4,7 +4,7 @@ import type { FieldError } from 'react-hook-form';
interface Props {
text: string;
error?: FieldError;
error?: Partial<FieldError>;
}
const InputPlaceholder = ({ text, error }: Props) => {
......
......@@ -21,14 +21,19 @@ const FileInput = <Values extends FieldValues, Names extends Path<Values>>({ chi
const files = Array.from(fileList);
field.onChange(files);
field.onBlur();
}, [ field ]);
const handleClick = React.useCallback(() => {
ref.current?.click();
}, []);
const handleInputBlur = React.useCallback(() => {
field.onBlur();
}, [ field ]);
return (
<InputGroup onClick={ handleClick }>
<InputGroup onClick={ handleClick } onBlur={ handleInputBlur }>
<VisuallyHiddenInput
type="file"
onChange={ handleInputChange }
......
import { Box, Flex, Icon, Text, useColorModeValue, chakra } from '@chakra-ui/react';
import { Box, Flex, Icon, Text, useColorModeValue, IconButton, chakra } from '@chakra-ui/react';
import React from 'react';
import crossIcon from 'icons/cross.svg';
import CrossIcon from 'icons/cross.svg';
import imageIcon from 'icons/image.svg';
import { shortenNumberWithLetter } from 'lib/formatters';
......@@ -10,9 +10,10 @@ interface Props {
className?: string;
index?: number;
onRemove?: (index?: number) => void;
isDisabled?: boolean;
}
const FileSnippet = ({ file, className, index, onRemove }: Props) => {
const FileSnippet = ({ file, className, index, onRemove, isDisabled }: Props) => {
const handleRemove = React.useCallback(() => {
onRemove?.(index);
......@@ -33,14 +34,16 @@ const FileSnippet = ({ file, className, index, onRemove }: Props) => {
<Text fontWeight={ 600 } overflow="hidden" textOverflow="ellipsis" whiteSpace="nowrap">{ file.name }</Text>
<Text variant="secondary" mt={ 1 }>{ shortenNumberWithLetter(file.size) }B</Text>
</Box>
<Icon
as={ crossIcon }
<IconButton
aria-label="remove"
icon={ <CrossIcon/> }
boxSize={ 6 }
color="link"
_hover={{ color: 'link_hovered' }}
cursor="pointer"
variant="simple"
display="inline-block"
flexShrink={ 0 }
ml="auto"
onClick={ handleRemove }
isDisabled={ isDisabled }
/>
</Flex>
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment