The Evolution of Input Containers: A Step-by-Step Guide to Styling and Customizing
When it comes to creating visually appealing user interfaces, input containers are an essential component. In this article, we will take you through a step-by-step guide on how to style and customize your input container using CSS.
First, let's start with the basics. We'll begin by selecting a suitable color for our input container. In this case, we've chosen a gray color (`#ecef1`). This is a versatile and neutral shade that will provide a clean backdrop for our input field. Next, we'll set the text color to black to ensure maximum contrast and readability.
To add some visual interest to our input container, let's introduce a border radius of 5 pixels. This subtle curve will help soften the edges of our container and create a more rounded shape. Additionally, we'll apply a font weight of 600 to give it a slightly heavier feel. Finally, we've added some padding to the top and bottom (4 pixels) and left and right (12 pixels) to create some breathing room around the input field.
Now that we have our basic styling in place, let's move on to customizing the button. We'll select the button container using CSS and set its border radius to 5 pixels to match our input container. Next, we'll remove any default borders and apply a padding of 4 pixels to create some space around the text.
To make our button more visually appealing, let's give it a font weight of 600 and add some padding to make it slightly larger than the input field. We'll also set its box sizing to border-box to ensure that the padding is applied correctly. Finally, we've added a background color of white and set the text color to gray.
To complete our button design, let's add some interactive effects. We'll give it a cursor pointer by setting `cursor: pointer` and add a hover effect by changing its background color to `#f7f7f7`. When the button is active, we'll change its background color to `#ccc`.
Moving on to our input field, let's select the input element using CSS and set its box-sizing to border-box to ensure that the padding is applied correctly. We'll remove any default borders and apply a font size of 15 pixels to make it slightly larger than the button. Finally, we've added a background color of white and set its font weight to 200.
To style our input field's placeholder text, let's select the `::placeholder` pseudo-element using CSS and set its color to gray (`#ecef1`). We'll also set its font weight to 200 to match our button design. Finally, we've added some padding to create space around the placeholder text.
Now that we have our input container styled and customized, let's move on to the next step: creating an app.js file to handle user interactions.
In this article, we will take you through a step-by-step guide on how to style and customize your input container using CSS.
"WEBVTTKind: captionsLanguage: enwelcome to this Gemini AI multimodal model course where you'll learn to build an app that can see and answer questions about images you'll learn to use the powerful Gemini model to analyze uploaded images and provide insightful responses to your queries Ana Kubo developed this course she will teach you everything from understanding Gemini to building the apps functionality Google provided a grant to make this course possible hey everyone and welcome to this course in which I'm going to show you how to use the Gemini multimodal model what is it you ask well it's the thing that we will be using in order to build this app that will allow us to upload images to it from our computers and ask the app questions about them so for example if I upload a picture of this glamorous octopus wearing a hat and then I want to ask the app in the text input what is the creature in the picture wearing the app should respond with hat or a similar text response we will also be adding a feature to ask a question at random if you can't think of one such as does the image have puppies or other questions that are similar okay so a lot to learn for those of you who don't know me my name is anel Kubo and I'm a software developer and course creator here on free C Camp as well as on my own channel as well as your guide today for this action packed course in fact here are all the things that we will be covering in this video first off we're going to look at what is Gemini followed by getting set up and then look at authentication followed by all the Gemini models to our disposal and end with building out an app that can actually see images that I discussed so what are we waiting for let's do it what is Gemini to put it simply Gemini is a series of multimodal generative AI models developed by Google Gemini models can accept text and image and prompts depending on what model variation you choose and output text responses what this means is that we can feed in text proms such as what day of the week is it today and we can receive responses back such as it is Wednesday and not only that we can feed in images as prompts too so I can feed in a picture of a cat in a hat and we can ask what's in the photo and we should receive a text response back pretty cool right now there is more than one way to interact with Gemini you might be familiar with interact with Gemini via the app we can interact with it pretty easily by typing the prompt here and we can even see a history of all our previous chats so here I am writing a prompt in text and receiving text back as well as continuing a whole chat that takes into account the previous messages I sent or here I am uploading images and asking questions about them or if you want to actually use this cool technology to build out your own apps you can also interact with a Gemini API by interacting with the API we can do exactly what the Gemini app UI does so for example putting in a text input and receiving a text input back by using the Gemini model and the generate content method from it and we can also use the generate content method and the Gemini provision model in order to prompt with text Andor images and receive text back as well as build multi-tank conversations with a Gemini model as well as some extra configuration an advanced use of Gemini is to create embeddings using the embedding 01 model with the embed content method though this is outside the scope of this tutorial we will go into some of these models and the methods they come with and how to use them individually later on just for now know that these are the most popular at the time of recording and a few more do exist but we will not be covering them in this particular course Okay so got it to recap Gemini is a series of multimodal generative AI models developed by Google that you can interact with via an API or via the app with the same name of Gemini okay to start off you're just going to head over to gemini.com and this is the web page that you should see at the time of recording please keep in mind that this might change if you're watching this in the future and all you're going to do is simply sign in so please go ahead and do that you will have to sign in with your Google account so I'm just going to go ahead and do that now so anafree cam.org is the address that I'm going to use today and I'm just going to sign in okay great and here is the dashboard so as we briefly touched on before this is the Gemini app it's essentially a UI that we're going to use in order to communicate with the Gemini models so I can write in some text such as when is Christmas just like that or perhaps I can select from the pre-made questions it is up to you and I can submit this will generate a text response so here we are this is a text response now if I go ahead and ask a follow-up question such as what kind of decorations without the context of the previous message what kind of decoration might not come back with anything of value to the conversation this is because we have started a chat okay so if I go ahead and ask what kind of decorations the app will know that we're talking about Christmas based on the previous chat history okay so here we are here are some Christmas decorations for us so that is looking good and of course we can upload images as well so that is the Gemini app and if we want to communicate with the Gemini model not via the app but via our own applications that we build we need to get acquainted with the Gemini API documentation so let's go ahead and do that so this time I'm going to just head over to ai. gooogle dodev Gemini API slocs and here we go here's all the information that we're going to need so today because it's the new model we're going to be using Gemini 1.5 flash but please do keep in mind if you're watching this in the future there might be a newer model out don't worry just use Gemini 1.5 flash today and then once you are comfortable using Gemini 1.5 flash you can then replace it with the more current models that are out okay great getting your API key just like most apis the Gemini API uses API keys for Authentication in this section I'm going to show you how to get your own API key when it comes to communicating with the API from the application that we will be building remember make sure not to share or upload your API key anywhere public if you do someone might take it use it in their own project and use up all of your free tokens or rack up a huge credit card bill if you have a card attached this also includes exposing it in any client side code by this I mean building an app without a backend and deploying it onto the internet the code in this case will be visible simply by inspecting the page someone will then be able to go and take it and use it for their own use to use this key safely requests must be rooted through your own backend server where your API key can be securely loaded from an environment variable or Key Management Service okay so let's do it let's get our API key okay so starting where we left off over on AI gooogle dodev Gemini apid docs I am simply going to select get an API key from the menu on the left and then we're just going to get an API so really simple that's all we need to do and this will take you to AI studio. dole.com and here what we're going to do is just choose to get an API key and here we are so here we can create an API key just go ahead and click got it once you choose to create an API key and if you've never used this before you're going to be prompted to create an API key in a new project so just go ahead undo that and then this should generate an API key for you okay so here we go just copy that and there we go make sure to keep it safe if for some reason your API key has been compromised simply go ahead and delete it there and go through those steps again great so now now that we have our free of charge API key we are ready to go as we know we can interact with Gemini API by interacting with the API we can get access to all the Gemini generative AI models and their methods as a recap we can have text only input and use the generate content method to generate a response from the Gemini model give it an input message and we can also use the generate content method and the Gemini flash model in order to prompt with text Andor images and receive text back as well as build multi-turn conversations with a Gemini model as well as some extra configuration an option to create embeddings using the embedding 001 model with the embed content method also exists so it is good to keep that in mind for when you might need to create one in the future in today's course however we'll be focusing on the Gemini flash model in order to Pro with text and or images and receive text back for this course we will be using no JS so please make sure to have nodejs version 18 and above installed as well as npm we will also be using the Gemini skk in order to initialize the generative model okay so make sure your node version is up to date and if you would like have a quick scan over the Gemini STK and if you are ready let's continue by building out our app okay so let's go ahead and start a new project now as I am using webstorm this going to be super easy all I have to do is Click react and then I can call this whatever I want so I'm going to call this react Gemini vision app okay and then it's going to use this command in order to spin up a react project for me however you're not using webstorm that's fine just head over to your terminal go into the directory that you want to work in and then just go ahead and use the same command to npx create react app and then go ahead and call it whatever you wish so I can do react Gemini vision app and hit enter well I'm not going to do it this way because I'm going to do it this way and just hit create so that is essentially going to spin up all the files and configuration that we need for our project okay so this will take a while but when it's done we will continue and great that is now done so if you look in here you will see a bunch of stuff including the source directory with loads and loads of files that we actually don't need so I'm just going to go ahead and delete these three so please go ahead and delete these three as well so delete anyway and then we don't need the app test file so I'm going to delete that too uh and let's delete the app CSS file as well so I'm going to delete that because it's a simple project we're just going to have one style sheet so now these three files are the only things in here and as well in here we're going to delete everything apart from the index HTML so just delete that and delete these as well cool delete anyway so now the appjs file I'm just going to go ahead and once again just delete the majority of this I'm just going to zoom in a bit for you maybe let's call this up in lowercase and let's Chang this to be a functional expression just because I prefer working with functional Expressions so there we go and I'm going to just delete these inputs too now my index CSS file I'm going to delete everything and my index JS file we don't need to have these anymore because we deleted them so I'm just going to also delete the semicolons and there we go so that is the entire content of my index JS that is the entire content of my index CSS and that is the entire content of my appjs file so those are only three files that you need right now now because I want to get to the meest stuff first I'm going to start off writing the back end okay so in order to do this on the same level as the package Json I'm going to create a new file I'm just going to call This Server JS okay so all our backend code is going to go here now in order to start the back end and the front end we're going to have to go into the package Json and change some scripts around so at the moment this script will start our front end but however I'm going to actually write start front end so we can differentiate from another script we're going to write called start backend in which we're going to listen out to constant changes so we're going to use a package called No demon to listen out for constant changes on the server JS file so so cool those are our two scripts and we're going to have to import some dependencies in here too that we're going to need for this project so for this project I'm just going to make this a little bit bigger for you we're going to install a few packages we're going to install the course package to get rid of any pesky course messages the EnV so we can essentially read secrets that we store in a separate file that we don't particularly want to upload anywhere like GitHub we're going to S all our secrets in there namely our Google Gemini API key so that's what we're going to need we're also going to need Express for rooting fs and molter for handling images that we pass through from the front end to the back end no demon to listen out for constant changes as we said and then we're also going to install Google generative AI so just hit enter on that and you will see those dependencies show up here along with the versions that we are going to be using for this tutorial today so this is important these versions so for example Google generative AI this is the version we're using if you're watching this the future and for some reason you know it's like way Advanced as four more likely it's going to be like one uh just go back to using zero for this tutorial cuz that's what we're going to be using today and just do npmi to install that package again or all the packages in fact so once again here are all the packages and the versions that we are going to be using today make sure yours are the same I can't stress that enough if you don't want to run into any errors okay so now that we've done that let's start our front end so I'm just going to do npm Run start front end and this should spin up the front end right here on Local Host 3000 and there we go there's nothing in here for now apart for an empty div if you look in the div with IDE of root a div with a class name of app okay cuz that's what we have in our app component so this is looking good next we need to also spin up our back end right so here's the script we need for that I'm going to open this up in a new tab making sure that I am in react Gemini vision app make sure that is the case and I'm going to do npm Run start backend so just like that and that is now doing its thing so it's listening out however how can we be sure I'm actually going to write something so let's get rid of the package Json file for now and minimize this in the server JS we're actually going to define the port for this I want my back end to be on Port 8,000 let's also go ahead and import some packages so cons Express is what we're going to use for rooting so require the package express uh cores for getting rid of any pesky cuse messages that might block us from making requests from the front end to the back end const app um essentially we're going to get exp press save everything that it contains under the con Express and then call it in order to release all the wonderful methods and properties and save them onto the const app so we can use them so one of them being app listen and we're going to listen out to Port 8000 and then we need a corack function here and I'm just going to put console log to print this out down here we can put listening to changes on Port port and then just the port number right and that will show up every time we make a change in here so this is good we are listening out for changes let's move on some other things we're going to need to do is use app use and pass your course and call it to get rid of those pesky messages and also app use express Json to essentially work with Json and pass it through from the front end to the back end we're also going to require the package Dov like I said so we can essentially work with secrets in our secret. EnV file and then like I said the package fs and molter to work with images or specifically passing images from the front end to the back end and saving them in our back end so require molter like so now in order to use Google generative AI so const we're going to have to get Google generative AI just like that from the package so require and then at Google generative AI I'm just going to minimize that for now so there we go that's everything that we need and in order to work with this well we're going to have to get our API key so we're going to create a new Constructor new Google generative AI and then we're simply just going to pass through our API key which we're going to store an a. dnv file so on the same level as the package Json I'm going to create a file EnV and this is for all our secrets I am indeed going to store my Gemini API key here okay so just like that okay I'm going to paste it in like so as a string and now using so let's minimize this now using process EnV once checking that this is in here I can now get my Gemini API key so that string will now be passed through into this Constructor great and let's save this now something gen Ai and going to save it as okay so we are now all set our setup is ready number one we're going to get an image from our front end and save it to the back end that's number one so let's do it and for this I'm actually going to like I said use FSM molter and we're going to Define where we want to store in our back end so let's define storage and I'm going to use molter disk storage and this is just from the documentation okay we need to define the destination um Rec file CB just copying the syntax uh and then we're going to save all our images in the I'm going to choose to save them in the public directory so just in here all my images are going to be saved in there cool next I'm also going to actually format the file name to whatever I want so Rec file CB again and for the file name well I'm just going to use the date because say we wants to upload an image and maybe we uploaded the same image a second ago we can use date now to actually differentiate it with a string uh I'm going to separate it with a dash and then I'm going to get the file original name okay and attach it to the date now amazing so we've reformatted the file name don't worry I will be showing you what this looks like however first we need to define a upload again just from documentation using molter I need to pass through the storage as the storage that we just defined up here um and then just make sure it's for a single file okay so now I'm going to create a rout up post and if we post to the end point upload I want to essentially get the image that I send over to the upload end point um so that's something I'll be doing from the front end and then we can use upload and then again I need to request response and then maybe let's get the error if there is an error so if an error somehow has occurred I just want to return res send the error code 500 and the J is the error okay so oh an errors is occurred however there's no error I'm actually going to get whatever we pause through from the front end okay it's already saved in the public directory by now and I'm going to also save the file path so actually I'm going to create a variable here so at the moment file path is just nothing right but we can override it with the request file part because we're sending over an image from the front end with the request body great don't believe me let's try it out so of course we need to pass it from the front end so I'm going to go in here and I'm just going to make like a super simple input um so let's do it inut I'm going to give this the type cuz it has to have the type of file so we can deal with uploading files um I'm also going to tell it to accept images so accept just images image like that and now I'm going to actually attach it to a label I'll show you why in a bit so this label is going to say upload an image space and now to link the label to the input I need to give this an ID I'll give this the ID of files plural just so it's really obvious that we're going to use HTML for for and to link it up we need to use this ID name so now they are linked this just means if we go in here at the moment it looks like this and you can kind of see the file right so if I go ahead and open a baby Yoda it says baby Yoda here and you can kind of see this ugly button if I want to not show this ugly button and the word I can just go ahead and put hidden and now if I actually click on upload image so the text now I can also upload an image of baby Yoda however it's not obvious but we know right we know so cool um that's really it if we actually want to display this as well I can do so pretty easily I'm going to go ahead and maybe do this up here so let's import use State from react and now this just means that I can essentially save the image here set image we're going to start off with the image just being null okay uh maybe let's format this a little bit better so at the moment null is assigned to image and if I want to change it I use set image so I do want to change it I'm going to use set image um on change of this input so on change of this however we do want to do a lot of things so maybe let's go ahead and write a function for this called upload image okay so there we go so now I can do const upload image I'm just going to Define that function here just like so and in here I'm want to set image to be the e e Target and this comes with a bunch of stuff files and we just want the first file okay so that's all I'm going to do um and then if I console log image here console log image you'll be able to see that baby Yoda so let's try again baby Yoda and now in the console log you will see the whole file right here's the file we have the name of the file the original name which is baby Yoda we've got the size we've even got the type so lot of information that we're saving that whole object so cool we're saving it we can also display it now so I can for instance just use an image like this a self closing image and as the source of this I'm going to use URL create object URL and just pass through the image so that will now be obvious we can see baby Yodo which is pretty fun however that's all I'm going to use this for I've just set it here so we can see it um in regards to sending it to the back end we're going to essentially use the fetch keyword to make a HTTP post request so what I'm going to do actually is uh append this file to some form data so const form data equals I'm going to create a new form data Constructor and now I can get form data and use append and I'm going to append a property this property is file with the value of this okay so that's now appended um maybe let's move this down here because we want to do that first and this is kind of like a second thing so I've done form data because I wanted to show you how to do that you can also append a bunch more stuff if you want now like for any reason if you want to send something to the back end of like BL the attribute blur and then the value of blur you can so that's why I've done the form data thing so you can send more information if you want when you choose to take this project to the next level Okay so we've got our form data we've appended our file now I'm going to use try and catch so try and catch just like so so there we go let's console log any errors or console error any errors that we might bump into and I'm going to use a wait fetch uh we need to use the async keyword here because we use await we'll save the response of this to something await Fetch and let's pass through the endpoint of HTTP Local Host and our back end is 8,000 and our endpoint is upload and what do we want to send over well we want to send over everything right so the form data so maybe let's define our options appear options as an object in which we send over the method it's going to be a post method and we also want to with the body just send over the form data cool so now let's grab our options oops just get rid of that just like so amazing so this is looking good I'm actually going to just move those options maybe and put them in the try as well so great once we get our response from the backend and I'm just going to get the Json just like that and save it to const data okay cool and then console log the data uh making sure to use a here is also an async method so now I think let's try it out right we have now essentially written the code so here's my whole upload function to send over that image to our back end and once it gets here it should be saved in the public directory so let's try it out I'm just going to refresh we are getting an error message because at the moment the image does not exist so we're going to have to wrap that if image exists then only show this image element great so that will get rid of that error let's have a look and it has so now let's upload an image once again I'm just going to upload a bage of a bab yoga there we go and now that means if I look in here TDA we get baby Yoda appended with the date now and a Dash so if we click on it there's our baby Yoda so we have successfully now saved an image to our back end how cool is that okay cool um if you need to delete them it's easy just delete them if you start to get too many that could be a good idea so wonderful we've done it that is part one the next part is that along with the image we want to pass through some text so like what's in this picture we want to be able to ask that so let's maybe go back to our front end now and I'm actually going to style this out a little bit better okay um not doing any final styling just adding in the correct elements that we're going to need so let's do it for this I'm actually going to create a section so so here we go and I'm going to give this the class name of search section just like that making sure that this is a string so there we go now in here I'm also going to create a div and I'm going to give this the class name of image container and this is going to hold our you guessed our image so let's grab that and just put it in here so this is is looking good let's also maybe give this the class name of image just like that now after this I'm simply going to have a little p element uh and then I'm going to also give this the class name of extra info as that is what this is it's extra info and in here I'm going to put a span cuz I want to break it up and this span is going to have essentially my and input so just put it in like that um of course please format it nicely great so after that span I'm just going to have some text to ask questions about so this should Now read upload an image to ask questions about and that's the end of our P element let's also have one more P element um and this is going to say what do you want to know about about the image question mark and then in here again in the P element I'm just going to break up have a button um I'm going to give this the class name of surprise just like so uh and this should say surprise me H and then I am also going to give this an onclick and on click of this I'm going to surprise so this will just come up with a few options for us so we don't really have to do any thinking just three options okay and we're actually going to disable this so we'll only disable this if we already have a response from the llm cool so that's two things we're going to need to Define let's move on for now so after this P element I'm also going to have another div and this is going to have the class name of input container so input container just like so and our input container well this is where the input the text input is going to be so the text input which is going to take our questions it's going to have a value so we can actually see the value of the question I'm going to have some placeholder text I'm simply going to put what is in the image so that is a question you could ask the llm and on change of this I'm simply going to change the value of this so e e Target value let's pass it through set value so that's another state that we're going to have to write e Target value great so that is the inputs and then we're also going to show two buttons but these two buttons well the first button is going to only show if there is no response from the llm no response and there is no error so if those two things are true then we're going to show a button and this button is going to say go ahead and ask me because there's no responses no errors we're free to ask so on click of this I'm going to actually write a function called analyze image so that is a function we're going to have to write and I'm just going to grab all of this actually and this time if there let's delete all this if there is a response or there is an error well then I actually just want to clear everything right cuz oh we've got a response or oh there's an error let's just clear the whole thing so we can stop Fresh So on click of this we're going to clear cool and then also what I'm going to do is actually show the error right so I'm going to do so here if the error exists then I'm just going to show a p element with that error message so just like that amazing this is looking good and of course we also want to show the response right so if a response exists then we want to show a p element with the response okay done so that's really it I know that's a lot um at the moment we'll get loads of Errors because we need to define the function of surprise analyze image and clear and we also need to set state for error responses and value so let's do it so const value set value equals use State empty string just going to copy that then we also have response set response and error so error and set eror just like that and now also the functions right so const surprise just write a function like that for now and then down here I'm going to do const analyze image and const clear so to clear everything well that's easy because I'm just going to reset all the states so set image is going to go back to being null set value it's going to go back to be an empty string set response is going to be an empty string and set error is also making an empty string so cool this is what it looks like at the moment it's not pretty but it has all the functionality that we need so an easy one to to do is actually maybe just the surprise me button right the surprise me function and just get three strings to show randomly so maybe let's define them so con surprise options equals and then I've already picked this out so just like that so now in order to get a value a random value so a random string from those three I can get the array so there we go open it up and pass through math floor because we're rounding down to the nearest integer uh I'm going to use math random to return a random value from 0 to just under one and then multiply it by the surprise option length Okay so cool so this part can give me back a number even even let's say 2.9 right but 2.9 we can't really pass this through into surprise option it won't give us anything so we use math Flor to round it down to two and if we pass two into the surprise options 0 1 2 it should bring back this string so let's save the random value right uh it's going to be either one of these three strings and we can set value as the random value okay so that will now be saved to here so we're either saving whatever we type here or we're saving whatever we click here as the value okay you don't believe me console log value you will see that in the console so there we go and then if I type something instead like that it shows up or if I change it it will essentially show up as well so we're saving the value great this is looking good next like I said once we get the value and we already have the image as we uploaded the image we want to analyze the image so we want to send over some text or the prompt to the back end I think we can also just set the error here I'm going to set an error as the string of something didn't work please try again okay and then analyze image once again we are going to well first off if no image exist we don't want to do anything right the image must exist so if no image we're going to set error as error must have an existing image so just like that making sure it's just Spell existing the same and then we can just return out of it however if we do have an image right so everything is good then we are okay to continue and we're going to use try and catch so we're going to try something and catch any errors so we're going to console error the error and then let's also set the error you can make the error message whatever you want I'm just going to do something didn't work please try again but you can be way more specific than I am okay so what are we going to try essentially well I think we should try to await Fetch and we're going to send over some text to our back end so we're going to Define an endpoint I'm just going to do HTTP Local Host 8,000 and we can just do Gemini right because we're sending over to our Gemini endpoint along with some options so let's define our options uh of course we do need to save this to something I'm just going to save it to response and because a weight is here we need to make this an async method so con options my options is just going to be an object it's going to have the method of post the body is going to be we need to pass it through Json stringify okay it's going to be an object which going to have the message and just the value that we've saved okay so whatever we typed in the input or whatever we selected from the surprise options we're also going to have to pass through headers so headers and then content type type application Jason just like that okay so this is looking good and of course we're going to have to await the response Jason just like that and then maybe let's save this as data um and then if we want to you know set the response data so we can see it in the browser we PA it through here because the response will be shown if it exists oops get of that s amazing so now let's actually Define our end point right so let's go back to the server and here once again it's a post method and we're going to post something to Gemini so just like that request response and there we go so once again we're going to do try and we're going to catch error console error the error okay and what do we want to try well we want to essentially let's define the model that we want to use so const model equals gen AI get generative model and we're going to pass through an object okay and we're going to pass through the model of geni 1.5 flash latest so that is the latest one and most powerful one at the time of recording so cool we've defined our model and of course the text or the value that we've passed through is with the request body message as the message attribute is what we save the value to so if I get the request body message we should get the text right or the value and let's just save this as the prompt um so just to make sure that this is work just going to conso Lo The Prompt in the back end this won't use this uh okay this is kind of irrelevant we're just checking through that the prompts being passed over from the front end to the back end so let's see so now let's upload an image once more once again I'm going to choose baby Yoda uh surprise me is the image fabulously pink ask me let's go back in here and we do indeed get the text of is the image fabulously pink so that is working this is looking good and of course we could have written whatever in here so you know let's maybe get rid of that ask me and that text should show up so we're getting the The Prompt this is good of course we're only getting that prompt if an image exists so for example if I did that in here error must have an existing image so everything is working as it should great so we're getting the prompt so now I can use it right so I'm going to use await meaning we need to use the ASN keyword here await model generate content and we're going to pass through an array we're going to pass through the prompt and then we're going to pass through the file path that we saved above here however we need to do a few things to it I need to uh format it a little bit so in here what I'm going to do is write a function file to generative Parts we're going to pass through the path I'm going to pass through the mime type into the function and then we're going to just return an object that says in line data just like that and then data is going to be buffer from going to pass through this we're going to use FS read file sync and pass through the path that we passed through into the function and then use two string base 64 okay and then we're also going to pass through the mime type that we pass through into the function so we've just kind of reformatted everything so I'm going to use that function file to generative part going I use it here and then we have to pass through the path and the mime type so the path just is well the file path and the mime type is going to be image JPEG cool so let's save this as something I'm going to save this to results just like that and then we're going to get the result response so result response await this await just like that save it as response and now I'm going to get the response text just save it under the const text and then do sent the text just like so so great that is the four thing let's give it a go right so in here once again upload image baby Yoda surprise me ask me however it seems that in here let's have a look I am awaiting the Json I don't want to do this I just need to get the text as what we're sending from the back end is just some text and not an object so make sure just to get text so this now once again that's just make sure everything is working so you don't have to take my word for it baby Yoda surprise me ask me and Tada no the image does not have a whale it has a baby Yoda holding a cup how cute is that so there we go that's really it we've done it right this is disabled as we have a response this does not say ask me it says clear because we have a response we're done you can now take this project make it your own style it as you want or if you want my styling if you thought it was cool please do stick around just going to style this up super quickly in some super basic CSS so yeah like I said you can either choose to take this now and run with it style it up please do share it with me on Instagram Twitter I would love to see or you can continue and style along with me so let's do it so I'm just going to minimize all these and just focus on the index CSS file for now so I'm going to grab everything and say the font family is going to be sand serif everything in here I'm also going to grab the whole body I'm going to do margin zero padding zero to reset it let's make the width of Everything 100 viewport width the height of Everything 100 viewport height just like that and then I'm going to change the background color so it's kind of like an off-white f a f a f c okay let's change the color as well I'm going to do da da like just this gray color and then I'm going to initialize Flex box so that we can Center everything from left to right so that is my body next I'm going to grab every P element and just give it a font weight of 200 and then a font size too okay so all of them are going to have the same font size of 14 pixels cool next I'm going to grab the app itself so the element with the class name of app and just give it a width of 90 viewport width so it's a bit smaller than the desktop next I'm going to grab the element with the class name of upload and change the text of this to be purple so let's do 6 E1 e81 so that is a nice purple color okay now I'm actually going to grab the image container so the El with the class name of image container and I'm just going to give this a height of 200 pixels it's going to hold my image I'm going to use display Flex to essentially Center the image using just AI content Center and then I'm going to give it a margin of 30 pixels to space it out from everything now the image inside the image container so I can actually grab this and say the element with the class name of image that we gave it is just going to have a height of 100% of the the parent element so it always kind of fits inside next I'm going to grab the element with the class name of search section just like so and I'm just going to make sure that it spans the whole thing so 100% I'm going to use display Flex once more to make sure that everything is stacked on top of each other using Flex Direction column and I'm going to Center everything again great so moving swiftly on I'm now going to grab the button that has the surprise class name and I'm going to give this the background color of this gray e c e cf1 let's also change the color of the text to be black uh and I'm going to give it a border radius to kind of round it off a bit of five pixels let's also give it a font weight I'm going to give it a font weight of 600 um the padding of this I'm going to give four pixels on the top and bottom 12 pixels on the left and right and the margin of this is going to be zero on the top zero on the right two pixels on the bottom and five pixels on the left okay and I'm just going to get rid of the border so if you want to see what this looks like now is probably a good time to show you this is what the button looks like that's what all the text looks like we just have the input ready to style next so let's do it so now I'm going to grab the input con ster just like so and I'm going to make sure that it spans the whole thing the whole parent um I'm also going to initialize Flex box I'm going to give it a border radius of six pixels and an overflow of hidden okay and a box shadow that I have pre-picked out already so here is my box Shadow wonderful and now that we have the input container I'm going to sa the input that lives inside the container well again I'm just going to get rid of any border that exists any default border I'm going to give it a padding 13 pixels on the top and bottom and 14 pixels on the left and right box sizing is going to be border box font size I'm going to make it 15 pixels in here so slightly larger the outline of this is going to be none I don't want any outline on it the width of this is just going to be 90% cuz the buttons going to take up the rest and the font weight is going to be 200 so now let's grab the input container uh actually maybe let's grab the input once more because I want to actually style the placeholder text too so placeholder let's make the color um just this gray really and then the font weight is also going to be 200 cool so now let's actually grab the button that lives in here and I'm going to give a Min width of 10 pixels to compensate for the input let's also give it a border of none and then a border left of one pixel and then ca ca ca the gray and I'm going to make it solid I'm also going to give it a background color of this white and then the text color of Gray I'm going to also give it a font we of Bold and the cursor is going to be a poter so cursor pointer cool now if the button is active so just like that I'm going to give it a background color of ca ca ca and then let's also make sure that anything with extra info as a class name it's going to have the text aligned Center and finally the response right I'm also going to give this a box Shadow same as the one above and padding is going to be 13 pixels top and bottom 14 pixels uh left and right the Box sizing is going to be border box the font size is going to be 15 pixels and the font weight is going to be 200 and finally the Border radius is going to be six pixel so there we have it that is what it looks like all styled up okay just make sure that the appjs file in here on the response I'm just going to give this the class name of answer as well just to make sure that that styling is applied okay so now let's give this to go upload an image once again I'm going to go with baby Yoda so same one each time surpris me does the image have puppies does the image have cats ask me and then we should get our response no the image does not have cats it has a cartoon character from the Star Wars franchise known as the child or baby Yoda I love it and of course because we do have a response this is disabled this doesn't say ask me this says clear and and yeah this is looking wonderful I'm happy with this one other thing you might want to do is just maybe wrap the extra info so this P element right here and just say if there is no response show this okay because if there is a response we don't want to be able to upload any more images so let's try that one more time baby Yoda surprise me ask me a question and taada amazing we cannot change the image anymore this is looking good so yes please do share your final projects with me take this to the next level like I said i' absolutely love to see how you startled this made this your own please do share this with me on Instagram Twitter or wherever reallywelcome to this Gemini AI multimodal model course where you'll learn to build an app that can see and answer questions about images you'll learn to use the powerful Gemini model to analyze uploaded images and provide insightful responses to your queries Ana Kubo developed this course she will teach you everything from understanding Gemini to building the apps functionality Google provided a grant to make this course possible hey everyone and welcome to this course in which I'm going to show you how to use the Gemini multimodal model what is it you ask well it's the thing that we will be using in order to build this app that will allow us to upload images to it from our computers and ask the app questions about them so for example if I upload a picture of this glamorous octopus wearing a hat and then I want to ask the app in the text input what is the creature in the picture wearing the app should respond with hat or a similar text response we will also be adding a feature to ask a question at random if you can't think of one such as does the image have puppies or other questions that are similar okay so a lot to learn for those of you who don't know me my name is anel Kubo and I'm a software developer and course creator here on free C Camp as well as on my own channel as well as your guide today for this action packed course in fact here are all the things that we will be covering in this video first off we're going to look at what is Gemini followed by getting set up and then look at authentication followed by all the Gemini models to our disposal and end with building out an app that can actually see images that I discussed so what are we waiting for let's do it what is Gemini to put it simply Gemini is a series of multimodal generative AI models developed by Google Gemini models can accept text and image and prompts depending on what model variation you choose and output text responses what this means is that we can feed in text proms such as what day of the week is it today and we can receive responses back such as it is Wednesday and not only that we can feed in images as prompts too so I can feed in a picture of a cat in a hat and we can ask what's in the photo and we should receive a text response back pretty cool right now there is more than one way to interact with Gemini you might be familiar with interact with Gemini via the app we can interact with it pretty easily by typing the prompt here and we can even see a history of all our previous chats so here I am writing a prompt in text and receiving text back as well as continuing a whole chat that takes into account the previous messages I sent or here I am uploading images and asking questions about them or if you want to actually use this cool technology to build out your own apps you can also interact with a Gemini API by interacting with the API we can do exactly what the Gemini app UI does so for example putting in a text input and receiving a text input back by using the Gemini model and the generate content method from it and we can also use the generate content method and the Gemini provision model in order to prompt with text Andor images and receive text back as well as build multi-tank conversations with a Gemini model as well as some extra configuration an advanced use of Gemini is to create embeddings using the embedding 01 model with the embed content method though this is outside the scope of this tutorial we will go into some of these models and the methods they come with and how to use them individually later on just for now know that these are the most popular at the time of recording and a few more do exist but we will not be covering them in this particular course Okay so got it to recap Gemini is a series of multimodal generative AI models developed by Google that you can interact with via an API or via the app with the same name of Gemini okay to start off you're just going to head over to gemini.com and this is the web page that you should see at the time of recording please keep in mind that this might change if you're watching this in the future and all you're going to do is simply sign in so please go ahead and do that you will have to sign in with your Google account so I'm just going to go ahead and do that now so anafree cam.org is the address that I'm going to use today and I'm just going to sign in okay great and here is the dashboard so as we briefly touched on before this is the Gemini app it's essentially a UI that we're going to use in order to communicate with the Gemini models so I can write in some text such as when is Christmas just like that or perhaps I can select from the pre-made questions it is up to you and I can submit this will generate a text response so here we are this is a text response now if I go ahead and ask a follow-up question such as what kind of decorations without the context of the previous message what kind of decoration might not come back with anything of value to the conversation this is because we have started a chat okay so if I go ahead and ask what kind of decorations the app will know that we're talking about Christmas based on the previous chat history okay so here we are here are some Christmas decorations for us so that is looking good and of course we can upload images as well so that is the Gemini app and if we want to communicate with the Gemini model not via the app but via our own applications that we build we need to get acquainted with the Gemini API documentation so let's go ahead and do that so this time I'm going to just head over to ai. gooogle dodev Gemini API slocs and here we go here's all the information that we're going to need so today because it's the new model we're going to be using Gemini 1.5 flash but please do keep in mind if you're watching this in the future there might be a newer model out don't worry just use Gemini 1.5 flash today and then once you are comfortable using Gemini 1.5 flash you can then replace it with the more current models that are out okay great getting your API key just like most apis the Gemini API uses API keys for Authentication in this section I'm going to show you how to get your own API key when it comes to communicating with the API from the application that we will be building remember make sure not to share or upload your API key anywhere public if you do someone might take it use it in their own project and use up all of your free tokens or rack up a huge credit card bill if you have a card attached this also includes exposing it in any client side code by this I mean building an app without a backend and deploying it onto the internet the code in this case will be visible simply by inspecting the page someone will then be able to go and take it and use it for their own use to use this key safely requests must be rooted through your own backend server where your API key can be securely loaded from an environment variable or Key Management Service okay so let's do it let's get our API key okay so starting where we left off over on AI gooogle dodev Gemini apid docs I am simply going to select get an API key from the menu on the left and then we're just going to get an API so really simple that's all we need to do and this will take you to AI studio. dole.com and here what we're going to do is just choose to get an API key and here we are so here we can create an API key just go ahead and click got it once you choose to create an API key and if you've never used this before you're going to be prompted to create an API key in a new project so just go ahead undo that and then this should generate an API key for you okay so here we go just copy that and there we go make sure to keep it safe if for some reason your API key has been compromised simply go ahead and delete it there and go through those steps again great so now now that we have our free of charge API key we are ready to go as we know we can interact with Gemini API by interacting with the API we can get access to all the Gemini generative AI models and their methods as a recap we can have text only input and use the generate content method to generate a response from the Gemini model give it an input message and we can also use the generate content method and the Gemini flash model in order to prompt with text Andor images and receive text back as well as build multi-turn conversations with a Gemini model as well as some extra configuration an option to create embeddings using the embedding 001 model with the embed content method also exists so it is good to keep that in mind for when you might need to create one in the future in today's course however we'll be focusing on the Gemini flash model in order to Pro with text and or images and receive text back for this course we will be using no JS so please make sure to have nodejs version 18 and above installed as well as npm we will also be using the Gemini skk in order to initialize the generative model okay so make sure your node version is up to date and if you would like have a quick scan over the Gemini STK and if you are ready let's continue by building out our app okay so let's go ahead and start a new project now as I am using webstorm this going to be super easy all I have to do is Click react and then I can call this whatever I want so I'm going to call this react Gemini vision app okay and then it's going to use this command in order to spin up a react project for me however you're not using webstorm that's fine just head over to your terminal go into the directory that you want to work in and then just go ahead and use the same command to npx create react app and then go ahead and call it whatever you wish so I can do react Gemini vision app and hit enter well I'm not going to do it this way because I'm going to do it this way and just hit create so that is essentially going to spin up all the files and configuration that we need for our project okay so this will take a while but when it's done we will continue and great that is now done so if you look in here you will see a bunch of stuff including the source directory with loads and loads of files that we actually don't need so I'm just going to go ahead and delete these three so please go ahead and delete these three as well so delete anyway and then we don't need the app test file so I'm going to delete that too uh and let's delete the app CSS file as well so I'm going to delete that because it's a simple project we're just going to have one style sheet so now these three files are the only things in here and as well in here we're going to delete everything apart from the index HTML so just delete that and delete these as well cool delete anyway so now the appjs file I'm just going to go ahead and once again just delete the majority of this I'm just going to zoom in a bit for you maybe let's call this up in lowercase and let's Chang this to be a functional expression just because I prefer working with functional Expressions so there we go and I'm going to just delete these inputs too now my index CSS file I'm going to delete everything and my index JS file we don't need to have these anymore because we deleted them so I'm just going to also delete the semicolons and there we go so that is the entire content of my index JS that is the entire content of my index CSS and that is the entire content of my appjs file so those are only three files that you need right now now because I want to get to the meest stuff first I'm going to start off writing the back end okay so in order to do this on the same level as the package Json I'm going to create a new file I'm just going to call This Server JS okay so all our backend code is going to go here now in order to start the back end and the front end we're going to have to go into the package Json and change some scripts around so at the moment this script will start our front end but however I'm going to actually write start front end so we can differentiate from another script we're going to write called start backend in which we're going to listen out to constant changes so we're going to use a package called No demon to listen out for constant changes on the server JS file so so cool those are our two scripts and we're going to have to import some dependencies in here too that we're going to need for this project so for this project I'm just going to make this a little bit bigger for you we're going to install a few packages we're going to install the course package to get rid of any pesky course messages the EnV so we can essentially read secrets that we store in a separate file that we don't particularly want to upload anywhere like GitHub we're going to S all our secrets in there namely our Google Gemini API key so that's what we're going to need we're also going to need Express for rooting fs and molter for handling images that we pass through from the front end to the back end no demon to listen out for constant changes as we said and then we're also going to install Google generative AI so just hit enter on that and you will see those dependencies show up here along with the versions that we are going to be using for this tutorial today so this is important these versions so for example Google generative AI this is the version we're using if you're watching this the future and for some reason you know it's like way Advanced as four more likely it's going to be like one uh just go back to using zero for this tutorial cuz that's what we're going to be using today and just do npmi to install that package again or all the packages in fact so once again here are all the packages and the versions that we are going to be using today make sure yours are the same I can't stress that enough if you don't want to run into any errors okay so now that we've done that let's start our front end so I'm just going to do npm Run start front end and this should spin up the front end right here on Local Host 3000 and there we go there's nothing in here for now apart for an empty div if you look in the div with IDE of root a div with a class name of app okay cuz that's what we have in our app component so this is looking good next we need to also spin up our back end right so here's the script we need for that I'm going to open this up in a new tab making sure that I am in react Gemini vision app make sure that is the case and I'm going to do npm Run start backend so just like that and that is now doing its thing so it's listening out however how can we be sure I'm actually going to write something so let's get rid of the package Json file for now and minimize this in the server JS we're actually going to define the port for this I want my back end to be on Port 8,000 let's also go ahead and import some packages so cons Express is what we're going to use for rooting so require the package express uh cores for getting rid of any pesky cuse messages that might block us from making requests from the front end to the back end const app um essentially we're going to get exp press save everything that it contains under the con Express and then call it in order to release all the wonderful methods and properties and save them onto the const app so we can use them so one of them being app listen and we're going to listen out to Port 8000 and then we need a corack function here and I'm just going to put console log to print this out down here we can put listening to changes on Port port and then just the port number right and that will show up every time we make a change in here so this is good we are listening out for changes let's move on some other things we're going to need to do is use app use and pass your course and call it to get rid of those pesky messages and also app use express Json to essentially work with Json and pass it through from the front end to the back end we're also going to require the package Dov like I said so we can essentially work with secrets in our secret. EnV file and then like I said the package fs and molter to work with images or specifically passing images from the front end to the back end and saving them in our back end so require molter like so now in order to use Google generative AI so const we're going to have to get Google generative AI just like that from the package so require and then at Google generative AI I'm just going to minimize that for now so there we go that's everything that we need and in order to work with this well we're going to have to get our API key so we're going to create a new Constructor new Google generative AI and then we're simply just going to pass through our API key which we're going to store an a. dnv file so on the same level as the package Json I'm going to create a file EnV and this is for all our secrets I am indeed going to store my Gemini API key here okay so just like that okay I'm going to paste it in like so as a string and now using so let's minimize this now using process EnV once checking that this is in here I can now get my Gemini API key so that string will now be passed through into this Constructor great and let's save this now something gen Ai and going to save it as okay so we are now all set our setup is ready number one we're going to get an image from our front end and save it to the back end that's number one so let's do it and for this I'm actually going to like I said use FSM molter and we're going to Define where we want to store in our back end so let's define storage and I'm going to use molter disk storage and this is just from the documentation okay we need to define the destination um Rec file CB just copying the syntax uh and then we're going to save all our images in the I'm going to choose to save them in the public directory so just in here all my images are going to be saved in there cool next I'm also going to actually format the file name to whatever I want so Rec file CB again and for the file name well I'm just going to use the date because say we wants to upload an image and maybe we uploaded the same image a second ago we can use date now to actually differentiate it with a string uh I'm going to separate it with a dash and then I'm going to get the file original name okay and attach it to the date now amazing so we've reformatted the file name don't worry I will be showing you what this looks like however first we need to define a upload again just from documentation using molter I need to pass through the storage as the storage that we just defined up here um and then just make sure it's for a single file okay so now I'm going to create a rout up post and if we post to the end point upload I want to essentially get the image that I send over to the upload end point um so that's something I'll be doing from the front end and then we can use upload and then again I need to request response and then maybe let's get the error if there is an error so if an error somehow has occurred I just want to return res send the error code 500 and the J is the error okay so oh an errors is occurred however there's no error I'm actually going to get whatever we pause through from the front end okay it's already saved in the public directory by now and I'm going to also save the file path so actually I'm going to create a variable here so at the moment file path is just nothing right but we can override it with the request file part because we're sending over an image from the front end with the request body great don't believe me let's try it out so of course we need to pass it from the front end so I'm going to go in here and I'm just going to make like a super simple input um so let's do it inut I'm going to give this the type cuz it has to have the type of file so we can deal with uploading files um I'm also going to tell it to accept images so accept just images image like that and now I'm going to actually attach it to a label I'll show you why in a bit so this label is going to say upload an image space and now to link the label to the input I need to give this an ID I'll give this the ID of files plural just so it's really obvious that we're going to use HTML for for and to link it up we need to use this ID name so now they are linked this just means if we go in here at the moment it looks like this and you can kind of see the file right so if I go ahead and open a baby Yoda it says baby Yoda here and you can kind of see this ugly button if I want to not show this ugly button and the word I can just go ahead and put hidden and now if I actually click on upload image so the text now I can also upload an image of baby Yoda however it's not obvious but we know right we know so cool um that's really it if we actually want to display this as well I can do so pretty easily I'm going to go ahead and maybe do this up here so let's import use State from react and now this just means that I can essentially save the image here set image we're going to start off with the image just being null okay uh maybe let's format this a little bit better so at the moment null is assigned to image and if I want to change it I use set image so I do want to change it I'm going to use set image um on change of this input so on change of this however we do want to do a lot of things so maybe let's go ahead and write a function for this called upload image okay so there we go so now I can do const upload image I'm just going to Define that function here just like so and in here I'm want to set image to be the e e Target and this comes with a bunch of stuff files and we just want the first file okay so that's all I'm going to do um and then if I console log image here console log image you'll be able to see that baby Yoda so let's try again baby Yoda and now in the console log you will see the whole file right here's the file we have the name of the file the original name which is baby Yoda we've got the size we've even got the type so lot of information that we're saving that whole object so cool we're saving it we can also display it now so I can for instance just use an image like this a self closing image and as the source of this I'm going to use URL create object URL and just pass through the image so that will now be obvious we can see baby Yodo which is pretty fun however that's all I'm going to use this for I've just set it here so we can see it um in regards to sending it to the back end we're going to essentially use the fetch keyword to make a HTTP post request so what I'm going to do actually is uh append this file to some form data so const form data equals I'm going to create a new form data Constructor and now I can get form data and use append and I'm going to append a property this property is file with the value of this okay so that's now appended um maybe let's move this down here because we want to do that first and this is kind of like a second thing so I've done form data because I wanted to show you how to do that you can also append a bunch more stuff if you want now like for any reason if you want to send something to the back end of like BL the attribute blur and then the value of blur you can so that's why I've done the form data thing so you can send more information if you want when you choose to take this project to the next level Okay so we've got our form data we've appended our file now I'm going to use try and catch so try and catch just like so so there we go let's console log any errors or console error any errors that we might bump into and I'm going to use a wait fetch uh we need to use the async keyword here because we use await we'll save the response of this to something await Fetch and let's pass through the endpoint of HTTP Local Host and our back end is 8,000 and our endpoint is upload and what do we want to send over well we want to send over everything right so the form data so maybe let's define our options appear options as an object in which we send over the method it's going to be a post method and we also want to with the body just send over the form data cool so now let's grab our options oops just get rid of that just like so amazing so this is looking good I'm actually going to just move those options maybe and put them in the try as well so great once we get our response from the backend and I'm just going to get the Json just like that and save it to const data okay cool and then console log the data uh making sure to use a here is also an async method so now I think let's try it out right we have now essentially written the code so here's my whole upload function to send over that image to our back end and once it gets here it should be saved in the public directory so let's try it out I'm just going to refresh we are getting an error message because at the moment the image does not exist so we're going to have to wrap that if image exists then only show this image element great so that will get rid of that error let's have a look and it has so now let's upload an image once again I'm just going to upload a bage of a bab yoga there we go and now that means if I look in here TDA we get baby Yoda appended with the date now and a Dash so if we click on it there's our baby Yoda so we have successfully now saved an image to our back end how cool is that okay cool um if you need to delete them it's easy just delete them if you start to get too many that could be a good idea so wonderful we've done it that is part one the next part is that along with the image we want to pass through some text so like what's in this picture we want to be able to ask that so let's maybe go back to our front end now and I'm actually going to style this out a little bit better okay um not doing any final styling just adding in the correct elements that we're going to need so let's do it for this I'm actually going to create a section so so here we go and I'm going to give this the class name of search section just like that making sure that this is a string so there we go now in here I'm also going to create a div and I'm going to give this the class name of image container and this is going to hold our you guessed our image so let's grab that and just put it in here so this is is looking good let's also maybe give this the class name of image just like that now after this I'm simply going to have a little p element uh and then I'm going to also give this the class name of extra info as that is what this is it's extra info and in here I'm going to put a span cuz I want to break it up and this span is going to have essentially my and input so just put it in like that um of course please format it nicely great so after that span I'm just going to have some text to ask questions about so this should Now read upload an image to ask questions about and that's the end of our P element let's also have one more P element um and this is going to say what do you want to know about about the image question mark and then in here again in the P element I'm just going to break up have a button um I'm going to give this the class name of surprise just like so uh and this should say surprise me H and then I am also going to give this an onclick and on click of this I'm going to surprise so this will just come up with a few options for us so we don't really have to do any thinking just three options okay and we're actually going to disable this so we'll only disable this if we already have a response from the llm cool so that's two things we're going to need to Define let's move on for now so after this P element I'm also going to have another div and this is going to have the class name of input container so input container just like so and our input container well this is where the input the text input is going to be so the text input which is going to take our questions it's going to have a value so we can actually see the value of the question I'm going to have some placeholder text I'm simply going to put what is in the image so that is a question you could ask the llm and on change of this I'm simply going to change the value of this so e e Target value let's pass it through set value so that's another state that we're going to have to write e Target value great so that is the inputs and then we're also going to show two buttons but these two buttons well the first button is going to only show if there is no response from the llm no response and there is no error so if those two things are true then we're going to show a button and this button is going to say go ahead and ask me because there's no responses no errors we're free to ask so on click of this I'm going to actually write a function called analyze image so that is a function we're going to have to write and I'm just going to grab all of this actually and this time if there let's delete all this if there is a response or there is an error well then I actually just want to clear everything right cuz oh we've got a response or oh there's an error let's just clear the whole thing so we can stop Fresh So on click of this we're going to clear cool and then also what I'm going to do is actually show the error right so I'm going to do so here if the error exists then I'm just going to show a p element with that error message so just like that amazing this is looking good and of course we also want to show the response right so if a response exists then we want to show a p element with the response okay done so that's really it I know that's a lot um at the moment we'll get loads of Errors because we need to define the function of surprise analyze image and clear and we also need to set state for error responses and value so let's do it so const value set value equals use State empty string just going to copy that then we also have response set response and error so error and set eror just like that and now also the functions right so const surprise just write a function like that for now and then down here I'm going to do const analyze image and const clear so to clear everything well that's easy because I'm just going to reset all the states so set image is going to go back to being null set value it's going to go back to be an empty string set response is going to be an empty string and set error is also making an empty string so cool this is what it looks like at the moment it's not pretty but it has all the functionality that we need so an easy one to to do is actually maybe just the surprise me button right the surprise me function and just get three strings to show randomly so maybe let's define them so con surprise options equals and then I've already picked this out so just like that so now in order to get a value a random value so a random string from those three I can get the array so there we go open it up and pass through math floor because we're rounding down to the nearest integer uh I'm going to use math random to return a random value from 0 to just under one and then multiply it by the surprise option length Okay so cool so this part can give me back a number even even let's say 2.9 right but 2.9 we can't really pass this through into surprise option it won't give us anything so we use math Flor to round it down to two and if we pass two into the surprise options 0 1 2 it should bring back this string so let's save the random value right uh it's going to be either one of these three strings and we can set value as the random value okay so that will now be saved to here so we're either saving whatever we type here or we're saving whatever we click here as the value okay you don't believe me console log value you will see that in the console so there we go and then if I type something instead like that it shows up or if I change it it will essentially show up as well so we're saving the value great this is looking good next like I said once we get the value and we already have the image as we uploaded the image we want to analyze the image so we want to send over some text or the prompt to the back end I think we can also just set the error here I'm going to set an error as the string of something didn't work please try again okay and then analyze image once again we are going to well first off if no image exist we don't want to do anything right the image must exist so if no image we're going to set error as error must have an existing image so just like that making sure it's just Spell existing the same and then we can just return out of it however if we do have an image right so everything is good then we are okay to continue and we're going to use try and catch so we're going to try something and catch any errors so we're going to console error the error and then let's also set the error you can make the error message whatever you want I'm just going to do something didn't work please try again but you can be way more specific than I am okay so what are we going to try essentially well I think we should try to await Fetch and we're going to send over some text to our back end so we're going to Define an endpoint I'm just going to do HTTP Local Host 8,000 and we can just do Gemini right because we're sending over to our Gemini endpoint along with some options so let's define our options uh of course we do need to save this to something I'm just going to save it to response and because a weight is here we need to make this an async method so con options my options is just going to be an object it's going to have the method of post the body is going to be we need to pass it through Json stringify okay it's going to be an object which going to have the message and just the value that we've saved okay so whatever we typed in the input or whatever we selected from the surprise options we're also going to have to pass through headers so headers and then content type type application Jason just like that okay so this is looking good and of course we're going to have to await the response Jason just like that and then maybe let's save this as data um and then if we want to you know set the response data so we can see it in the browser we PA it through here because the response will be shown if it exists oops get of that s amazing so now let's actually Define our end point right so let's go back to the server and here once again it's a post method and we're going to post something to Gemini so just like that request response and there we go so once again we're going to do try and we're going to catch error console error the error okay and what do we want to try well we want to essentially let's define the model that we want to use so const model equals gen AI get generative model and we're going to pass through an object okay and we're going to pass through the model of geni 1.5 flash latest so that is the latest one and most powerful one at the time of recording so cool we've defined our model and of course the text or the value that we've passed through is with the request body message as the message attribute is what we save the value to so if I get the request body message we should get the text right or the value and let's just save this as the prompt um so just to make sure that this is work just going to conso Lo The Prompt in the back end this won't use this uh okay this is kind of irrelevant we're just checking through that the prompts being passed over from the front end to the back end so let's see so now let's upload an image once more once again I'm going to choose baby Yoda uh surprise me is the image fabulously pink ask me let's go back in here and we do indeed get the text of is the image fabulously pink so that is working this is looking good and of course we could have written whatever in here so you know let's maybe get rid of that ask me and that text should show up so we're getting the The Prompt this is good of course we're only getting that prompt if an image exists so for example if I did that in here error must have an existing image so everything is working as it should great so we're getting the prompt so now I can use it right so I'm going to use await meaning we need to use the ASN keyword here await model generate content and we're going to pass through an array we're going to pass through the prompt and then we're going to pass through the file path that we saved above here however we need to do a few things to it I need to uh format it a little bit so in here what I'm going to do is write a function file to generative Parts we're going to pass through the path I'm going to pass through the mime type into the function and then we're going to just return an object that says in line data just like that and then data is going to be buffer from going to pass through this we're going to use FS read file sync and pass through the path that we passed through into the function and then use two string base 64 okay and then we're also going to pass through the mime type that we pass through into the function so we've just kind of reformatted everything so I'm going to use that function file to generative part going I use it here and then we have to pass through the path and the mime type so the path just is well the file path and the mime type is going to be image JPEG cool so let's save this as something I'm going to save this to results just like that and then we're going to get the result response so result response await this await just like that save it as response and now I'm going to get the response text just save it under the const text and then do sent the text just like so so great that is the four thing let's give it a go right so in here once again upload image baby Yoda surprise me ask me however it seems that in here let's have a look I am awaiting the Json I don't want to do this I just need to get the text as what we're sending from the back end is just some text and not an object so make sure just to get text so this now once again that's just make sure everything is working so you don't have to take my word for it baby Yoda surprise me ask me and Tada no the image does not have a whale it has a baby Yoda holding a cup how cute is that so there we go that's really it we've done it right this is disabled as we have a response this does not say ask me it says clear because we have a response we're done you can now take this project make it your own style it as you want or if you want my styling if you thought it was cool please do stick around just going to style this up super quickly in some super basic CSS so yeah like I said you can either choose to take this now and run with it style it up please do share it with me on Instagram Twitter I would love to see or you can continue and style along with me so let's do it so I'm just going to minimize all these and just focus on the index CSS file for now so I'm going to grab everything and say the font family is going to be sand serif everything in here I'm also going to grab the whole body I'm going to do margin zero padding zero to reset it let's make the width of Everything 100 viewport width the height of Everything 100 viewport height just like that and then I'm going to change the background color so it's kind of like an off-white f a f a f c okay let's change the color as well I'm going to do da da like just this gray color and then I'm going to initialize Flex box so that we can Center everything from left to right so that is my body next I'm going to grab every P element and just give it a font weight of 200 and then a font size too okay so all of them are going to have the same font size of 14 pixels cool next I'm going to grab the app itself so the element with the class name of app and just give it a width of 90 viewport width so it's a bit smaller than the desktop next I'm going to grab the element with the class name of upload and change the text of this to be purple so let's do 6 E1 e81 so that is a nice purple color okay now I'm actually going to grab the image container so the El with the class name of image container and I'm just going to give this a height of 200 pixels it's going to hold my image I'm going to use display Flex to essentially Center the image using just AI content Center and then I'm going to give it a margin of 30 pixels to space it out from everything now the image inside the image container so I can actually grab this and say the element with the class name of image that we gave it is just going to have a height of 100% of the the parent element so it always kind of fits inside next I'm going to grab the element with the class name of search section just like so and I'm just going to make sure that it spans the whole thing so 100% I'm going to use display Flex once more to make sure that everything is stacked on top of each other using Flex Direction column and I'm going to Center everything again great so moving swiftly on I'm now going to grab the button that has the surprise class name and I'm going to give this the background color of this gray e c e cf1 let's also change the color of the text to be black uh and I'm going to give it a border radius to kind of round it off a bit of five pixels let's also give it a font weight I'm going to give it a font weight of 600 um the padding of this I'm going to give four pixels on the top and bottom 12 pixels on the left and right and the margin of this is going to be zero on the top zero on the right two pixels on the bottom and five pixels on the left okay and I'm just going to get rid of the border so if you want to see what this looks like now is probably a good time to show you this is what the button looks like that's what all the text looks like we just have the input ready to style next so let's do it so now I'm going to grab the input con ster just like so and I'm going to make sure that it spans the whole thing the whole parent um I'm also going to initialize Flex box I'm going to give it a border radius of six pixels and an overflow of hidden okay and a box shadow that I have pre-picked out already so here is my box Shadow wonderful and now that we have the input container I'm going to sa the input that lives inside the container well again I'm just going to get rid of any border that exists any default border I'm going to give it a padding 13 pixels on the top and bottom and 14 pixels on the left and right box sizing is going to be border box font size I'm going to make it 15 pixels in here so slightly larger the outline of this is going to be none I don't want any outline on it the width of this is just going to be 90% cuz the buttons going to take up the rest and the font weight is going to be 200 so now let's grab the input container uh actually maybe let's grab the input once more because I want to actually style the placeholder text too so placeholder let's make the color um just this gray really and then the font weight is also going to be 200 cool so now let's actually grab the button that lives in here and I'm going to give a Min width of 10 pixels to compensate for the input let's also give it a border of none and then a border left of one pixel and then ca ca ca the gray and I'm going to make it solid I'm also going to give it a background color of this white and then the text color of Gray I'm going to also give it a font we of Bold and the cursor is going to be a poter so cursor pointer cool now if the button is active so just like that I'm going to give it a background color of ca ca ca and then let's also make sure that anything with extra info as a class name it's going to have the text aligned Center and finally the response right I'm also going to give this a box Shadow same as the one above and padding is going to be 13 pixels top and bottom 14 pixels uh left and right the Box sizing is going to be border box the font size is going to be 15 pixels and the font weight is going to be 200 and finally the Border radius is going to be six pixel so there we have it that is what it looks like all styled up okay just make sure that the appjs file in here on the response I'm just going to give this the class name of answer as well just to make sure that that styling is applied okay so now let's give this to go upload an image once again I'm going to go with baby Yoda so same one each time surpris me does the image have puppies does the image have cats ask me and then we should get our response no the image does not have cats it has a cartoon character from the Star Wars franchise known as the child or baby Yoda I love it and of course because we do have a response this is disabled this doesn't say ask me this says clear and and yeah this is looking wonderful I'm happy with this one other thing you might want to do is just maybe wrap the extra info so this P element right here and just say if there is no response show this okay because if there is a response we don't want to be able to upload any more images so let's try that one more time baby Yoda surprise me ask me a question and taada amazing we cannot change the image anymore this is looking good so yes please do share your final projects with me take this to the next level like I said i' absolutely love to see how you startled this made this your own please do share this with me on Instagram Twitter or wherever really\n"