‫Next up comes a really cool part,
‫which is to handle file uploads
‫and then to actually upload images to a super base bucket.
‫So, basically, we will now make
‫this part of the form here work
‫where we upload a corresponding cabin photo.
‫And so, let's start by registering also this field
‫by just copying this,
‫and then let's just call it image.
‫And then we also need to make it off the type file.
‫All right.
‫Now, let's actually check out
‫this component right here that I created earlier.
‫So, this is actually just another input element, right?
‫But since we already know that this is a file input,
‫it should automatically get somehow this type of a file.
‫So, we shouldn't have to declare this right here manually
‫each time that we use this component,
‫because again, that component
‫should already have that in itself.
‫And with styled components, we can actually do that.
‫So, right here, after declaring that this is an input field,
‫we can then set the attributes property.
‫And so, in here, we can set the type to file.
‫All right.
‫And so, this should now be working.
‫So, let's come to our event handler function here
‫and actually deactivate this
‫and just take a look at the data again.
‫So, all of this doesn't matter for now.
‫And so, let's just select some image here.
‫So, inside or project folder, inside public
‫or actually inside the data.
‫So, here we have some cabin photos.
‫So, let's select this file, open it,
‫and so then we can take a look
‫at what kind of data we get here.
‫So, the image is this file list here
‫where we will want to retrieve the very first element.
‫So, this file right here.
‫So, this is of the type of file.
‫Then here we get the name and some other stuff.
‫But this really does contain the image itself.
‫And so, we now need to pass this
‫also into our mutate function.
‫So, then here, let's actually create
‫a new object with all the data in it.
‫So, we need to spread it out.
‫And then we define the image property.
‫And again, it is called image for the exact same reason
‫that all these other fields have their names.
‫So, ID, max capacity and so on.
‫And so, that's because in super base,
‫that's exactly the name that we gave our fields
‫so to our columns.
‫And so, here, we then of course,
‫need to match exactly those.
‫So, here, that's going to be data.image
‫and then the very first one.
‫Okay.
‫And so now, let's go here to or create cabin function
‫because this is where we will actually upload the image.
‫So, here we will first of all,
‫of course, create the cabin itself.
‫So, create the cabin.
‫And if that is successful,
‫then we upload the image.
‫Upload image.
‫Now, what we still need to do
‫is to actually specify the image path
‫here in this new cabin that we create.
‫So, remember that in our data right here,
‫for example, in this first row,
‫we already have the image
‫but the only way in which we specify the image in the cabin
‫is by using the file name.
‫So, with this file name,
‫we basically connect this cabin row
‫with the corresponding cabin image.
‫And actually let's grab this URL here.
‫So, we will need this in a minute.
‫So, the format of that URL.
‫But as I was saying, we need not only
‫to upload the image itself,
‫but to also specify the image name
‫and actually the path to the image in the bucket
‫right here in the new cabin that we insert.
‫So, first of all, we need to create a URL like this.
‫So, basically containing the path to the bucket itself
‫and then a unique cabin name.
‫So, let's do that.
‫So, image name.
‫And so, here, we need to really make sure
‫that this name is unique.
‫So, let's create a template literal
‫and then doing math.random.
‫And so, then, we just prefixed that
‫to the cabin name itself.
‫So, that is gonna be stored inside
‫the new cabin.image.name as we saw earlier.
‫Now, if this cabin name contains any slashes,
‫then super base will create folders based on that.
‫And so, we of course don't want that.
‫And so, let's replace all the slashes with nothing.
‫So, this part is really important because again,
‫if for example, the file was called like this,
‫then super base would create a new folder with this
‫and then create an image called 2.jpeg.
‫And so, that's not what we want
‫and so, we would have to replace that part.
‫All right.
‫And next up, let's then create the image path.
‫So, that's what we will then ultimately store
‫inside of the cabin row.
‫So, basically here we have our super base URL
‫and then besides that, it is slash storage V1
‫and then all of this and the name of our bucket.
‫So, let's grab actually the super base URL from right here.
‫So, basically that's exactly the same,
‫and not here but here of course.
‫And so, we need to use that here.
‫So, let's try to import that super base URL.
‫Ah, but for that,
‫we need to actually export it as a named export here.
‫So, up until this point, we didn't need this
‫outside of this file, but now we do want to use it here.
‫Now, that doesn't work automatically
‫so let's just import that here manually.
‫So, super base URL.
‫And yeah, then let's just add all of this part right here.
‫And then finally, the image name that we created earlier.
‫All right.
‫And so here, now we need to spread out this new cabin.
‫And then the image is going to be
‫the image path that we just created.
‫Nice.
‫So, that's the first part that is finished now.
‫And next up, we want to actually upload the image itself.
‫So, let's come here to our API to learn how we can do that.
‫Now, actually right here in this documentation,
‫they don't explain how to do it.
‫And so, let's come here to the introduction
‫where they should be a link to the documentation.
‫So, this one right here, let's click that.
‫And so, this is a good opportunity to also check out
‫the documentation here.
‫So, here, is where you could read
‫all about how to fetch data, how to insert, update,
‫and so on.
‫Then we have authentication.
‫And finally, here we have everything about storage buckets.
‫So, here creating a bucket we already did manually.
‫And what we are interested now is uploading a file.
‫All right.
‫Now, here they actually tell us
‫that we need role level security policies.
‫So, we haven't done that yet.
‫And so, let's go do this now.
‫So, coming here to our bucket.
‫So, let's then select policies from here.
‫And then for our cabin images,
‫which is the one we're working on now,
‫let's create a new policy.
‫And let's do full customization
‫and simply for now, enable everything for everyone.
‫And again, we will change this later.
‫So, allow all operations.
‫And again, we can then actually later change this here
‫only to authenticated users.
‫But for now, this will need to suffice
‫because we don't have authentication yet.
‫Okay.
‫And now, let's see actually how we can do this.
‫So, let's grab all of this
‫and place that here.
‫So, again, we are doing this
‫only if there was no error
‫in creating the cabin itself, right?
‫And so, let's then analyze this here.
‫So, here we won't need this data.
‫Then we have this duplicate error.
‫So, let's rename this to storage error.
‫And then here, of course, we need to change a lot of things.
‫So, it's superbase.storage.
‫And then from
‫and here, our bucket name is cabin images.
‫And then here, we need to specify the name of the file
‫and the file itself.
‫Then we have a few objects here
‫but those are not really important.
‫And so, here is the image name that we already created.
‫So, the image name itself.
‫And then here is the actual image.
‫So, that's new cabin.image and this is actually already it.
‫So, this is how we upload images to super base.
‫Now, there's just one final thing that I want to do here
‫and that is to prevent a new cabin
‫from being created in case
‫that this file actually didn't upload correctly.
‫So, basically, what I want to do is to delete the cabin
‫if there was an error uploading the corresponding image.
‫So, if there was a storage error,
‫and now let's just grab this data from here.
‫So, and here the ID is going to be the one
‫coming from the data.
‫So, basically, this data
‫that we received here from super base
‫will already contain the new ID.
‫And so, again, if the cabin was successfully uploaded
‫but then there was an error in uploading the file,
‫then we just go back and delete that cabin as well.
‫And then let's also lock some stuff to the console.
‫So, also grabbing that part.
‫So, then here that's gonna be the storage error.
‫And then here, let's just say cabin image
‫could not be uploaded and the cabin was not created.
‫Now, okay.
‫So, this should be all the code that we need.
‫And so now, let's go test this.
‫So, just reloading adding a new cabin.
‫So let's do 008 for eight people,
‫800 euros, $80 or euros discount
‫and then let's select our image number 8.
‫So, open, add the cabin,
‫and we have an error.
‫So, data.image.at is not a function.
‫So, let's come here.
‫And I guess this at method here only works on actual arrays
‫but this image here is I think called a file list.
‫So, let's actually do it like this.
‫So, that should fix it.
‫Let's try it.
‫So, it's taking some time, which is a good sign.
‫And yeah, beautiful.
‫There is our new cabin.
‫Cabin number eight with the image that we selected.
‫So, let's of course come now here to our bucket.
‫And there it is.
‫So, here we get that random value
‫plus the name of the image.
‫And so, that's exactly the one
‫that we have uploaded right now.
‫And then it was also successfully connected.
‫So, this is automatically refreshing.
‫And so, indeed, he replaced exactly the path to that file.
‫And so, then in our HTML,
‫that file can be correctly rendered.