import { Add } from '@mui/icons-material' import clsx from 'clsx' import { ComponentType, useState } from 'react' import { FieldError, FieldPathValue, FieldValues, Path, PathValue, UseFormRegister, UseFormSetValue, UseFormWatch, Validate, } from 'react-hook-form' import { useTranslation } from 'react-i18next' import { TransProps } from '@dao-dao/types' import { processError, toAccessibleImageUrl, validateUrlWithIpfs, } from '@dao-dao/utils' import { Button } from '../buttons/Button' import { Modal } from '../modals/Modal' import { ImageUploadInput } from './ImageUploadInput' import { InputErrorMessage } from './InputErrorMessage' import { InputLabel } from './InputLabel' import { TextInput } from './TextInput' // Return the field name paths that have type string. export type StringFieldNames = { [Property in Path]: PathValue extends | string | undefined ? Property : never }[Path] export interface ImageSelectorModalProps< FV extends FieldValues, StringFieldName extends StringFieldNames, > { fieldName: StringFieldName register: UseFormRegister watch: UseFormWatch setValue: UseFormSetValue error?: FieldError onCloseOrDone: (done: boolean) => void loading?: boolean disabled?: boolean Trans: ComponentType buttonLabel?: string imageClassName?: string visible?: boolean style?: 'avatar' | 'banner' } export const ImageSelectorModal = < FV extends FieldValues, StringFieldName extends StringFieldNames, >({ fieldName, register, error, setValue, watch, onCloseOrDone, loading, disabled, Trans, buttonLabel, imageClassName, visible = true, style = 'avatar', }: ImageSelectorModalProps) => { const { t } = useTranslation() const imageUrl = watch(fieldName) ?? '' const [uploadError, setUploadError] = useState() return ( onCloseOrDone(false)} visible={visible} >
{ // Prevent submitting form on enter. if (e.key === 'Enter') { e.preventDefault() onCloseOrDone(true) } }} register={register} validation={[validateUrlWithIpfs]} />
{ setUploadError(undefined) setValue(fieldName, url as any) }} onError={(error) => setUploadError(processError(error, { forceCapture: false })) } />
) } export interface ImageSelectorProps< FV extends FieldValues, StringFieldName extends StringFieldNames, > { fieldName: StringFieldName register: UseFormRegister validation?: Validate>[] watch: UseFormWatch setValue: UseFormSetValue Trans: ComponentType disabled?: boolean error?: FieldError className?: string size?: string | number style?: 'avatar' | 'banner' } export const ImageSelector = < FV extends FieldValues, StringFieldName extends StringFieldNames, >({ fieldName, error, watch, className, disabled, size, style = 'avatar', ...props }: ImageSelectorProps) => { const [showImageSelect, setShowImageSelect] = useState(false) const imageUrl = watch(fieldName) ?? '' return ( <> {showImageSelect && ( setShowImageSelect(false)} style={style} watch={watch} {...props} /> )} ) }