class ApplicationController extends Controller {
public function index()
{
return Inertia::render('Admin/Applicants/Index', [
'applicants' => Application::count(),
'applicants_data' => Application::all(),
'message' => session('message'),
]);
}
public function create()
{
$sectors = Sector::with('occupations')->get();
return Inertia::render('Apply/Index', [
'sectors' => $sectors
]);
}
public function store(ApplicationStoreRequest $request)
{
$data = $request->validated();
$image_one = $data['high_school_transcript'];
$image_two = $data['gslce_result'];
$image_three = $data['profile_photo'];
$data['high_school_transcript_path'] = $image_one->store('applicants/transcript/' . Str::random(), 'public');
$data['gslce_result_path'] = $image_two->store('applicants/result/' . Str::random(), 'public');
$data['profile_photo'] = $image_three->store('applicants/profile/' . Str::random(), 'public');
Application::create($data);
return to_route('/home')
->with('message', 'The Application Sent Successfully');
}
public function show()
{
//
}
public function edit(string $id)
{
$applicant = Application::find($id);
$sectors = Sector::with('occupations')->get();
$trainees = User::where('role', 'trainee')->get();
return Inertia::render('Admin/Applicants/Edit', [
'applicant' => $applicant,
'sectors' => $sectors,
'trainees' => $trainees,
]);
}
public function update(ApplicationStoreRequest $request, Application $application)
{
$data = $request->validated();
$image_one = $data['high_school_transcript'];
$image_two = $data['gslce_result'];
$image_three = $data['profile_photo'];
if ($application) {
if ($image_one) {
Storage::deleteDirectory(dirname($application->high_school_transcript_path));
$image_one = $image_one->store('applicants/transcript/' . Str::random(), 'public');
}
if ($image_two) {
Storage::deleteDirectory(dirname($application->gslce_result_path));
$image_two = $image_two->store('applicants/result/' . Str::random(), 'public');
}
if ($image_three) {
Storage::deleteDirectory(dirname($application->profile_photo));
$image_three = $image_three->store('applicants/profile/' . Str::random(), 'public');
}
}
$application->update($data);
return to_route('admin.applicants.index')->with('message', "$application->first_name's application updated");
}
public function destroy(Request $request, Application $application)
{
$request->validate([
'password' => 'required|current_password'
]);
if ($application) {
Storage::deleteDirectory(dirname($application->high_school_transcript_path));
Storage::deleteDirectory(dirname($application->gslce_result_path));
Storage::deleteDirectory(dirname($application->profile_photo));
$application->delete();
return redirect()->route('admin.applicants.index')
->with('message', 'Application deleted successfully');
}
return redirect()->route('admin.applicants.index');
}
}
the above is my application controller. I am focused on the update method.
class ApplicationStoreRequest extends FormRequest { /** * Determine if the user is authorized to make this request. */ public function authorize(): bool { return true; }
/**
* Get the validation rules that apply to the request.
*
* @return array<string, IlluminateContractsValidationValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'.......',
'high_school_transcript' => [$this->isMethod('post') ? 'required' : 'nullable', 'file', 'mimes:png,jpg,pdf,jpeg', 'max:5120'],
'gslce_result' => [$this->isMethod('post') ? 'required' : 'nullable', 'file', 'mimes:png,jpg,pdf,jpeg', 'max:5120'],
'profile_photo' => [$this->isMethod('post') ? 'required' : 'nullable', 'file', 'mimes:png,jpg,pdf,jpeg', 'max:5120'],
'.....',
];
}
}
the above is the application store and update Request method ApplicationStoreRequest.
the below is the frontend:
const [confirmApplicantDeletion, setConfirmApplicantDeletion] = useState(false); const [deletingApplicant, setDeletingApplicant] = useState(null); const passwordInput = useRef('');
const { data, setData, delete: destroy, put, processing, reset, errors, } = useForm({ high_school_transcript: applicant.high_school_transcript, gslce_result: applicant.gslce_result, profile_photo: applicant.profile_photo, });
const refreshUsername = (enrollmentType, email) => { setUsername(generateUsername(enrollmentType, email)); };
const closeModal = () => { setConfirmApplicantDeletion(false); setDeletingApplicant(null); reset(); };
const confirmModalApplicantDeletion = (applicant) => { setDeletingApplicant(applicant); setConfirmApplicantDeletion(true); };
const delApplicant = (applicant, e) => { e.preventDefault();
destroy(route('admin.applicant.destroy', applicant), { preserveScroll: true, onSuccess: () => closeModal(), onError: () => passwordInput.current.focus(), onFinish: () => reset(), }); };
const submit = (e) => { e.preventDefault(); put(route('admin.applicants.update', applicant)); };
<InputError
className='mt-2'
message={errors.high_school_transcript}
/>
</div>
</div>
) : (
<>
<div className='max-medium:w-full max-medium:mt-4'>
<InputLabel
value='High School Transcript'
htmlFor='high_school_transcript'
className='mb-2'
/>
<TextInput
type='file'
name='high_school_transcript'
id='high_school_transcript'
onChange={(e) =>
setData('high_school_transcript', e.target.files[0])
}
className='p-2 mt-1 block w-full desktop:max-w-md'
/>
<InputError
className='mt-2'
message={errors.high_school_transcript}
/>
</div>
</>
)}
{initialData.gslce_result_path ? (
<div className='flex flex-col'>
<a
target='_blank'
href={`${window.location.origin}/storage/${initialData.gslce_result_path}`}
className='flex items-center justify-center rounded relative bg-gray-200 w-full max-h-[150px] min-h-[150px] text-black py-4 hover:bg-gray-300 dark:bg-neutral-700 dark:hover:bg-neutral-600 dark:text-white group'
>
<IoDocumentAttach size={31} />
<LiaExternalLinkAltSolid
size={20}
className='absolute bottom-1 right-1'
/>
<p className='text-[14px] absolute inline-flex scale-50 opacity-0 group-hover:opacity-100 group-hover:scale-100 transition items-center justify-center bg-white/90 inset-0 backdrop-blur-sm text-center dark:bg-black/70'>
Review High School Transcript
</p>
</a>
<div className='max-medium:w-full max-medium:mt-4 mt-1'>
<InputLabel
value='Update GSLCE Result'
htmlFor='gslce_result'
className='text-nowrap mb-2'
/>
<TextInput
type='file'
id='gslce_result'
name='gslce_result'
onChange={(e) => setData('gslce_result', e.target.files[0])}
className='p-2 mt-1 block w-full desktop:max-w-md'
/>
<InputError className='mt-2' message={errors.gslce_result} />
</div>
</div>
) : (
<div className='max-medium:w-full max-medium:mt-4'>
<InputLabel
value='GSLCE Result'
htmlFor='gslce_result'
className='text-nowrap mb-2'
/>
<TextInput
type='file'
id='gslce_result'
name='gslce_result'
onChange={(e) => setData('gslce_result', e.target.files[0])}
className='p-2 mt-1 block w-full desktop:max-w-md'
/>
<InputError className='mt-2' message={errors.gslce_result} />
</div>
)}
{initialData.profile_photo ? (
<div className='flex flex-col gap-1'>
<img
src={`http://127.0.0.1:8000/storage/${initialData.profile_photo}`}
alt=''
className='inline-block w-full max-w-[150px] max-h-[150px] min-h-[150px] object-cover rounded hover:scale-[1.02] transition'
/>
<div className='max-medium:w-full max-medium:mt-4'>
<InputLabel
value='Update Passport size photo'
htmlFor='profile_photo'
className='text-nowrap mb-2'
/>
<TextInput
type='file'
id='profile_photo'
name='profile_photo'
onChange={(e) => setData('profile_photo', e.target.files[0])}
className='p-2 mt-1 block w-full desktop:max-w-md'
/>
<InputError className='mt-2' message={errors.profile_photo} />
</div>
</div>
) : (
<div className='max-medium:w-full max-medium:mt-4'>
<InputLabel
value='Passport size photo'
htmlFor='profile_photo'
className='text-nowrap mb-2'
/>
<TextInput
type='file'
id='profile_photo'
name='profile_photo'
onChange={(e) => setData('profile_photo', e.target.files[0])}
className='p-2 mt-1 block w-full desktop:max-w-md'
/>
<InputError className='mt-2' message={errors.profile_photo} />
</div>
)}
</div>
</FieldSet>
This is my second time experiencing this problem, at first I just went okay by not solving it. but now I am in the place where I have to work it out. AI isn’t helping me out here.
encType=’multipart/form-data’ isn’t working here since its inertiaJS https://inertiajs.com/file-uploads
Please help
I am expecting the image to update as the other text inputs but since all files are required it is being hard for me tackle