refactor(FE-438): Replace FileInput with custom file upload UI

This commit is contained in:
rstubryan
2025-12-26 21:50:59 +07:00
parent e6a38c3f65
commit 1843a47d59
@@ -1,6 +1,6 @@
'use client'; 'use client';
import { useCallback, useEffect, useMemo, useState } from 'react'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useFormik } from 'formik'; import { useFormik } from 'formik';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { Icon } from '@iconify/react'; import { Icon } from '@iconify/react';
@@ -14,7 +14,6 @@ import SelectInput, {
OptionType, OptionType,
useSelect, useSelect,
} from '@/components/input/SelectInput'; } from '@/components/input/SelectInput';
import FileInput from '@/components/input/FileInput';
import { import {
UniformityFormSchema, UniformityFormSchema,
@@ -57,6 +56,8 @@ const UniformityForm = ({
const [uniformityFormErrorMessage, setUniformityFormErrorMessage] = const [uniformityFormErrorMessage, setUniformityFormErrorMessage] =
useState(''); useState('');
const fileInputRef = useRef<HTMLInputElement>(null);
// ===== SELECT INPUT DATA ===== // ===== SELECT INPUT DATA =====
const [selectedLocation, setSelectedLocation] = useState<OptionType | null>( const [selectedLocation, setSelectedLocation] = useState<OptionType | null>(
null null
@@ -451,50 +452,105 @@ const UniformityForm = ({
/> />
<div> <div>
<FileInput <label
required htmlFor='file-upload-input'
name='files' className="w-full text-sm font-normal leading-5 after:content-['*'] after:ml-0.5 after:text-red-500"
label='Upload File' >
onChange={handleFileChange} Upload File
accept='application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,text/csv' </label>
isError={formik.touched.files && Boolean(formik.errors.files)} <section
errorMessage={formik.errors.files as string} className='h-full w-full border border-gray-300 rounded-2xl border-dashed cursor-pointer mt-2'
className={{ wrapper: 'w-full' }} onClick={() =>
/> document.getElementById('file-upload-input')?.click()
}
{formik.values.files && ( >
<div className='mt-4 flex flex-col gap-2'> {formik.values.files ? (
<label className='text-sm font-semibold'> <div className='flex flex-col items-center justify-center gap-2 my-10'>
File yang dipilih: <div className='border border-[#18181B]/25 rounded-2xl p-1 flex items-center justify-center'>
</label> <Button
<div className='flex items-center justify-between gap-4 p-3 bg-base-200 rounded-lg'> type='button'
<div className='flex items-center gap-2'> className='rounded-2xl border border-sky-500 bg-[#0069E0] text-white'
<Icon onClick={(e) => {
icon='material-symbols:attach-file' e.stopPropagation();
width={20} document.getElementById('file-upload-input')?.click();
height={20} }}
/> >
<span className='text-sm'> <Icon
{formik.values.files.name} icon={'heroicons:document-text'}
className='text-2xl text-white'
/>
</Button>
</div>
<span className='text-md font-semibold text-black line-clamp-2 text-center max-w-xs break-all'>
{formik.values.files.name}
</span>
</div>
) : (
<>
<div className='flex flex-col items-center justify-center gap-2 my-10 mb-0!'>
<div className='border border-[#18181B]/25 rounded-2xl p-1 flex items-center justify-center'>
<Button
type='button'
className='rounded-2xl border border-sky-500 bg-[#0069E0] text-white'
onClick={(e) => {
e.stopPropagation();
document
.getElementById('file-upload-input')
?.click();
}}
>
<Icon
icon={'heroicons-solid:arrow-up-tray'}
className='text-2xl text-white'
/>
</Button>
</div>
<span className='text-md font-semibold text-[#18181B80]'>
Drag file to this area to upload
</span> </span>
<span className='text-xs text-base-content/60'> <span className='text-xs font-light text-[#18181B80] text-center max-w-xs px-4'>
({(formik.values.files.size / 1024).toFixed(2)} KB) Upload data file (*.csv)
</span> </span>
</div> </div>
<Button
type='button' <div className='flex items-center justify-center gap-2 py-4'>
color='error' <div className='h-px bg-[#18181B33] w-8'></div>
onClick={handleRemoveFile} <span className='text-[#18181B33] text-xs'>
> Templates
<Icon </span>
icon='material-symbols:delete-outline-rounded' <div className='h-px bg-[#18181B33] w-8'></div>
width={18} </div>
height={18}
/> <div className='flex items-center justify-center mb-10'>
</Button> <Button
</div> type='button'
</div> variant='outline'
)} className='btn-sm rounded-2xl shadow-md border border-base-300'
href='https://www.timestored.com/data/sample/chickweight.csv'
target='_blank'
onClick={(e) => e.stopPropagation()}
>
<Icon
icon='heroicons:arrow-down-tray'
width={18}
height={18}
/>
Template CSV
</Button>
</div>
</>
)}
</section>
<input
ref={fileInputRef}
type='file'
id='file-upload-input'
name='files'
accept='application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,text/csv'
onChange={handleFileChange}
className='hidden'
/>
</div> </div>
<Button <Button