Skip to content

Commit

Permalink
fix(ImageField): add image preview
Browse files Browse the repository at this point in the history
  • Loading branch information
Birkbjo committed Oct 21, 2024
1 parent 042e3b2 commit 8afd1cc
Showing 1 changed file with 68 additions and 32 deletions.
100 changes: 68 additions & 32 deletions src/pages/organisationUnits/form/ImageField.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
import { useDataEngine } from '@dhis2/app-runtime'
import { useConfig, useDataEngine } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import {
FileInput,
FileInputChangeHandler,
FileList,
FileListItem,
Label,
Field as UIField,
} from '@dhis2/ui'
import React from 'react'
import { Field as FieldRFF, useField } from 'react-final-form'
import React, { useState } from 'react'
import { useField } from 'react-final-form'
import css from './ImageField.module.css'

Check failure on line 12 in src/pages/organisationUnits/form/ImageField.tsx

View workflow job for this annotation

GitHub Actions / lint

Unable to resolve path to module './ImageField.module.css'

const fileToBase64 = (file: File): Promise<string> => {
const reader = new FileReader()

return new Promise((resolve, reject) => {
reader.readAsDataURL(file)
reader.onload = () => resolve(reader.result as string)
reader.onerror = reject
})
}

export function ImageField() {
const dataEngine = useDataEngine()
Expand All @@ -17,6 +28,8 @@ export function ImageField() {
const currentFile: { name?: string; id?: string } | undefined =
input.value || undefined

const [fileBase64, setFileBase64] = useState<string | undefined>()

const uploadFile = async (fileToUpload: File) => {
const fileToUploadDetails = {
name: fileToUpload.name,
Expand Down Expand Up @@ -61,45 +74,68 @@ export function ImageField() {
input.onBlur()
}
const deleteFile = () => {
setFileBase64(undefined)
input.onChange(undefined)
input.onBlur()
}
const handleChange: FileInputChangeHandler = ({ files }) => {
const handleChange: FileInputChangeHandler = async ({ files }) => {
const newFile = files[0]
if (newFile instanceof File) {
uploadFile(newFile)
const file64 = await fileToBase64(newFile)
setFileBase64(file64)
}
}

return (
<FieldRFF<string | undefined> name={fieldName}>
{() => (
<>
<Label htmlFor={fieldName}>{i18n.t('Image')}</Label>
<UIField label={i18n.t('Image')} name="image">
<div className={css.fileInputWrapper}>
<ImagePreview
fileBase64={fileBase64}
fileResource={input.value}
/>
<FileInput
accept="image/*"
buttonLabel={i18n.t('Upload an image')}
multiple={false}
name={input.name}
onChange={handleChange}
error={!!(input.value && input.value.error)}
valid={!!(input.value && input.value.id)}
/>
</div>

<FileInput
accept="image/*"
buttonLabel={i18n.t('Upload an image')}
multiple={false}
name={input.name}
onChange={handleChange}
small
error={!!(input.value && input.value.error)}
valid={!!(input.value && input.value.id)}
<FileList>
{currentFile?.id && (
<FileListItem
key={currentFile?.name}
label={currentFile?.name}
onRemove={deleteFile}
removeText={i18n.t('Remove')}
/>

<FileList>
{currentFile?.id && (
<FileListItem
key={currentFile?.name}
label={currentFile?.name}
onRemove={deleteFile}
removeText={i18n.t('Remove')}
/>
)}
</FileList>
</>
)}
</FieldRFF>
)}
</FileList>
</UIField>
)
}

const ImagePreview = ({
fileBase64,
fileResource,
}: {
fileBase64?: string
fileResource?: { id: string }
}) => {
const baseUrl = useConfig().baseUrl

if (fileBase64) {
return <img src={fileBase64} alt={i18n.t('Preview of current icon')} />
}

if (fileResource && fileResource.id) {
const src = `${baseUrl}/fileResources/${fileResource.id}/data`

return <img src={src} alt={i18n.t('Preview of current icon')} />
}
return null
}

0 comments on commit 8afd1cc

Please sign in to comment.