Example of File upload in JustinByrne/Mealing

File composer.json (link to Github)
{
    //
    "require": {
        "php": "^7.3|^8.0",
        //
        "spatie/laravel-medialibrary": "^9.0.0"
    },
    //
}
File resources/views/recipes/create.blade.php (link to Github)
//
        <form action="{{ route('recipes.store') }}" method="POST" enctype="multipart/form-data">
//
                <div class="items-start md:grid md:grid-cols-9 md:space-x-6">
                    <label for="image" class="dark:text-gray-200 self-top">
                        Image
                    </label>
                    <div class="w-full md:col-span-4">
                        <div x-data x-init="
                            FilePond.create($refs.input);
                            FilePond.setOptions({
                                server: {
                                    url: '/upload',
                                    headers: {
                                        'X-CSRF-TOKEN': '{{ csrf_token() }}'
                                    }
                                }
                            });
                        ">
                            <input type="file" name="image" x-ref="input">
                        </div>
                    </div>
                </div>
//
File app/Http/Controllers/UploadController.php (link to Github)
use App\Models\TempFile;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;

class UploadController extends Controller
{
    public function store(Request $request)
    {
        $mimeTypes = ['image/jpeg', 'image/png', 'image/svg+xml', 'image/webp'];

        if ($request->hasFile('image') && in_array(File::mimeType($request->file('image')), $mimeTypes)) {
            $file = $request->file('image');
            $filename = Str::slug(str_replace("'", '', $file->getClientOriginalName()));
            $folder = 'tmp/' . uniqid() . '-' . now()->timestamp;
            Storage::putFileAs($folder, $file, $filename);

            TempFile::create([
                'folder' => $folder,
                'filename' => $filename,
            ]);

            return $folder;
        }

        return response('Failed upload', 500);
    }
}
File app/Models/Recipe.php (link to Github)
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\MediaLibrary\MediaCollections\Models\Media;

class Recipe extends Model implements HasMedia
{
    use InteractsWithMedia,
    //
    public function registerMediaConversions(Media $media = null): void
    {
        $this->addMediaConversion('thumb')
              ->width(368)
              ->height(276)
              ->sharpen(10);
    }
}
File app/Http/Controllers/RecipeController.php (link to Github)
use Auth;
use App\Models\Recipe;
use App\Models\TempFile;
use Illuminate\Support\Facades\Storage;
use App\Http\Requests\StoreRecipeRequest;

class RecipeController extends Controller
{
    //
    public function store(StoreRecipeRequest $request): RedirectResponse
    {
        $recipe = Auth::User()->Recipes()->create([
            'name' => $request['name'],
            'servings' => $request['servings'],
            'adults' => $request->has('adults'),
            'kids' => $request->has('kids'),
            'timing' => $request['timing'],
            'category_id' => $request['category_id'],
            'instruction' => $request['instruction']
        ]);

        $file = TempFile::where('folder', $request->image)->first();
        if ($file) {
            $recipe->addMedia(Storage::path($request->image . '/' . $file->filename))->toMediaCollection();
            $file->delete();
        }

        for($i = 0; $i < count($request['ingredients']); $i++)   {
            $recipe->ingredients()->attach($request['ingredients'][$i], ['quantity' => $request['quantities'][$i]]);
        }

        foreach($request['allergens'] as $id => $level)    {
            if($level != 'no')  {
                $recipe->allergens()->attach($id, ['level' => $level]);
            }
        }

        return redirect($recipe->path());
    }
    //
}

Additional resources on File upload: