import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Path } from 'react-hook-form'; import { UnpackNestedValue, UseFormSetValue } from 'react-hook-form/dist/types/form'; import { FieldPathValue } from 'react-hook-form/dist/types/path'; import { FieldValues } from 'react-hook-form/dist/types/fields'; import { FormInput } from '../form/form-input'; import { FormComponent } from '../../models/form-component'; import { AbstractFormItemProps } from './abstract-form-item'; import { FabButton } from '../base/fab-button'; import noAvatar from '../../../../images/no_avatar.png'; export interface ImageType { id?: number, attachment_name?: string, attachment_url?: string } interface FormImageUploadProps extends FormComponent, AbstractFormItemProps { setValue: UseFormSetValue, defaultImage?: ImageType, accept?: string, size?: 'small' | 'large' onFileChange?: (value: ImageType) => void, onFileRemove?: () => void, } /** * This component allows to upload image, in forms managed by react-hook-form. */ export const FormImageUpload = ({ id, register, defaultImage, className, rules, disabled, error, warning, formState, onFileChange, onFileRemove, accept, setValue, size }: FormImageUploadProps) => { const { t } = useTranslation('shared'); const [file, setFile] = useState(defaultImage); const [image, setImage] = useState(defaultImage.attachment_url); /** * Check if image is selected */ const hasImage = (): boolean => { return !!file?.attachment_name; }; /** * Callback triggered when the user has ended its selection of a file (or when the selection has been cancelled). */ function onFileSelected (event: React.ChangeEvent) { const f = event.target?.files[0]; if (f) { const reader = new FileReader(); reader.onload = (): void => { setImage(reader.result); }; reader.readAsDataURL(f); setFile({ attachment_name: f.name }); setValue( `${id}[_destroy]` as Path, false as UnpackNestedValue>> ); if (typeof onFileChange === 'function') { onFileChange({ attachment_name: f.name }); } } } /** * Callback triggered when the user clicks on the delete button. */ function onRemoveFile () { if (file?.id) { setValue( `${id}[_destroy]` as Path, true as UnpackNestedValue>> ); } setValue( `${id}[attachment_files]` as Path, null as UnpackNestedValue>> ); setFile(null); setImage(null); if (typeof onFileRemove === 'function') { onFileRemove(); } } // Compose classnames from props const classNames = [ `${className || ''}` ].join(' '); return (
{!hasImage() && {t('app.shared.form_image_upload.browse')}} {hasImage() && {t('app.shared.form_image_upload.edit')}} {hasImage() && } className="delete-image" />}
); };