The Ultimate AI Next.js 13 Crash Course for Beginners - Build 4 Apps in 12 Hours! (2023)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
yo do you want to build an insane chat GPT messenger app a beautiful d 2 image generator an AI trell clone with dragon drop features or even a realtime weather app welcome to the AI nextjs 13 crash course where we're going to be building four amazing apps in just 12 hours that's 12 hours of straight up coding with no pauses no interruptions just pure fun throughout this AI crash course you're going to learn amazing bits of tech such as reactjs nextjs 13 tawin CSS script Firebase Version 9 and Firebase admin and most importantly how to integrate AI services such as open AI into your next nextjs app and finally we're going to be able to deploy these apps using Vel so I'm going to show you all of this it's going to be a breeze and that's not all guys I'm even going to show you how to integrate amazing Tech libraries such as Microsoft Azure including Cloud functions and the blob storage service use SWR cool libraries such as react DND for drag and drop Z stand for GL Global State Management headless UI to build great accessible components database services such as Firebase and at bright Cloud trema 2.0 to level up your apps styling graph ql and steps Zen to make deploying your graph ql interface that much bit easier and I'm even going to show you how to integrate chat GPT and the Del 2 API into your app so that you can include all of those great AI services that you've been seeing all over the news and of course how to tie all of this together to build fully functional web apps that you can go ahead and show case on your portfolio now remember guys all of these videos are trimmed up we've edited them the entire team has put a huge amount of work and effort into making them so that you get zero interruptions when you're watching this the least that we ask is that you smash the like button to support this video and help it reach as many developers as possible and if you want to go ahead and Skip to your favorite part you can go ahead and check out the time stamps in the description or on the video timeline now remember guys if you get stuck at any point inside of this a AI crash course then I highly urge you to check out Zero to fullstack Hero Zero to fullstack Hero is the world's best developer Community we have over 120 hours of amazing coaching corol content and module content this means you can get direct access to video content where we go in depth to teach you exactly what you're after from a absolute beginner perspective all the way to a full stack hero I put my heart and soul into building this course this community now we have over 1,000 th members we know how to grow our students from absolute beginner levels all the way up to Landing production level jobs inside the course I myself hold weekly coaching calls where you have the chance to ask me any questions in your developer journey in addition we also have success coaches teaching inside the community every single Friday this means you get mentorship all around you get mentorship from myself mentorship from the entire community and you have a lifelong support network to go ahead and help you become the best developer you can possibly become with that you get access to the entire papam community so you're never going to get stuck or feel like you're ever alone ever again and for those who want to take things that extra step further definitely check out our Diamond plan in our Diamond plan we have an additional 80 hours of coaching for Content inside of it I also go ahead and teach additional coaching calls every fortnite this is the membership we want to be a part of if you want to take your skill set to that Elite level of developer but look don't take my word for it let's see some results from our students themselves inside of Z to full Zach hero Gabriel Graves one of our Diamond members now works at PayPal Rocky Morgan landed an internship at MasterCard shortly after joining the papa fam Fabian landed a full stack developer role at Vodafone ranhoff delivered an entire web 3 training after he learned a ton of this knowledge inside of zero full stack hero he now delivers major AWS talks at Big conferences we have students like Alexander winning thousands of dollars winning hackathon events he won two events back to back Alex eckan now jumps around the world working remotely Developer jobs from Thailand to different locations all around the world simply with the help of the papa F take Samuel for example he landed a job by using the Netflix s built on the channel and debugged it with the help of the community inside of zero to full stack hero I can go on and on for hundreds of different success stories this is probably my best achievement I've ever made in my entire life and I can go on for hundreds and hundreds of more success stories I want you to see for yourself so simply head over to the link on the screen right now and see our students we have lots of videos up on there right now you guys can actually see for yourselves real people getting real results and to help our course become more accessible to all of the students around the world we now support purchasing power parity to see what discount your country has simply go ahead and see if there's a blue Banner on the top of your page when you visit pap.com course and you'll get a relevant discount code applicable to your country with that said let's get started with the first of four builds inside of this AI crash course starting off with one of our most viewed Builds on this channel with over over 1 million views introducing the chat GPT messenger in this build you're going to learn incredible bits of tech such as nextjs 13 reactjs how to use chat GPT using the open AI API and how to leverage the different chat models such as GPT 3.5 turbo and GPT 4 you're also going to learn how to leverage libraries such as use SWR to go ahead and further fetch data more effectively and efficiently and you're going to learn how to integrate fire base Version 9 and Firebase admin to go ahead and store the data that we're going to need inside of our app and of course to keep the code robust we're introducing typescript and to keep it looking elegant and beautiful we've introduced Tailwind let's jump straight in without further Ado let's go ahead and give you a absolutely amazing demo of the chat GPT clone check this out guys boom we have the chat GPT messenger let's go ahead and sign in firstly because we can do that we have Google authentic ation I'm going to go ahead and sign in with my Google account because we've absolutely you know we had to have proper authentication in here now look at that look at how clean that is you would think that's the real thing is it the real thing no it's not it's the absolutely amazing clone that we have right now as you guys can see this is not a normal boring build we have the ability to choose from all the different available models over at chat GPT we can go ahead and create our own little chat so let's go ahead and create a new chat right now we've got Dynamic rooting in next year's 13 let's go ahead and uh click on the joke right here so tell me a joke and write an essay about it that's one example of a chat let's checking out another one one uh write a story about a coder who learned to code from YouTube tutorials and I said here are you're a human right and let's go ahead and test this for ourselves to see if it actually works because that's why you're all here right you want to make a chat GPT clone so right now go ahead and give me a question right now give me a question right everyone think are you creating your own prompt we have the ab we're actually connected to the open API prompt so this is going to be open API API right so open AI API wow okay crazy let's go ahead and explain what JavaScript is Right explain what JavaScript is enter chat GPT is thinking guys we've got live react hot toaster notifications in so clean so so clean right we've got um look at that JavaScript is a programm language that is used to make web pages interactive as lightwe flexible language oh that's just that's just so beautiful right so so beautiful so let's go ahead and break down this app right and bear in mind you know I don't do things half Hast right look at this fully responsive fully fully responsive and all of these chats I'm going to go ahead and demonstrate what the hell is happening right now so we are going ahead and using chat uh fir store to go ahead and store these chats bam check this out right so look at this we have inside of here the users then I have the users so in this case I've got my two accounts Pap react and sunny I'm logged into sunny and you can see I've got chats over here so here's a bunch of chats I've gone ahead and um I've had a bunch of test ones as well as you can see um but let's go ahead and type in something like let me go ahead and create a new chat new chat and let's go ahead and see you see it created a new chat let's go ahead and look at what's going on here and let's go ahead and type in hello world enter and as you can see what this will do is it will start a collection of messages inside of it so I need to refresh that right now so just go inside messages and as you can see what is happening here is absolutely mindblowing so I'm going to explain the flow of what's happening right now and I'm going to show you remember you're going to learn all of this in this video for absolutely free so buckle up cuz it's a lot to take in right we are using a realtime database right now now check out what's happening here if I go ahead and say explain JavaScript to me right and I go ahead and hit enter so it just entered in my question now what's happening is on the back end we're connecting to Firebase admin API which is then connecting to open AI API which is then formulating a response from chat GPT which then fills out a response and then we have a real time connection to our web app bam just like that just like that and all of that is built with nextjs 13 tell wi CSS all that good stuff and we're using things like uswr so we got caching we've got server components we've got client components we've got Dynamic page reading hot toes notifications everything you can think of is in this build so I you can see why I'm excited now right the code is already in the papa GitHub repo so if you want to go ahead and check it out you know where to go otherwise build along with me that's it simple as right let's dive into the tech stack of today's build right so I'm going to go ahead and get my little pen up on the screen so I'm going to say screen brush there we go loads of you ask me that question all the time it's actually called screen brush that's what I'm using when I'm drawing on the screen right so let's go ahead and dive into this right now is my screen sticking there we are okay so we have typescript under the hood yes we have typescript right we have nextjs 13 which obviously is powered by react so you're going to learn all about react we have Firebase right so Firebase and lots of things about Firebase we have Firebase fire store we have Firebase oh no oops oops okay I've lost it we have typescript we have react why am I doing that right react we have nextjs 13 don't worry about it not not 13 not 14 there we go we have Tailwind CSS we have chat gpt's API so tons of stuff you're learning in today's video we even have next or authentication which is connected to Firebase or so we have Firebase Google authentication so not only are you getting authentication you're getting like learning about typescript all this good stuff and on top of that we've made it super performant we're using things like use SWR for efficient data fetching right amongst different components all this kind of cool stuff and if you see this right here this is actually pulling from the chat GPT models list so this is actually going to go ahead and pull all of the available models from chat GPT so not only are you going to be able to use the da Vinci model but you can use any model that open AI delivers and because it's frequently being updated it will fetch the most recent list and then it will feed that into the open API open AI API I'm going to get that messed up so many times today so forgive me right so much is going to happen in this video right so we have all of this happening you're going to learn about react Firebase Hooks and how you can get this realtime connection going on you're going to learn all about server components right so all the the brand new you know the new and exciting thing going on in xjs right now server components you're going to learn all about that and um we're going to talk about Firebase admin which I haven't done in a long time right so Firebase admin and how we can leverage this on the back end to do administrative things such as allow our server to directly write into our database so that requires a lot of configuration and I'm going to make it seem like it's easy because it is going to be easy following the steps I'm going to show you okay so buckle up get excited smash that like button um let's go ahead and jump in now before we jump in I am going to show you how to actually deploy this app in the end of it so most of you are going to want to add this to your portfolio I'm going to show you how to deploy this onto Vel afterwards so let's go ahead and dive into this build without further Ado so jumping into things right tell me if you'll enjoy this music you can get it in the link in the description right so we're going to go ahead and firstly get our key to open AI now if you don't know what the hell chat GPT is it's an incredibly powerful AI chat bot and basically what you can do is you can talk to it and ask it any question and it's trained on so much data across the Internet it's not live connected to the internet but the model has been trained on a huge amount of data so you can ask it things like coding questions you can ask it things like natural language questions you can ask it anything and it pretty much will give you a solid answer depending on if you gave it a good prompt or not and I'm going to show you how to add that into your own apps so you can build the next bazillion dollar app right and and make yourself famous right do do whatever you want to do with it I I don't care but it's cool all right so in this case we're going to go to open ai.com I've logged in right so you'll you'll be able to hit this screen once you log in right so in this case all you need to do head over to personal on the top right click on view API keys and a lot of you always ask a question is it it free you know do I have to pay for this no it's absolutely free you can do this right now so this whole tutorial is free right even the keys all that kind of stuff it's free don't worry about it right so API Keys all you want to do is click on create new secret key so I'm going to click that right now bam and I'm going to hide the screen because it's created me one and then I'm going to click on copy and I'm going to click okay and then I'm going to hide it and as you can see now I have a key I have a second key so in this case you can create as many keys as you want if your key gets compromised you can go ahead and revoke the key key and so forth okay so I've got a test key that I'm going to keep on here while we go ahead and get things working and then I'll show you how we basically come back but this is going to be the key that allows us to connect to chat gpt's API so it's very important that you get that key so that's the first step okay first step out the way second step is we're going to have to go ahead and create a Firebase project right so all you want to do head over to firebase.com now Firebase is an amazing Suite of tools they allow you to have things like real time databases the firestore databases which we're going to use today and it makes things like authentication so simple okay so it brings it down so that we as a developer can just enjoy what we want to do which is build the damn app as opposed to hm I don't know how to make my my authentication work the perfect way and stuff like that it just handles it right that's what we want so in this case we're going to go ahead and go into my correct account before I go ahead and do something I don't want to do right and then we are going to click on go to console okay now we're going to go ahead and head over to add project so you want to go ahead and create a new project right now so click on ADD project and here we're going to go ahead and say chat GPT messenger I'm going to say YouTube okay so you can call it wherever you want really it doesn't matter okay continue I'm going to disable Google analytics and we're going to create the project now it's worth mentioning that I have no connection to open aick GPT any of those Services I am literally just teaching you how to interact with their apis for purely entertain uh entertainment and educational purposes all right so that is it that all it is educational purposes right now we're just trying to help you interact with their services because they already have over 100 million users on their platform that's the fastest app to ever get that by the way all right so let's go ahead and click continue and then let's go ahead and firstly head over to actually we can pause here this is good right so now we've got our Firebase set up and then we've got our API key done cool now the next step is we're going to go ahead and initialize our first ever project right so in this case we're going to be using Tailwind with nextjs and we're going to use this lovely little template over on the Tailwind website and all you have to do is go ahead and copy this MPX create next app uh - e with TN CSS my project okay and then we're going to go ahead and copy that so first things first open up my terminal nice we're going to go ahead and make this massive cuz I always get comments I can't see what you're writing there you go hopefully that's good all right and I'm going to go ahead and put in my documents I like to just put in somewhere like documents builds I don't like to throw this everywhere right so you can put wherever you want right but now you want to go ahead and pop it in and then you basically just want to change this final um final sort of command argument so this one is going to be the project name so in this case I'm going to say chat GPT messenger YouTube hit enter this code is available on the papa GitHub repo right so definitely if you want to check it out you get stuck what I would recommend is try a code along with me it's completely free that's the best way or you can go ahead and get access to not only this code but every single build I've ever made on YouTube it's all in the pap GitHub repo the link is in the description feel free to go grab it okay so and everyone always ask why do you charge for your GitHub Reaper because too many people just copy it and they don't put in the work and that is honestly why I get so angry with the like new upcoming developers put in the work and I'm giving it for free so put in the work and make it happen or just just buy the repo that's it it's simple as right it's it's a way to stop you I'm I'm actually trying to help you out when I do that okay so in this case we're going to go into CD into chat GPT uh messenger D yoube bam and then we're going to go ahead oops no okay don't do that I'm going to type in CD there we go and then I'm going to go ahead and put in code do bam okay and then this will open up our vs code now if you tried to do this command code Dot and it didn't work the reason why it didn't work is simple the only reason why it didn't work is because you haven't got this command uh set up so command shift p and I'm going to type in install and then at that point you'll see install code command impath I have code inside this cuz I use the beta but in this case just do install code command impath and it will work then you might have to restart your terminal but then you'll have that ability to do what I just did if not just go ahead and click on file open and open your workspace okay as simple as but now we have our nextjs 13 app right now you're probably wondering this ain't nextjs 13 because we have a page directory here right this a bit doesn't look like the new app directory Sunny well we have to go ahead and set it up and tell it that we want to use the new nextjs 13 features now if you haven't ever touched nextjs 13 but you've worked with nextjs before I highly recommend you check out my nextjs tutorial where I run through the entire sort of conversion over to nextjs 13 from nextjs 12 I give loads of different coding examples but otherwise if you get stuck at any point with any of the things I'm talking about around nextjs 13 then that's how you go ahead and do it okay so in this case what we're going to do is head over to my next config and we have to tell it that we basically want to go ahead and use tell me if the screen's good I think that's better as well right so now I'm going to go ahead and type in experimental and I'm going to give it an object and inside of here I'm going to say the app directory is going to be true okay and then what I want to do is come command J to open up my terminal now I'm going to go ahead and just cut my old app right cuz it was running as well and what you're going to do is command J opens up your terminal now here you want to go ahead and type in Yar run Dev okay I'm using Yan as you can see I've got a Yar lock file if you have mpm or package lock file then you'll be using mpm if you want to switch that is fine all you need to do is then use the opposite command like if I had package lock I use yarn but then I'll delete my package lock and then run yarn and then I'll get the nice yarn lock and so forth you just swap it over right but make sure you just stick consistent with the one that you want okay so in this case yarn R Dev bam and what this will do is it will start up the application on our Local Host 3000 right so I'm going to go ahead and open this up right now and what I like to do is set up my coding environment so we're going to push my code over here I'm going to go ahead and pop my other app over here and then we're going to go ahead and do the following I'm going to Local Host 3,000 okay and what you should be seeing is this beautiful screen right here this is going to be your starter template next JS 13 starter template what we're going to do is basically kind of like translate this from nextjs 12 to nextjs 13 very quickly and I'll show you how well nextjs 13 uses the new app directory the app directory basically allows us to have loads of things uh no everything in the app directory is basically a server component by default right so in this case we're going to use the new server components and in this case we got a create an index page and there is a certain file structure we have to use there is a reserved word called page. TS s x and in this case this will create our first page our index page so I'm going to type in RFC right and if you're wondering how the hell did he just do that well firstly I'm going to rename that and secondly I'm going to show you how I did that so the what you need to install is es7 react Redux Snippets just to install that you can get those nice little uh things that I just did okay so let's go ahead and do that now and then oops okay I keep opening this up bum you know it's crazy I first started doing this when it was like a million that's crazy now it's 7 million hope I had some impact on that right so we're going to go ahead and remove that right now right so in this P we have the page right now this obviously isn't going to work because we have nothing attached to it right so in this case I'm going to show you how we can change this which is located in our Pages index we can go from this page to this page instead now I'll show you how we do it firstly we can delete the old page that's fine get rid of it don't need it right and then we're going to go ahead and type in H1 chat GPT messenger bam hit save and then I'm going to go ahead and do command J now at this point I'm going to cut my server so contrl C and then I'm going to do Yar runev now watch the magic that happens now whoa firstly it said contains a typescript version okay so I'm going to click on allow fine then I'm going to refresh my page and then look how it creates random files to me right well explain what the hell that is so firstly we've got the layout file this is where we have our layout constraints of our components right so in this case all the pages are going to be basically be injected into the children property here so at each level right so we have loads of different ways of doing this um so at this point and then we can inject anything that we want in the head for example the title so in this case I'm going to type in chat GPT clone right hit enter or save sorry and then we're going to refresh and then you can see we changed the title so super easy okay and then we're going to go ahead and hit page now at this point we have our page but you can see this is not Tailwind this is some like old school you know font that we just don't want to associate with right so at this point we need to go to uh layout and then what we need to do is take and steal this where we have our Styles this is basically where we import our Tailwind magic so I'm going to go ahead and copy that head over to my layout and I'm going to go ahead and hit uh paste right hit save and then what we should see is boom that that's nice right so what this is doing is this is basically going ahead and stripping all of the styles from us because we want to go ahead and whenever we're using Tailwind we want a blank canvas okay okay so if you don't know what Tailwind is go check out Tailwind css.com what are you doing because it's absolutely a banger way of writing your CSS it's my favorite way and it's the way that I'm doing it in my builds okay so that's why we start off with an empty like styled uh H1 like that now we can get into the magic now okay so you don't actually need the app. TSX file you can get rid of that if you want I'm just going to keep it for now but in this case we have a starting point so what I like to do is Mark things up okay so what I'm going to do is I'm going to open up my old app I'm going to run it on a different port so I'm going to run it on like 3001 for example right and it probably won't work because I just realized something so if I do 31 it's probably not going to work with my authentication I have a feeling it won't yeah oh no okay I mean we get this far that's fine I can do this okay I can use this as a rough draft right so we need to get from this to this right so how the hell do we get from this to this well firstly just take it in steps right so take it in nice little chunks okay now what we're going to do is we're going to essentially have things like the sidebar and this and like this bit basically we're going to have that in the layout file because that's going to be a part of every page right but this right here the chat GPT part this is going to be the page that gets rendered out so this is going to be where I'll basically have in page. TSX I'll have the code for this and then here I'll have a sidebar component inside of my layout. TSX okay so let's do that right now so heading over to layout in this case and you're going to see why it's really nice once we understand the new way of doing things why it's so cool to be doing it like this right so in this case I'm going to pop open this right here and I'm going to put in a div and I'm going to say the children go inside the div simple as right then we're going to have a comment for the sidebar so this means I need to build a sidebar there right and I recommend you do this honestly it's going to help you out a lot right and then we have the content down here right and I'm going to wrap the content in a div okay so we're going to have the sidebar here we're going to have um something called a client provider here and what this will do is this is going to be for the notifications so those nice little chat gpts thinking notifications that you saw earlier that is all going to be inside the client provider so we are using something called react hot toast notifications and that gives us this nice Dynamic sort of chat gpts thinking and then that way the user isn't sitting there thinking what the hell's going on this thing's crap right so it works but it's a nice way of kind of you know giving it a little bit of feedback somebody says are you live yes I am live my friend right so in this point we've got the sidebar the client provider and yeah we're good okay so I think we should firstly do this part because this gives us the most kind of like I can see something back from it right so I I can see the response right so I can see like something being built so in this case I'm just going to start styling things out now you're probably going to wonder how has he got all of these Auto completes well if you go over to Tailwind uh extensions and then you type in Tailwind CSS I have tons as you can see right you can go tawin TSS intellisense install it thank me later right I promise you it's going to be a game changer right so install that that's how you get all these nice little fancy extensions now once we're here we're going to go ahead and type in BG BG stands for background color at this point we're going to go ahead and say a custom color now this custom color we are going to use a bit you know throughout the build but this is going to be somewhat of the background that we're going to be in considering ourselves with so in this case I can add that in and then you can see I've changed the background color there right then I'm going to type in in Flex one okay now the reason why I'm going to do Flex one is because the div in which surrounds everything is going to be a flex box okay it's going to be a flex box and eventually the sidebar is going to be you like kind of working against this Flex box as well and this all this cool stuff's going to happen Okay but this is where we move over to the actual chart now this is the layout and then we go to the page all right so inside the page and remember we actually go over this all so so in depth inside of zero to full stack hero so if you really want to just become a pro at this stuff and you want to skip all the I want to watch all the tutorials and kind of you know figure out then you can go ahead and and join Zer stack hero right we have two memberships platinum diamond and our members are absolutely loving it and they are so sick as react developers it's incredible all right so at this point we're going to build the page that you see here this part here okay so we got a bunch of icons bunch of different styling that kind of stuff weit have a warm-up exercise to get us ready for the main event right so in this case we're going to have a H1 and in this h each one I'm going to change this to just say chat GPT hit save and let's start styling it out so this is going to be a text 5xl it's going to be font Bo and it's going to have a margin bottom of 20 okay hit save and you can see that's already a lot bigger right a lot nicer now for the class name I'm going to go ahead and say that this should have text white so everything inside I want it to be of white text So eventually we're going to get to this right so this is how we start getting to that process now in terms of the actual layout this is going to be a flexbox and again if you want to know more about flexbox definitely check out my flexbox froggy video if you're watching the replay somewhere around here right now otherwise Jay's going to come in clutch and pop it in the chat right now okay so in this case Flex Flex column and then we're going to say items should be aligned in the center right and that gives it a nice little Central axis now if we do justify Center what you'll find here is that this will go ahead and Center it on the y- axis as well but you can see it did nothing that's because we have to set the height to be of the screen that means it will use up the full amount of the screen and it's just nicer to do that right then we want padding on the xaxis of two so that way once the screen gets small enough it's not going to touch the sides right we want to have a little bit of breathing room so hence I've added a little bit of padding okay good stuff now we're going to open up a div and this is where we have the interesting portion so now we've got this which basically what we're going to do is we're going to have a container around these and then inside we're going to have a container we'll basically encapsulate this and this same for this same for this and then we're going to go ahead and pop these in right so you've got to explain something to me and all these kind of things right so I'll go ahead and make it easy for you don't worry okay so first things first we're going to go ahead and pop in a P tag which says explain something to me what is the difference between a dog and a cat and then oh actually before we do any of that I need to actually go ahead and pop in the icon itself so we're going to do it in sort of like lines we'll do this line first then this line then this line okay so the first line is going to be a um inside of it we're going to have another div and then this one's going to have a another div because it's going to resemble this the icon so we need the sun icon and then we need the H2 which says examples okay and then the sun icon how do we get that right well we'll touch on that in just a second but after that we're going to go outside of here and we're going to have a div and in here we're going to have three p tags and I'm using EMT to make our a little bit easier now I'm going to save us a bit of time and just copy in the following so I'm going to put some text in here and add a class name bam right so all I've done is added the infotext class name and I'll show you that infotext does nothing at the moment that infotext does nothing at the moment that's a custom utility class name which we have yet to create okay now these are two closely bundled up so I'm going to go ahead and space them out so space y of two bam so in this case we've got the examples and then we're going to go ahead and start that out that actually don't have a style so it's pretty simple and then for this one we're going to go ahead and give it a flex box Flex column so this is the one with the icon in items are going to be aligned in the central axis justify in the center as well with a margin bottom of five bam right so that's how we're kind of getting along the lines of this now so you can see it's going to be basically very close to this very shortly okay so the next natural thing that we need to do is go ahead and get access to icons so I'm going to go ahead and do that right now and I'm I stupidly just minimize my code there we go um so how do we do that we use something called hero icons now hero icons is super cool it's built built by the guys over at tailwind and it's so easy to use so what I like to do is keep this open to go ahead and search for different icons and then I click through the documentation and I simply install now here you can see mpm install I'm going to do yarn add right so in this case let's go back to our code we can actually close that right now to make life a bit easier command J I'm going to open up a new terminal while my old one is running and I'm going to say Yar add hero icons react because I'm using Yan okay right so we've installed it that's amazing and now I need to use it so in this case let's just start with an example copy the first example and I like to show you this because it makes your life a little bit easier when you're watching it back right so if you're doing this on your own this is the way I'd recommend it copy the example copy the use case example and then pop it in and just see how it behaves see how it acts right so that gave us a blue beer icon now in this case I don't want a beer icon I want a sun icon right so we have two options we have solid variants and we have outline variants okay so in this case if I go ahead you can see we got solid and outline I'm going to use outline and what I need is something called the sun icon okay now I found that by going into the search directory here and typing in Sun and I just typed in Sun in here and then you can see it starts Auto like Auto kind of filling things out right so Sun icon is the name for it I'm going to replace this over here like so right so go ahead and save now you can see we got a nice little sunshine example nice right and I'm going to do eight and eight so cover that eight and eight and then text blue 500 just get rid of it because it what it does is it sees icons as text which means I made the parent text white which means all my icons are going to be naturally white okay so you can see we're kind of getting there right slowly getting there now we've got we've given this like info text here to a few different areas right now what I'm going to do is create a custom utility class so I'm going to go into Styles global. CSS and in here I can create my own custom CSS utility classes for Tailwind right and basically this allows me to prevent me writing out the same lines of utility classes again and again and again right it makes it a lot easier to go ahead and repeat and reuse what I want to do so how do we create a custom utility class firstly we go ahead and we say at uh layer components right and then here what we do is we basically inject our own like kind of Uh custom classing so here I say info text and then I say at apply that's the keyword that's like the way that we basically that we have to write this for Tailwind to basically accept it right so in this case that's how we do it okay now basically what I'm going to do is as I start applying these what you'll see is like padding of four you see how all of them got padding of four nice right right so padding of four now what we're going to do is go ahead and say background gray 700 and then we're going to give it a 50% opacity right I'm going to round the corners by by saying rounded LG and I'm going to give each one a Max width of a set of custom value of 300 pixels right now as you can see boom look at that like look how it just snapped together right look at that boom and because we're using Flex box it's all styled out it's all working the way it should bam that's really nice okay so at this point what we can do is we can now copy what we have here right so what I'm now going to do is basically take the div at this point right so we're going to take this div I'm going to copy it right and as you can see what I'm going to do is paste it again paste it again so now I have three of these things right and I'm going to change each one to how I need it so the next one is going to be a boat icon right and then I'm going to do control space bar and you can see it automatically Imports B icon for me and then I'm going to go down to the exclamation triangle icon okay again import it at the top and as you can see look we've got the new examples and then I'm going to change the boat example to capabilities and then the exclamation triangle to limitations okay so there you go we've got limitations capabilities and then I'm just going to Simply change the text of each of those ones right so all I'm doing here is basically replacing these P tags so I'm getting rid of them and I'm popping in P tags with different bits of text in okay so you can feel free at this point to really add whatever text you want again I'm just doing this more for the UI right so I'm going to remove these three p tags and I'm popping in my own three p tags and that's it okay now you can see this is not being laid out correctly right it's not nice it doesn't look good don't try and convince me it doesn't I this I'm not accepting this right this looks horrible so at this point we now need to make the surrounding div so the surrounding div can encapsulating all of those three that we just copied we're going to go ahead and say class name make it a flex Box by default when I hit save they go into a row okay then we say space them out with a value of two between the x axis now you can see we've got a bit of breathing room between them and then as a parent component I'm going to say all the children within should have text centrally aligned and just like that pal now sirat says using grid instead of flex doesn't better isn't better isn't it better for this you can you can definitely do it I'm just showing you Flex box here but feel free change it up however you want right you can actually use like a colum a grid of three as you get into a mobile view change to a grid of one feel free remember there's 100 different ways to do the same thing when you're doing this kind of stuff right so that's looking damn good okay now I think we should build a sidebar right so the sidebar is the next element that we're going to tackle so in this case this is our final build I need to have that cool looking sidebar over there right so let's go ahead and do that right so in this case I'm going to go ahead and pop open the layout like so and then inside of here I'm going to create a sidebar so now what I'm going to do is I'm going to go ahead and create a new component folder so in this case we've got the app and then I'm going to go into package Json at that level and I'm going to create a folder called components okay and now inside of the components folder I'm going to go ahead and create a new file and I'm going to create a sidebar. TSX now inside of here I'm going to do RFC bam I now get my nice little snippet I'm going to cut that out we don't need that anymore in the latest versions of react on XS sidebar goes here that's what I'm going to write for now okay now I at this point we've got go to the layout at this point we're going to say sidebar and then I'm going to close it right and now what you're going to see is look the sidebar goes here right so you should be able to get that at this point remember at the top level they're just Flex so they're basically sitting next to each other right so at this point you've basically just got two children so if I was even to get rid of this look two children this div and this sidebar and then they're Flex next to each other which is why I seen it like this okay so now let's go let's add some jazz to that sidebar so it starts looking good and this side is going to play a very important uh aspect to this entire build right so it's going to have a lot of functionality inside this sidebar so first things first let's go ahead and start this out let's go ahead and say a padding of two it's a flex box it's going to be a column Direction Flex box and it needs to be the height of the screen okay that's a little bit breathing room there it's better okay somewhat better and then we're going to go ahead and get rid of this like so right so at this point now we're going to have another div boom right and in the final build you can see here we've got a new chat button right so we're actually going to create a new chat button and then we're going to have like you know these different chats and all that kind of stuff so there's lots of different components here lots of different ways to kind of get this right but the first thing I'm going to do is create a uh class name and I'm going to say Flex one sorry Flex one and then in here I'm going to have a I'm going to start doing my little comment magic I'm going to say a new chat needs to go here right so a new chat and firstly inside of this Flex one div I'm going to have another div with the new chat inside of it okay so we've got the new chat that's going to be a component and then we're going to have a div with a model selection inside so inside here we're going to have model selection so this is going to be like for selecting the different models that's going to be a component of its own um and then we've got this one for new chat awesome stuff and then we've got these individual chats all right so then we're going to go ahead and have the chat rows right so then here we're going to map through the chat right so in this case chat row I completely fudged that one up right chat Rose okay whoa map through the what am I doing with my I need chat GPT to help me out spelling right so at this point that's pretty good and then we're going to have you know the the picture down here so that kind of stuff we're going to pause on because we need to kind of have things like Firebase set up in order to go ahead and continue those right but before we kind of you know call it on that one I'm actually going firstly have a new chat button which I think we can go ahead and actually Implement right now so let's go ahead and say new chat right we're just going to make it bit of a dummy button and then we're going to go ahead and create this component so inside of my components I'm going to say new chat. TSX newr DSX there we go bam RFC like so oh my God okay RFC so sometimes that happens right it gets annoying so RFC my Snippets don't work so what I do is I just copy this paste it uh get rid of that and then I have a new component I just rename this to new chat how right and now we have the new chat inside of my new chat I'm going to go ahead and simply have a plus icon and a new chat par P tag so in this case I'm going to have a div with a P tag inside and I'm going to have a plus icon um with a outline actually know we're going to have the solid variant here so what I'm going to do is I'm just going to import that I'm going to change this to a solid variant cuz I want the solid one right and then we going to say class name and it's going to be height and width of four so height and width of four boom and inside the P tag I'm going to say new chat simple as right so new chat now let's go back over here import it so we can see our new chat component right so there you go new chat cool uh is everyone with me so this case we're going to say div and now I'm going to go ahead and style this up and I'm going to make this look a lot more like the chat GPT new chat button right right so it's going to look a lot nicer in that sense so first things first I'm going to say border should be gray 700 right then I'm going to say the that there should be a border in the first place the items should be centrally aligned and it should be justify Center okay boom uh and in fact that's not going to work because I don't think it's Flex oh yeah I got an idea so in this case sorry we don't do that I'm going to add in a something called a chat row and I'm going to create a custom style for this right so chat row so Now command P allows us to go ahead and quickly search for file I'm going to type in Styles global. CSS you can see over here but that's command p is a very nice trick yeah you should make sure you definitely benefit from it in terms of speed now here we're going to go ahead and say chat row so we're creating a new custom uh tailn utility class now here I'm going to say we're going to round the corners rounded LG I want to say padding X of five and I'm going to keep hitting save so you can see the difference right padding y of three so it gives a little breathing room text should be small I like that Flex items Center justify Center as well that looks a bit better uh and then we're going to say Space X of two so Space X of two and we're going to say when we hover over it I want the hover state to change background to a nice gray of 700 with a slightly darker opacity right so a little bit more opaque we're going to say cursor should be a pointer so that means when I hover over it it's like that then I'm going to say the text should be gray with a value of 300 transitions right so I'm going to add a transition here now I'll show you actually what we're going to do here so firstly if you see this so that's kind of what we're going for right now um I need the overall background to be the right color so I'll change that in just a second but you can see that that's got the same kind of nice effect I want right then I'm going to say transition and you can choose different ones here right the opacity and all that I'm just going to just for the we laziness I'm going to go and say transition all um duration two and I'm going to do ease out okay now you can see that I get a nice little animation like o smooth right 200 milliseconds right and also applies to the other stuff on that bit right so it's fine now we've got that in I'm going to go to my sidebar and I want to have the sidebar um actually colored so what I'm going to do is go over to my um app layout right and where I've got my sidebar I'm going to wrap it in a div okay I'm going to W it in a div and here I'm going to go ahead and say they want a specific background color and they don't have it in the Tailwind default style so I found a nice color to match I think it's the exact one from chat GPT themselves so we're going to go ahead and pop that in and then we're going to type in on the so basically I'm going to make it a responsive style right so firstly the max width I want it to be extra small right so I only want to ever have that maximum width so firstly the colors in looks much nicer I want to have it if it ever goes past the point that you can see I want to say that the height should be maximum the screen okay so I'm just going to say the height is set to a value of the screen and if it ever overflows then I'm going to say y should be a overflow y scroll okay and then what we're going to do is on a mobile view I want to basically go ahead so you can see right here look that looks pretty cool now on a um overflow y Auto sorry auto there we go so only if it needs it okay and then I'm going to say on a so these are all apply on mobile view because Tailwind is mobile first right so what I can do is I can say when we hit a medium screen or above I want to change the minimum width to be a little bit bigger at 20 RM right and if you want to hover over you can see the values it will equate to now you can see what will happen is when it hits a medium screen I get a little bit more of a bigger minimum width and that's because I just want it to breathe a bit more I don't want it to be so so cramped up after it hits a certain point so that's pretty good so far I like like that right so that's looking pretty nice uh and that's exactly where I want it so we've got the sidebar we've got the children all good right so next thing I want to do is I actually want to go ahead and start implementing the let's go ahead and got a new chat which is great right I actually want to I want to do the authentication now you're probably wondering why do you want to handle authentication right now well firstly I need this session for a few areas right so I need the session in a different like a bunch of different areas in this project and secondly I actually need to the session to create the correct structure in the database so in fir store database so I'm going to need to have the login flow down right and then then we can actually build out the rest fairly straightforward right or it's going to be a lot easier than you think okay and by the way I forgot to mention we are creating your own custom API endpoints in today's build so we're going to create two one for getting the models and one for asking chat GPD your question and getting the appropriate response back so loads of content coming right in one video crazy I know um so at this point we're going to go ahead and install next or so rather than do this every time what I'm going to do is move this over here like so that's my new friend and we're going to type in next or bam now next or is the authentication provider we are going to use to go ahead and get started you can see there's a bunch of documentation here but I'm just going to explain and you can go ahead and copy me if you want to go ahead and do it this way right so Yan add next o let's go ahead and add that to our project right command J boom add that in now while that's going ahead and installing head over to Firebase head over to our project and I want you to go into build and at this point I want you to go into authentication okay so in this case we're going to go ahead and do authentication get started and we're going to start in test mode but I do highly recommend that you go ahead and Implement oh sorry I'm talking about the fire fire store Sil any me right we're going to click on Google authentication provider we're going to enable it and then you need to go ahead and give an email so we're going to do that click on save so this enables Google as a uh provider for our authentication okay so there's a few steps we're going to have to do this is one of them cool Next Step we're going to go ahead and click on edit configuration we're going to go down to White U I'm sorry web SDK configuration now what I'm going to do is I'm just going to hide this for a second because what you're going to see on the screen is going to be um the following now what I'm going to do just quickly is actually cut something out right so here there will be a secret key right so I've just removed it there'll be a secret key where I'm putting my cursor right you need to copy the secret key and you need to copy the client ID okay so I've removed it so everyone can't just go crazy on my machine right so what I'm going to do is I'm going to copy my key right now so I'm just popping this in right so I've got those values and then I'm going to go ahead and click on save so so right so we've got those two variables now what I'm going to do is go over to my code and I'm going to create something called an environment file so at the package Json level I'm going to create a file I'm going to call this m. local and this is where we store our environment variables okay now inside of the um GitHub repo I have got an example file here so you will find that as well but in this case I'm going to do the following I'm going to say the first one should be the Google ID okay so I'm going to get that in a second the second one is called the Google secret right now these two values are the ones I had on the screen previously okay so in this case I'm going to go back to my um provider click on edit configuration click on web SDK and what I'm going to do is I'm going to copy those two values into my code and then I'm going to close this file okay so that's exactly what I'm going to do I'm going to open this web SDK configuration copy the two values the ID and the other one and copy it here and then I'm going to save the file and close it okay so um so I'm going to hide my screen for a sec while I do this so I'm copying the client ID right now I am pasting the client ID into Google ID I am copying the client secret I'm going to Google secret and I'm pasting it in there right now I'm closing my environment file right so hopefully that made sense so now inside my environment local file I have those two values so I'm just going to go back to my authentications so you can't see it there we go okay we're golden now at this point we have to set up our API for our authentication okay so let's go ahead and do so and also one thing I do want to mention is what's really nice is you noticed that I didn't write next public Google ID next public Google um secret because they don't need to be public this is one benefit of using the new app um app directory is that we have server components so we can actually protect our variables in an easier way now in most use cases right so in a lot of cases you don't need to be writing next public because then you're exposing your keys especially don't be doing that with your secret Keys okay so at this point now I'm going to go ahead and add in two more things one is going to be something called the next or URL so just bear with me one second I'm just going to hide something on the screen right now so that way it goes ahead and makes life a little bit easier so I'll tell you what I'll do I'm just going to go ahead and save this and say secret key so that way no one can do it okay that will do a trick okay so check this out so I'm going to go ahead and do next orth oops um okay was that no I'm going to go ahead and do next or URL so at this point next or URL and then I'm going to say next or secret okay so now the next door secret really don't matter right you can change this up I'm just going to say this is a super secret authentication orth right so this one is basically our keyword for our own next orth right so so you can make this unique to whatever you want they give you a nice little terminal command that you can actually run in your terminal to generate a nice little key from it all right that's the one that you saw pop up on the screen so I'm going to go ahead and save and I'm going to close this right now so I'm going to go ahead and put my Google secret back and then close this right now okay so um my Google secret was I believe that so I'm going to pop it in and I'm going to close there we go okay so we're good on the environment variable front now if we go over to our terminal running thing you'll see that it reloads the environment file when I hit save okay so this is built in now so we don't have to shut the server down but you just want to make sure that it actually did that right so that's Gucci we're good now we're going to move over to the uh setting up the back end authentication right so in this case let's go over to next door and here this is how we basically do it so yes we're using the new app directory in XJ 13 but oh and guys bam we just beat over 600 likes that's what I'm talking about that's so cool man and with that I'm going to go ahead and put on one of the new jams on my playlist which is absolutely Banger so viby right so we're going to go ahead and implement the API authentication back in portion okay now this still uses the Pages directory so for now we are going to go ahead and um implement the page so for now any api's uh backend end points are in Pages fot still until they change it okay so just know that so heading into Pages folder we're going to go ahead into the API folder and you can see we've got a dummy endpoint here called hello right what I'm going to do is I'm going to create a new folder inside of here called orth right now inside of here I'm going to create a new file called with square brackets dot dot dot next o just like that has to be sorry with lowercase a right dots okay and then you can find this over here next or right so this is the one I'm doing right now okay then what I'm going to do is I'm going to basically take this right so in this case what I've done is I've taken this and I'll show you how to rename it into what we need okay so I'm going to I've gone ahead and I pop this in now we're not using GitHub so we're going to be changing this to like a Google provider okay and this is going to be from providers to Google we're going to change it okay and then here you can see we've got client ID client secret which needs to change right so in this case proc id. GitHub it's not the one that we want we're going to change it to go ahead and get our Google ID from our um environment variables and notice how I do exclamation Mar because I'm saying it's going to be there right I'm making sure that it's going to be there you can have a safety check before which says you know oops you need to go ahead and have your authentication but I'm just going to assume that you you did this part right so Google secret we're going to change here as well we're going to promise that it's there okay right so now we've got our Google authentication set up right so we've got our or options which we're going to need later on and then we've got the next or itself so let's go ahead and hit save right so now we've got our authentication portion down pretty nice so what we can now do is head over to our layout okay so opening up the app folder into layout all right so at this point now what I need to do is get this session provider so a session provider essentially wraps our app so if you go down here what you'll find is they actually have a session provider but the only problem is is that how do we get the session to pass into the um into the the provider that they give us because we're using next year 13 so I'll show you how we can do this okay so what I'm going to do is import session Provider from um oops oh we need to create a session provider that's right right so inside of the body okay um inside of the body I'm going to go ahead and type in session provider session provider oops provider okay and then notice how it's complaining because we don't have something called session provider which is fine right it's fine I'm going to create it so I'm going to go into my components I'm going to create a session provider. TSX okay and the session provider will look something like this well firstly it's going to be using it's going to be something called a client side component which is why we need to say use client okay now in uh the app directory or in the new next year 13 way components are also server components by default this means things like um action handlers this means things like use effects use State anything that requires a window or some local state needs to be a client object right so in this case we're going to say that the session provider is a client side component then what I'm going to do is import the following I'm going to import the session and I'm going to import session provider as and I'm going to rename it as provider here okay so we're importing a few things that we need and then I'm going to go ahead and say export function session provider and basically this is nothing different to a regular Ro functional component okay and what it's going to do is it's going to go ahead and actually have this syntax so we're going to get rid of this for now just to make it very simple and you can see it it's a provider we're passing in the provider from nextor react and we're wrapping our children okay very simple all the children means is that basically this right here would be considered the children of this now that means that we have to pass it as a prop so children comes in as a prop and then we also have the session come in as a prop and we're going to create these type definitions now okay so in typescript the way we do this is we say type the prop type of props is that we get the children which is a react node and then we have session which is of type session or no now this session right here is from next or okay so we're saying we're expecting a session from next o and we're expecting some children which is just going to be child react nodes right so in this case and then what we're doing is we're basically just injecting our children we're basically powering them up we're wrapping them with the extra functionality of the session stuff right so in this case I can close that and I can import my session Provider from our component object and as you can see it's freaking out because we are missing the session children's not freaking out because the children is coming into it okay so in this case we got session right here now how do I get the session okay how do how do I know like how do I actually get the session that I'm trying to go ahead and inject into my session provider well the way we do it is we simply go into uh we import get server session from next door now in my old video you might have seen that this was actually unstable now it's no longer unstable right don't get me wrong it still has like a bit of jankiness to it but it's pretty good right so here we're going to say concession equals await get server session you're probably wondering did he just use an await in a functional component what because we can do that in server components right but I I'll explain that in a second so we also need to pull in the OR options from our API so in this case or options was the stuff that we basically said where the providers were and all that kind of stuff okay and then the await so in this case because it's a by default Remember by default they're server components server components can definitely be a synchronous functions but if you have a client component that cannot be an asynchronous function okay so now what we're doing is we're injecting the session now what we've essentially done is we've powered up our app so everything inside of our app so any all the children have the ability to share the session State the session essentially just means once I'm logged in there will be a session present once I log out there will be no session okay so that's how we're basically doing things right all right so at this point we've got the session in so we can now Implement something like a login right so what I'm going to do here is I'm going to have a little bit of a turnery operator and what this means is I'm going to going to render out the following based on if a condition is true and we have the session right here so what I'm going to do is I'm going to say if there is no session then what I want to do is render out something else I want to render out this okay so I'm going to say if there is a session then this should happen otherwise I want to render out something called the login component okay and we don't have a login component so let's go ahead and create this right now login. TSX RFC yes it worked and then go go ahead and pop this in like so and if I show this on the screen when I hit save what we should see once I go back to my layout and hit import save what we should see is I get a login okay now if I refresh you'll see I'm getting a login screen now boom this is good because we don't have a session right so if we don't have a session you should be seeing the login Comm on otherwise you should be seeing this and yes there are so many ways you can write this you can have a return statement up here you can have loads of different things going on right so this point this is actually what I code to by the way right so um we're going to create a login component so heading over to login. TSX now that we've done all the prep work it's actually a lot easier than you might think okay so this is going to be a client component now the rule of thumb is you want to try and basically keep your components to be uh server components and only clien tize so only make the components that you want client side to um to be smaller components right that way you kind of keep the server component benefits right without kind of losing everything right can we get the playlist please yes it's in the description just simply sign up to newsletter it get sent out to you right so at this point we're going to go ahead and import the following so I need to import the signin function and the image component from next image and then we're going to go ahead and have the following now bear in mind in the layout right what we were having previously was the um head body okay it's cool that's fine what I just realized something that I made a mistake on my old one I'm actually going to change that now so I don't mess this up one second guys with me okay that's bad pet peeve don't worry you never knew anything just happened right so at this point I've got an image component and this image is going to be for the chat GPT logo so I've actually saved you a bunch of time I've made my own little link to a neat little logo so before I hit save I'm going to add a button and that button will say sign in to use chat GPT and hit save now what we're going to see is we're going to get an error and this is because whenever we use the image component what we're essentially doing is we need to go ahead and image component handles a lot of optimizations it basically condenses the image it delivers it in a certain way it makes it more efficient a lot of this kind of stuff happens right and what we may need to make sure we do is whitelist only the domains that we trust so if we go into our next config so next config and here what I'm going to do is I'm going to type in images domains and we pass in an array of characters here and you see the host name is the one that we need to go ahead and copy so I'm going to copy that into it right now hit save and then do a comma and then we're going to close it and because I done a big change in my nextjs config you have to restart your server okay so let's go ahead and contrl + C to cut this out Yan runev boom and uh if you're enjoying this honestly just see what it's like inside zero so this is the vibe we have all the time in the coaching calls weekly coaching calls links in the description if you want to check it out so let's hit refresh and just like this wait for it there we go sign into to use chat GPT and boom we have a logo all right so that's good now I want to basically style this out so I'm going to say the background color and I've already got the nice little color of chat GPT to save us a little bit of time so let's go ahead and pop this in right now so popping that in like so so I'm going to get rid of our little bracket situation put that in I'm say it should be the height of the screen I want it to be a flex box right I want to be flexed in the column Direction I want it to be the items should be centrally aligned so it should be centrally aligned and I'm going to justify in the center so I'm centering on the X and the y axis okay and I want the text to be Center as well hit save and boom we get a nice Central axis right so this is looking good oh this song's sick right so at this point this is looking pretty good and now for this button I'm going to go ahead and style it out so this is going to be a text white font should be B text should be 3XL and I'm going to make it animate posts so this will give a nice little animation to it so boom sign in to use chat GPT is clickable as well right but we just don't do anything on the click now you see we pull in this signin method from next or now the the good thing about next off is once you get over all of that headache of the setting things up and you know the messy stuff that we just dealt with the actual implementation of signing in is actually fairly straightforward so all we need to do now is call this function so onclick we do an arrow function and we just say sign in right and then here what I can do is if I do this this will take me to a provider screen where you'll have all the different options of providers but I only have one provider here so I'm going to pass in a string and this you see we get all all complete for all the different ones I want to pass in Google so it's going to try and straight away log me into Google Okay so let's go ahead and give this a try so I'm going to go ahead and click on sign into use chat GPT and we get redirected to Google now this is what we want to see says this account is blocked the app's request is invalid and we get redirect URI mismatch now this is because over on Google side Google's like whoa whoa whoa who the hell are you we don't trust you you ain't logging into this app so we have to go into the Google Cloud platform and basically say this is safe to go ahead and do it and we also have to repeat this step when we deploy and make sure that that domain that we end up buying from hostinger or the one that we get from Vel is also whitelisted in the process right so what we need to do is go over to console we need to go to Google Cloud Google Cloud right and I'm going to go into so all you want to do is type in Google cloud and what I'm going to do is just hide the screen for a second cuz I have a few things that are going to pop up so go to console. cloud.google.com and then what you should see is The Following on the screen okay you should see this Google do uh console console. cloud.google.com right and then I'm going to change my account to Pap react so give me one second I'm just going to wait until that loads cool and now what I'm going to do is I have a few different projects here so I'm going to go into chat gbt clone and I'm going to go to the most recent one so chat GPT and this is the most recent one so so it's chat GPT messenger YouTube so I'm going to click on that and now you can see it goes and takes me to that now all I need to do is go into navigation menu go into apis and services and go into credentials okay then we need to basically go ahead and configure our o or 2 endpoint so o or two client IDs click on this and once sure at this point we now need to go ahead and whitelist so essentially we have the local Hoster 5000 here we need to Whit list Local Host 3,000 that's the first thing the second thing is this URL right here right so in this case we need a special coolback URL and then what the one thing I didn't see there was basically usually it gives us our nice coolback URL um in this case um I can get rid of that one second where is my nice little demo gun is it here where's my code so firstly I'm in 3,000 here so 3,000 well I'm in 3,001 so if I try and loog in so view developer see error details here we are right so you need to click on error details and you see request details redirect URI so you want to copy this redirect URI because this is the one that is trying to use and we have to essentially go to add URI and we're saying this is okay we trust it okay and hit save now what we've done is we've told Google it's safe right we've said it's safe to go ahead and do this um okay so at this point now what we do is we go back to our app we simply head over to local 3000 and we try again so English music 2022 says sunny what's up dude okay so then I'm going to click on sign in to use chat GPT and boom we have a permission to use it okay so I'm going to go ahead and hit my name right here so I'm logging in and then this is perfect this is what we want to see so now we have Google authentication and now I have a session which means I get through the past the layout screen right so at this point heading over to layout. TSX you can now see I have a session so it bypass login and now we get this and if I refresh you can see we don't get a little stutter it straight away goes to this screen which is banging perfect because it's doing it on the server it knows on the server side if this person from their request was authenticated or not okay amazing stuff so now that we have the session we can actually go ahead and log this out and I'll show you what we actually get so if we console.log the session here you you can now see that we get the users information here right so I get the users details their name their email and their profile picture so we can go ahead and use that information throughout our build and that's provided by the session provider throughout the children components right so amazing stuff okay so next up we have the sidebar so sidebar what I want to do is firstly I'm going to have a nice little little picture of me at the bottom let's just let's just start simple right so what I can do is I can get the s session object we don't have to prop through we don't have to pass things through we can instead use the use session variable so at this point I can go ahead and say const and then I can say equals use session now what I do is I import the the use session hook and we need to make our sidebar client side because I'm using hooks now okay so use client so this means that we've now converted our sidebar to be a client side component and um you can go ahead and refactor as much as you want but yeah and at this point I'm going to D structure here control space bar tells me that there's data and Status here we're going to rename the data to be the session variable okay so that has the same information I showed you previously and now what we can do is at the bottom of the screen so at the bottom of underneath this div I can now say okay if you have a session then I'm going to go ahead and I'm just putting safe measures in here like if there is a session because it can be Corner cases where you know it might not be logged in or you might catch it and you don't need to bug out so I'm just put a little bit of a precaution they're saying if there's a session we're going to say show me the users image right and we're going to force that the images there otherwise you could go ahead and have a a fullback image there right if you wanted to but I'm just going to force it the images there so hit save and now you can see we get a nice image now you're probably wondering Sunny why is that not an image component that you're using because sometimes the image that we get back from the URL could might not be in the format we it might not be from a trusted URL right it might be from a different Google UR URL in which case next chest is going to freak out and be like no you haven't whitelisted that so in this case I'm just using this for now okay but um here you can give it a profile picture and so forth okay so then we're going to style this out so here I'm going to say that it has a class name and then we're going to say height and width of 12 we going to say oops height and width of 12 rounded four cursor should be a pointer and then we're going to say margin X Auto to center it margin bottom of Two And when I I hover over it I want the opacity to go to a nice little 50% Gap right so 50% gives a nice little effect right so now you see when I hover over it look at that ooh nice and we're going to use that as a log out button okay so making that logout button is so easy all we have to do is simply go ahead import the sign out function from Nex stce react go into our image component say onclick of this button we're just going to implement the sign out and then we need to do a little arrow here to get around Ty script sign out and just like this guys let's go ahead and try out our authentication so I'm going to sign out and just like that I am signed out I go ahead and sign in I now am initializing a session object through Google authentication and buam we just get the nice forward screen right so this is exactly what we wanted amazing stuff we have our authentication now we can proceed to Firebase because now we have all the items that we need to go ahead and actually populate the database we have the user we have we have the uh input fi will set up in a sec but we're going to go ahead and do all of this right now but the first thing I want to do is have the ability so that way when I click a new chat it creates a new chat Row for me and then it will take me to that chat so SL chat SL you know the chat ID so we're going to go over to the sidebar let's go over to my sidebar let's just make this a little bit more neater let's head over to the sidebar right now and then what we're going to do is we are going to set up The Collection so okay so now we need to make a connection to Firebase so we need to go to our Firebase so we're going to close this we're going to go to Firebase where my fire here we are Firebase yeah and then we're going to go to build and now we're going to prepare our fire store database and this is going to be our real time database which is going to store all of our chats and this is not just a normal UI for chat GPT it's actually going to store chats and when you switch users it literally shows you the chats that that user user has so it's literally really like the actual chat GPT uh platform so we're going to click on create database we are going to start in test mode however I highly recommend afterwards you change to production mode and add in security rules so click in start and we're going to click on enable we don't care about location for now say it to wherever you are near you it might help you out cool and now we are going to we're going to enable cool now this is our collection so this is a nosql style database right so so previously we had I don't know if it's there okay so it's that's fine I'll show you anyway so we're going to have a users collection the users email address which is unique then we're going to have the messages collection then we're going to have the chat sorry collection and then we're going to have the messages inside of it okay so it's going to be that kind of structure and that's going to allow us to go ahead and have the outcome that we need Okay so let's go ahead and firstly I don't need this taken up room so we can get rid of that right now cool okay so I need to create a connection from my app to my Firebase how the hell do we do that well first things first is we're going to create something called a Firebase TS file so we're going to go to my package J and create a Firebase TTS file there we go right Firebase and now what I need to do is I need to install Firebase right so you can do this in a bunch of easy ways but the quickest way I want to show you is Firebase yeah oh sorry um Firebase I was just want to show you the actual documentation so v9 you just type in yarn add Firebase but I want to show you the actual documentation itself um because you should just you should see that right so in this case upgrade guide you can do it here mpm install okay it's fine I'm just going to show you that my way but yeah you can go to the homepage and then get started and basically read through the docs but here it's a very good place to get started right so you should check that out but I'm going to just show you how to do it anyway so here we go into our console Yan add Firebase like so that's going to install Firebase Version 9 so Firebase has been installed and now what I need to do is basically import the dependencies that I need okay so I'm going to import the things that I need so in this case boom we're going to pop this in um and then you can see here we've got get app get apps initialize app and get fir store okay so I'm going to have the Firebase config set up so the way we get this is we go to our Cog project settings we go down here to this right and then we type in um chat GPT messenger YouTube don't matter too much we don't need Firebase hosting cuz we're deploying on Vel and then we can go ahead and we've already done our instore tag and this is what we need next right so this is public information it's fine right so in this case I can pop this in we've got our initialized app core we can get rid of those I've already done it for us okay so that's our configuration object now this is fine in a react app okay because you're you're not going to have several instances that it could be occurring but what we need to do is do it in a next CH approach because there could be the possibility that we already have an app initialized right so in this case we say const app equals get apps and this will tell us all the initialized apps right so an a readon the array of all initialized apps and all we're going to say if the length is present right so this basically says if it's truthy so oops okay dot length okay then we're going to say if it has a um you know if it's already initialized then we're going to get the current APP that's initialized okay else I'm going to initialize a new app right so else initialize a new app and this is going to be a passing in the Firebase conf and this is called a Singleton pattern in coding okay so this is known as a Singleton pattern in coding okay so it means that we only want a single instance now from that we're going to go ahead and get our database object okay so we're going to go ahead and use the get fir store this is a modular Version 9 approach and then we're going to export the database object cuz we don't care about the actual app right now we don't really must like worry about that it's just going to be DB right so in this case that stands for our database hit save and now we're going to go ahead and close that so our Firebase config is now done okay so now what I want to do is in the sidebar where we have new chat right so remember in sidebar we had the new chat button so what I'm going to show you is the really nice part about this it's very very like kind of decoupled right which is what a good programming practices should be like it's decou it's a lot cleaner and working that way okay so what we're now going to do is we're going to have um this new chat has should have the functionality to go ahead and add a document right so it needs to add a chat create a chat if anything okay so at this point we're going to go ahead and create a function called create new chat so con create new chat and this is going to be an asynchronous function so it's going to be an asynchronous function it's going to be an arrow function and then what we're going to do is if you click on this div so on click of the div we're going to go ahead and say it should create a new chat okay so passing the signature in at this point what I'm going to do is I'm going to create a basically I'm going to go ahead and create a new chat right so the way I do this is I simply go ahead and I firstly need the users information before we can do that so I'm going to pull the users information from the session so previously we described this over here we import it we rename the data variable with the colon syntax to session right so that's what that does if you're wondering okay and then we also need the router because we're going to need to direct them to a new screen afterwards now when you're using nextjs 12 please please be careful that when you go ahead and use like router and all that kind of stuff you don't make this mistake you see how it imported from next router no no no you want to import from next navigation okay and this is also going to be a client component okay so when we're using the next just 13 like sort of stuff we don't want to do next R we use next navigation so it's very easy mistake you can make but it will screw you up and you'll be there for ages trying to figure out what's going on okay so at this point we're going to say const and basically what I'm going to do here is I'm going to push something into the fir store database right so I'm going to push something into our fir store database so click on continue to console fir store database I'm literally going to from our application when I click it I am pushing a value here right and I'll show you what value we're doing so and then the response will be the document that I've actually pushed in so we're going to say equals a wait right now the way that you do this is this modular approach so it's going to be add Doc and notice how I'm going to be importing things okay and then what I do is I simp I basically have to specify the collection so the way you do this is I say it's a collection and then what that does is it takes in firstly the database so see how it takes in fire store as a first argument so that's going to be the database and I'm going to import that from our Firebase locally right so that's my config then we pass in the path so this is going to take the approach of it's going to be essentially um the path document so it's going to be collection document collection document which is a nosql style structure okay so here we're going to say users then we're going to say session do user. email right and I'm going to basically say that it's always there which is hence the um exclamation mark and then I'm going to basically pop in a new chat okay and then I'm going to close it off now we've made a mistake somewhere where have I made a mistake it's uh argument for data was not provided um collection ad do um yes and then we need to go go ahead and oh yeah and then we need to pass in the data object itself so the first argument is basically the path right and then the second argument after all of that is going to be the data itself okay so that's going to be outside of this right here so the data itself right so notice how it's after so there two arguments right the first argument first argument and then the second argument is the data so the first argument is that collection route and the second is going to be the basically what I want to push into that document so in this case I'm going to say it's going to have a messages array which is going to be a basically like a an array of messages right so there's going to be a collection in there we're going to say the user ID will be stored and this user ID will be the session user email okay and then we're also going to po pop in a created app so a timestamp because you should be passing in timestamps when you're doing this now you don't want to use your local timestamp now the reason why you don't want to use your local timestamp is that I'm in Dubai right now and you could be anywhere in the world we have worldwide viewers here now if you use your Tim stamp your message will technically be ahead of me or before me which it's going to mess everything up right so how do they figure this out so all you need to do is use the server's timestamp that way no matter who is doing it we all get the same timestamp okay we get the service timestamp so in this point what we do is we go ahead and we import our server timestamp function we pop it in and we invoke it and this will give us a server Tim stamp simple as okay so then what we want to do is redirect the user to the chat screen so what I want to do is this will give me back the document ID I'm going to do some string interpolation so sorry um rout to. push I'm going to do some string interpolation here to say SL chat SL doid okay so in this case SL chat for/ do ID we don't have that page yet but that's what I want to do so when I click on new chat it should create a new chat and then take me to that new chat okay so let's go ahead and hit save and what I want to do here is I'm going to set this up in a demo way okay so what we should see now is I've got my database on the left and on my right hand side I've got the new chat so I'm going to click on new chat and I've clicked it now because we haven't got anything here it's not going to show just yet right so you can see it actually took me to the new chat screen with a valid document ID so you can see it actually took me to/ chat a doent ID so in this case if I go ahead and refresh okay so at this point now um we are going to go ahead and um you can see here we've got users we've got my email and then we've got chat right so chats and inside of there we've got the messages itself right so this is going to be the actual so all I want to show you here is this is the layout right so we got users my name and then we've got the list of chats these are going to be all the different chats I will be having with chat GPT and they'll be listed out here that's the document ID so we got got directed to and then you can see inside of here we've got created at messages and user ID okay in fact we don't actually end up using messages so we can actually get rid of that what we care about is the user ID and created at okay so um yeah so I don't think we actually care about this one we actually use a collection instead for that one okay so let's go ahead and get rid of that cool so at this point that's looking pretty clean so we don't actually need that so we actually won't have that in the outcome so you can get rid of that okay so now what we need to do is create this page okay so what I'm going to do is just test it out one more time and go back to here and then what you should see is if I click on it create new chat we should see another one in a second pop up oh there we go right so it created the chat it redirected me to the chat awesome right so now we need to go ahead and actually build out this Dynamic page so the rout for that page is SL chat SL random ID so that is known as Dynamic Roots right so I need to go ahead and create a dynamic root so I'm going to go into my app folder and using the new nextjs 13 folder structure the way we do it is we essentially draft out the rout in the folders so here I say the next route will be for SL chat and then inside of there it's going to be a random ID right so in this case we're going to have a wild card and I'm just going to give it the chat ID so in this case it's going to be ID and inside of the ID folder we're going to have page. TSX because remember page head layout they're all reserved keywords okay so here now what I do is I say RFC and this is going to be for the p uh chat page okay so in this case I'm just going to rename this to chat page get rid of this and then now we have our chat page so if I was to click on new chat now what you should see is we should get redirected to the chat page which is awesome it worked and if you're wondering whoa how did we keep the layout right that's pretty cool how did that stay around well that's because remember we have the new layout component which is is actually responsible for staying in the overall structure or layout of your website okay and I actually show you loads of little tricks in this in the next year's tutorial on the channel okay so at this point now that's going to be pretty cool to do so in this case we've got our layout already there and you can see now we've got this nice kind of you know we all we care about is the the view of this chat page right so it keeps everything very relatively clean right now before we do this I'm going to address two things the first one is we need to show the chats here the second one we need to build out the chat page and then eventually what we're going to do is have the open API AI integration part so that we can talk with chat GPT all right so it's going to be a lot of fun so at this point we've got that looking pretty good so I'm just going to put that text back so we know it's on the chat page okay and um what I'm going to now do is head over to my sidebar so components sidebar okay and then I'm going to expand this out so first things first is in the sidebar we are going to go ahead and actually connect to the uh Firebase database so I need a real time connection to my Firebase database so I'm going to go ahead and make a realtime connection to this database that you see right here okay give me one second I'm just rearranging my screens I've got everything everywhere right now there we go cool so I need a real time connection here okay so how do we do this in a nice fashion well easy way of doing this is we can go ahead and use something called react Firebase hooks okay lovely little Library and it is actually a really kind of clean way of actually connecting to our Firebase database and they've already done the hard work of creating all these reusable hooks for us okay and it works with Firebase Version 9 so we're going to install it react y add react Firebase hooks so go into your terminal y add react Firebase hooks that will install it into our project and now we can go down and you can see Cloud fir store hooks so inside of here they teach you how to go ahead and connect to the uh backend and you can get a real time list now by using syntax like this right so I'm going to now show you so firstly I showed you that because I want to show you where it comes from now I'll show you how to implement it right so first you get these three array destructured values value loading and error so what I'm going to do is I'm going to go ahead and say const I'm going to call it chats instead of value loading an error I don't actually use the error here but you can actually use it if you want to use it I'm going say use collection okay and then what I'm going to do is import this from react Firebase hooks right so in this case it's not Auto completing so I'm going to show you it off top of my head there we go boom and then inside of here we have to pass in the actual directory that we're going for now it's dependent on the session because I am going to be using the email to find that collection so I need to go ahead and say firstly the session has to exist that's the main thing then secondly we're going to do connect to a Firebase uh collection we're going to go ahead and import our database from our local Firebase file and then we basically spell out the rout okay so now I'm trying to get the chat so what I'm going to do is I'm going to go to users I'm going to go to the session. user. email with exclamation mark to go ahead and say that the email will be there then I'm going to grab the chats okay so now what I'm doing is I'm essentially pointing towards this right here so I'm I'm pointing right towards so you see we've gone through the users gone through the email I'm pointing now at the chats okay so this is what I'm getting back now so I want to get this list right here and I want a real time listener to that okay so this right here gives us that okay so now we have this amazingly powerful chats right here okay so if I was to log out chats you will now see and this is a client side um uh component so I can actually check the client logs and I should see three items in my log right so in this case you can see right here if I was to go ahead and log this up we get undefined and then we get the actual example or the data back right so this is exactly what we wanted um in this case you can't see it but you see in docs we've got three docs right so in this case we see doc changes it's actually got three docks in there okay so I'll show you how we can access this properly okay so now we need to map through so where I've got maap through the chat rows we're going to say chats and it could be undefined which is why I'm going to protect it I'm going to say docs map through every single chat and return the following right return the following and then this is where I need to make something called a chat row and whenever you map through you should always pass a key which is in like a unique key so we're going to give the chat ID that value and then I'm going to pass in the ID of the chat here as well so chat. ID okay so this is going to be the information that I passed through so we need to create a chat row and this chat row will symbolize this right here so I'm going to log into my old example right now so I'm just logging into my old uh testing example so I can show you uh the reason why it's not working is because I haven't got it wh listed on Local Host 3001 I believe um that's why it might not work okay no it is working that's fine um so in this case you see when I have a new chat all right so in this case oh I've gone back to 3,000 oh okay I see what's happening here that's fine so in this case if I do I don't know I'm I going to be Lo okay so it's not going to show me that's fine I'll show you how we do it so I'm going to have the new chats here right so the chat row is going to be these little chats boxes that are going to pop up here so we're going to implement that right now so chat row. TSX all right so let's go ahead and we've got the chat row here so I've got the I'm going to go ahead and pop in so right now you can see if I pop open the sidebar you can see the key is basically to make sure that react efficiently optimizes the list the next prop that I care about is the ID okay so in this case I'm going to go ahead and uh pop in the ID uh over here so in this case I've got the new chat and the props come through here so I'm going to say ID and this takes in props like so okay and then I'm going to Define what my props will be in this case is very simple okay so in this point we've got the ID and the ID I expect to get through is a string now type script is really important because it allows us to prevent the number of bugs and problems that cause that are causing our app so I recommend it's worth learning it it's going to allow you to become more valuable as a developer and then that's what we're going to do okay so um ID there we go boom and now once we've got this in we're now going to go ahead and get the chats render on the screen so actually one minute guys I've completely screwed up it's not this one it's not this one my brain was everywhere it's going to be inside of the chat row so did I create the chat row chat row chat row yeah there we are chat row this one my bad so ID and then this is going to be props okay so type props ID string okay um cool and then in this case we're now going to go ahead and create the chat row so I need a bunch of different things here to be honest with you I actually need sort of um I need to determine if the chat is active I need to determine uh the actual uh layout the design of it and all that kind of stuff but we're going to do it right now so firstly these are going to be next link components which going to allow us to iterate through the different URLs easier so it's going to be hre and this will take us to for/ chat ID okay inside of here we're going to have a chat bubble so chat bubble left icon so left icon and this one is going to be for um this going to be outline okay so left icon outline cool and in this case I'm going to go ahead and do class name height and width of five height and width of five so hit save so we've got that you I don't know if you're going to see it yet because in the sidebar if I import it like so we might be able to start seeing it being popped out now so in the sidebar let's let's log in now as I logged in and I messed it up a little bit okay so we got the chat bubble left and then we should see oh yeah there we go look chats hey there we go nice and then uh I'm got a P tag and then the P tag okay so I'm going to do something pretty cool here I'm going to have a trash icon afterwards which is going to be for if you want to basically delete it right so that's going to be the outline variant and I want to have the class name of this to be this is going to be a he height and width of five um text should be gray text should be gray of 700 and the hover State when you hover over I want it to become a red bin because it's going to be the delete button oh that's what I needed to kind of get the energy up right so now if I hover over this um there button you see that nice right cool now um for the P tag here I'm going to go ahead and say the following so we need to firstly get that um that message right so I'm not going to include this right here because what we need to do is we're going to pull information from the chat afterwards right so in this case this right now would just say new chat okay so we've got new chat for now and eventually it will say the text in which your last text that you had with chat GPT the last message it will say that eventually okay so in this case chat ID so now what we're going to do is style out the outline so this overall link okay so class name I'm going to go ahead and say it should be firstly we're going to do string interpolation because I'm going to use the active state which we haven't defined yet but I I'll show you afterwards so firstly this is going to be of type chat row so notice how chat row automatically kicked in really nicely then we're going to say justify Center okay so now you can see like chat row looking pretty good okay and then for the P tag this one is going to take in Flex one so Flex one it's going to be hidden on the mobile view on the medium screen and above it's going to show and then I'm going to truncate if um oops truncate if not okay so now you can see on the medium screens it will show new chat uh truncate oh nice there we go Bastian I appreciate you dude there we go so new chat and the trunk it will basically mean it'll do dot dot dot if it gets too big all right so this is sick so now we've got the chats over here cool and then we've got a new chat so see if I add a new chat it pops in this is looking good okay so I'm now going to go ahead head and set up everything that I need so we're going to need a few different things inside of here firstly right we're going to need the path name because I want to basically have it so if I'm in this chat I want this to be highlighted if I'm in this chat I want this to be highlighted and so forth right so in this case I'm going to say const path name equals use path name from next navigation right not next router next PATH there we go and then I'm going to say const routa so equals use routa and we're going to P pull this and you see this this do not make this mistake right next navigation is the one you want for next 13 we need the session so I'm going to go ahead and pull this in so session equals data session use session boom like so and then we need um an active State okay so this one I'm going to end up making a use effect if you don't know what a use effect is please check out my use effect tutorial it's got over 100,000 views now because people are finding it so useful so check that out come back if you're confused and then carry on okay so this is going to be a piece of State and again State as well I've done a tutorial on that as well okay so first things first if I if the chat that I'm in is active so I also need the messages so we well this just do it now right so I need the messages which is going to be a call to use collection so I'm going say const messages and remember you get the loading and error and so forth but in this case I don't care about the loading and error I just care about that we're going to have the used collection from here and then I'm going to go ahead and say uh it's going to be a query now because basically I want to do what I did before so I have a collection but I need to order it by the created ad date so that way it's always in the sequential uh time and date order right so in this case what I do is I pull in the query from fir store and then we basically make a like a a combined query right so in this case the first one is going to be the collection itself so this is going to be the collection from fir store is going to in include the um the DAT the yeah database there we go and then it's going to be the path so in this Cas users it's going to be session oops sorry session do user do email and then it's going to be making sure that it says uh that it's always there so then that's why we got the exclamation mark then it's going to be chats slash the chat ID which we have inside of here because of the oops sorry what be not because of the ID we get it passed through here yeah and then we're going to go into the messages themselves okay so that's a messages collection within okay so that's that bit then what I want to do is comma over here so if you see here this is a commas it's like the second argument of the query right we're going to say order buy from firestore and this one is going to be the created app field which is one basically the time stamp and we're going to do ascending okay so what this will do now is it makes like an aggregate query so basically it queries the collection for here gives me a real time list now but it orders it before it returns it so this way the messages are always going to be in time order ascending okay so now if I hit save what we can nicely see now is uh those messages will be and the reason why I need that message by the way we don't actually need to order it here to be fair I don't think yeah we don't actually need it here um I need the exclamation mark because otherwise it will say you know that the session user email might not be there right but in this case we logged in with a Gmail account which means we always have an email so I'm going to say that it's always there right so we've got the yes the messages just so the reason why I did that right there was because I actually so in this case I didn't actually need to order it I don't think that's fine uh it's fine yeah okay it's okay cool um so in this case we can go to the actual message so I want to basically get the so this is deleting no no sorry I need the text so I need the actual text of of the thing I'm calling so in this case messages docs right then what I'm going to do is I'm going to get the length so messages do docs and this is could be undefined length minus one and then I going say data text right and I'll explain this or it'll say new chat so basically what this is doing is I want it to basically is pull the last bit of text from that chat okay so pull the last bit of text from that that chat itself or just say new chat okay so in this case it hasn't got any messages there so it has nothing to say but that's essentially what we just did okay so now also notice how if I click into these it changes the URL to that link so every time I click on it it changes the URL right so the next step is to have a use effect which determines if we are active or not so in this case um I'm going to say use effect and then we've got our Syntax for use effect with our dependency aray and then I'm going to say if there is no path name I'm going to return from this function because we're going to protective we're defensively programming otherwise I'm going to set active and I'm going to basically say if the path name includes the ID okay so very simple check okay and then basically as we have a variable inside of here we have to include it in the dependenc AR okay so path name here now what we can see is that the active will now get set based on this fa this matter so in what we can do here is I can actually go ahead and apply a conditional styling by saying the following I can go ahead and say um active and that means only if it's active should you change the background to a slightly different shade of gray so that way I know that that's the one okay there we go guys look at that active so if I click this one now bam that's active if I click this one now bam that's active if I click this one now bam and then what if I click a new chat notice how it creates a new chat and then it makes that the active one so so good right so so good in fact what I didn't do correctly in uh which I made the mistake on is I should maybe order these in the um the other one so in this case the query call that I've got here maybe we should be applying it over here which I think would be a nicer version to do okay so what I'm going to do is I'm going to pop this open on the side and I'll show you what I'm doing is I'm simply just moving this right so I don't need the query here I need the query over here so I'm going to say query I'm going to wrap my collection like so and then I'm also going to pass in the order by created there we go created at ascending and now I'm going to pass in the query I'm going to pass in order bu hit save oops my pret is dying here there we go and now this one will basically query and this one I actually didn't need to query it I just realized I didn't actually need to do that so that's B okay so now what I just did guys was I basically said that on the sidebar the most recent one should come at the top or bottom I can't remember but basically if I click new chat there we go so the new chat now will come to the bottom so you see that if I click new chat boom there we go and it automatically selects it because that is now being highlighted based on if the route matches so you might actually find that massively useful because a lot of you always ask me how do I now go ahead and do that why not use use path name instead of use effect um use I think you can actually that use path name I did use use path name over here guys so if you look inside of chat row I use use path name to get the path name and then we have a use effect to determine if the path name that I got from use path name was the one I wanted or not or is it the active one currently in state right so the next thing I want to do is the ability to delete a chat okay so I'm going to create a function called const remove chat I'm going to remove chat this is going to be an asynchronous function right and then here we're going to say await and this is going to be a delete doc call right now think about what's happening right because I'm going to call this method and we have a realtime listener rendering out things in the sidebar sorry but real time list not rendering this out so as I delete documents they're going to get real time affected in the backr in and it's going to go and show this right so it's going to have a lot of stuff going on so I'm going to open up the doc right now and I'm going to pull in the database which I believe I have already yep I've done it and then I'm going to say we're going to go into the users we're going to go into the session. user. email with then make sure it's there then we're going to go into the chats then we're going to go into the ID and then we're going to go ahead and basically yeah so we're just deleting that document so basically deleting that chat right there because look it's a chat with the ID of something right that's essentially what we've done and then what I'm going to do is I'm going to push the user from that screen well we can actually replace the user URL because they shouldn't be able to technically go back to a screen that's deleted right so in this case now remove chat is assigned here and then what I want to do is hook up the trash icon to this button so now when you click that it'll remove that chat and because we have a real time listener connected in well this should work flawlessly so if I go ahead and do this boom pow boom boom boom we can add new chats delete them add new chats and if I wait a second it will redirect me to that chat oh just so beautiful look at that if I delete that one it will change to the home screen just amazing if I delete that one it will change to the home screen look at that guys I can add like five chats at a time delete as many as I want and it just does it and in Firebase in the back end this is all happening so if I go into over here now you'll see that there's there's Madness over here right look so look at this chats right here p p po delete delete delete delete delete oh it's just it's just beautiful look three chats bum B bam oh it's just so nice all right so really nice really really nice okay now we have the chat functionality we have the ability to create and delete chats so now we're going to go ahead and no flashing UI while deleting I know it's beautiful it's just Masterpiece right so this point we're going to go over here all right so now inside the chat so over here now this is where the it gets really interesting right so this is where we're going to essentially go into chat GPT stuff okay so get ready for this so at this point we have um firstly we need to go to the page itself and inside of here we're going to have two main elements okay so the first one is going to be the chat window right so the actual chat the second one is going to be the chat input and these are going to be decoupled elements right this is why I'm creating two separate elements so here we're going to say this this one's going to be a flex box Flex column height of screen and then we're going to say overflow hidden right so cu the reason why I want to have overflow hidden is because I want to have it scrollable right so once I'm in this chat screen I actually want to have it like a scrollable I don't want it to ever the whole page scroll down I want it to be a set high and then I want to have the inside chat only that to be scrollable okay so now what we need to do is create a chat component so chat. TSX do RFC get rid of this this is going to be my chat screen so now if I go to my ID screen so my ID screen right here and I go ahead and I get rid of this so I can say chat now I popped in my chat component and then here you can see over here I can go and say look chat boom so that's the chat component awesome stuff right and then right alongside that if I go back into the chat I can go ahead and create the chat input as well while we're here right so let's go ahead and just do two B one St let's go ahead and create a chat input inside my components folder so chat input. TSX RFC boom go up here delete and now over inside the page. TSX so over here I'm going to go ahead and import this like so okay now we've got the chat and the chat input so we're going to change this into what we want n Buon whoa what's up dude he has Sweden in the house so SW say sick man okay so at this point now we've got the chat page okay now now the chat page itself I do need something from this um I'm just determining what I need so at this point um from this page okay so I can get this ID because this is a page route okay so this right here is a page route okay which means that page Roots automatically so anything at the top level not a component a page rout anything at the top level gets some props and when you have a dynamic value like this rather than doing Ed path name and cutting it up and like that you don't have to do that right instead you just go ahead and do if you got props like so you can console log your props and look what we get inside and notice how this is a server component hence why it's going to be listed out in my server logs so in this case you can see pams so you see how the ID is in there so what I'm going to do is I'm going to extract this but I'm going to do it in a safe way with typescript so I'm going to say I'm going to enforce the props props right and then I'm going to say prams are inside I didn't care about the other ones all I care about is a string there we go and then I'm going to enforce it so I'm going to say this is prams I'm doing some inner destructuring work here so destructure it and props there we go right and uh Sunny what have you done oops my bad props there we go cool now inside of here I'm going to pass these in so I'm going to pass the ID down here and I'm going to pass the ID down here so only one layer of drilling in a right props someone's someone inside is like why are you doing this why are you passing ID in it's okay right it's fine and here I'm going to rename this as well to chat ID so let's rename this to chat ID boom and then in my chat and chat input I'm going to update these accordingly so let's go ahead and import this right now so firstly I'm going to have a types uh my prop type definitions like so then I've got my chat ID with the props Okay so we've got this updated and then we've got my my chat I see how it stop complaining I'm going do the same thing for this so we've got the same um props being passed in here so chat ID props and then we're going to say type props chat ID string okay so now we've got this looking pretty pretty nice so now we've got our props being entered in so the first thing is let's do either the chat or the chat input it really don't make a difference uh chat let's do first okay so actually let's do the chat input first because then I can actually enter messages in and then we can display the messages right so let's do that makes more logical sense so the chat input is actually the bottom one so I'm clicking into that Comm on click and then we've got the chat input so let's get the magic done here guys right so first things first let's get the UI in so we've got a form right the reason I've got a form is because I want to have this like type in hit enter functionality right so here I'm the input it's going to be typed text um and then I'm going to have mapping it to the state now there's many ways you can map your text and get it out of an input field okay I know this you can do it with the ref you can do it with state I'm going to do it with state today but you can do it wherever way you want ref State wherever I'm doing State because I want to disable it um if there's no session but yeah you can do it wherever way you want it really don't it's just several ways you can use react tox form yeah there's so many ways you can do this right so here I'm going to say type your message here this is when I got my Tesla in my Vlog this this is that soundtrack right last name 5 space X5 Flex one nice and now you can see we've got a little input form forming up at the top we're going to have a submit button and this one is going to have a paper airplane icon okay so inside of this button it's just going to be a paper airplane icon and that's going to be a solid I believe yep solid so in this case we've got a paper airplane icon there we go somewhere there so we're going to make that look really nice don't worry and then after that we're going to have a outside of my form we're going to have oh God that's horrible outside the form we're going to have a div and in here eventually we'll have modal selection as model selection right so basically eventually I'm going to have a drop down here which allows me to select the model or I'm going to have a drop down at the bottom which selects me if I'm in mobile view it's going to show up right so I'll show you how that works afterwards but I'm just writing a little reference here so that way we don't forget to do it okay so the button here should be type submit because that's what going to autom automatically submit the form when we have when we do that okay and then now what we need to do is basically have a piece of State hooked up to our form so quickest way to do this is you have a value you hook this up to a piece of state so in this case I'm going to call our piece of State prompt okay I'm going to create my piece of state now so we say prompt um set prompt and it's going to be a string value so in this case we don't need to cast it I'm going to give it a blank string to begin with that's fine and I'm unchange this means as I type in an event is going to get fired off all I'm simply doing is updating the text here to be set prompt oops what is that um set prompt to be e. targeted value so as the user types in it will update the state right so that's fine and at this point you can see we're using State inside of a component which is a server component big No No so at this point you have to tell it and say you are a client side component right so we we're looking good so far right so on the outer div I'm going to start styling this up and by the way to test this all you got to do is type in if you see yourself typing in and it works you've mapped it correctly if you don't type in your mapping is off you need to check these two lines of code with this okay so that's good so now uh for the class name I'm going to say the background should be gray 700 so background should be gray of 700 uh with a 50% opacity text should be gray of 400 I'm going to round the corners surrounded OG the text should be small uh focus should be outline so focus should be outline none so basically I don't want to have this nasty outline outline none so when I'm Focus uh to be fair I don't even need Focus you just do outline none there you go is it outline none is it outline yeah ring none no ring zero no ring none active Okay uh I'm sure it's Focus yeah focus online then okay um that's fine yeah okay um so now what I want to do is for the input oh s the input that's one me right this does nothing all right it's the input all right so over here I have a class name and this is what we style it so we say background should be transparent let's skip the song background should be transparent um focus here is where it's outline N I was wondering why wasn't it doing anything because there's no bloody thing there like silly me so we say Flex one I want that to use up the majority of the space look how it firstly that looks beautiful right and then secondly the uh this shouldn't be flexed it should be flexed that's my bad yeah so now you can see that will take up the majority of the space over there right so that's much better okay I say if it's disabled it's going to say curse and not allowed and then it's also going to have grade out text if it's disabled okay text grade of 300 okay and when is it disabled right I'm going to say it's disabled if there is no session and I'm going to get the session by doing what we typically did previously by basically going ahead and doing this right so we pop in our session like so so if there's no session I want to deactivate that but to be honest you won't even be on the screen right so I'm just going ahead and doing a protective block there but you shouldn't even be on that screen yeah so it was more so when I was doing it before but for the button I don't want to submit anything if there is no prompt or if there is no s right so this is a or statement so if you if you haven't typed anything in it should be kind of grayed out right so in this case good that looks all right but I do want to style the button class right so in this case the class name and I'm going to do string interpolation here so back tis because I'm going to be using uh actually I'm not going to be using it so I don't need string there we go so I'm going say background should be hover opacity make it 50% opacity and now you can see look that looks good man so look when I hover over it look oh nice okay so we want it to be a background color like that but we're going to say text should be white um and then the font should be bold okay I wanted to do padding on the y-axis uh firstly why is it so small that's right yeah okay so padding on the x-axis of four Ping On the y- axis of two rounded on around the corners up so look at that o nice looks good right and then the prompt right here we have no prompt so why is it not disabling so that's oh yeah my bad my God I'm making silly mistakes there disabled if it's disabled we have to style it so I'm going say background should be gray 300 to resemble that it's disabled and I'm also going to say the cursor should not be allowed so now if you see here it's going to be grayed out with a cursor not allowed symbol so if I go ahead and type in boom look at that so nice right so that's awesome I think we've done the chat correctly this is exactly what I wanted um the the actual chat window itself will push this to the bottom okay so that's what's going to give it that nice finishing effect uh and I can prove to you that they will do that by going over to chat right now and I'm just going to add in the flex one over here right so this is basically going to say use up the majority of the space that you have so the chat will use up this space in which case you can see it pushes it down the reason why this works guys is because remember both sibling components so these two are in a flex box Flex column so this one's saying Flex one so use up all the space chat input is then forced to be at the bottom of the screen nice that's what we we want right naturally that is exactly the UI we want okay so heading over to chat input now this have the functionality that way when I type in hit enter it's going to go ahead and push this into the database and then we're going to start doing some chat GPT stuff right so we got some cool stuff happening there someone says where's the GitHub repo link of this project is in the description down below so you can feel free to get the code over on that side okay so what we're going to do now is we got the data we got the session I'm going to go ahead and get a reference to the um we don't have the that's fine I'm going to go ahead and have the generator response so basically I need to have a sort of uh add so this is I'm going to call it generate response right but really it's kind of like send message so this just make send me I think send message makes it a lot easier to understand what's going on so asynchronous and now what you'll find is a form has a specific event that it fires off when it submits right so what we're going to do now is I'm going to show you a nice little trick so you say onsubmit and then we need to send the message onsubmit right now what you're going to find is here you're going to have an event that gets fired off but you're never going to know what type it is and then you're going to be like how the hell do I know what type it is oh my God so here's a little hack okay so you just need to go ahead and do e slash to an arrow function and then you get the form event here copy that punch that in do a little import from react get rid of that and just like that typescript hacks all right that helps you a lot right so in this case we got the same message so this now we can go e do prevent default you see how it automatically fills in because it's exactly the form element that we need so that's how you get the type definition correct every time right so what I'm now going to do is I'm going to get the input from The Prompt firstly what I want to do is I want to trim it I want to say input first we'll do some defensive program say if there is no input no prompt return right so first the defensiveness and then we say if there is an inut we simply want to do prompt. trim so and to get rid of any white space at the end cuz that can mess up your prompts then what I'm going to do is set the prompt to blank right so what I'm doing is I'm storing it in a local variable and then I'm doing a set prompt trim okay so in this case that Returns the string as well cool and then what we're going to do is we're going to create a message that is going to be stored in the back right um so we're going to say we're going to create a message all right so we're going to create a custom type which is a message okay now message will go ahead and I'll show you what it is but in this case we're going to say text input we're going to have a created app and this is going to be the server timestamp so it's not this whatever that is this server timestamp from Firebase fir store and then we're going to go ahead and do the following yeah okay cool I see J and then we're going to go ahead and see us say user and then the user is going to have the underscore oops it's going to say underscore ID and underscore ID is going to be the user's email we're going to have the name of the user and we're going to have the Avatar of the user okay now what we're going to do is if they don't have a URL I'm simply going to give them access to a picture which is basically just this cool little API service which you basically pass in their name and then it creates like a little UI all it does is basically say SS right it's kind of cool if you have one like a need for that there you go right so in this case message now this message we're going to create a custom type definition so I'm going to show you where we're going to do it so at package.json I'm going to say typings dod. TS okay and now inside of here I'm going to create a interface message and you can use this in an approach whereby we're basically creating any sort of types that we want to use use throughout our project we can go ahead and pop it in here right so in that case bam hit save and now you'll notice it automatically pulls that in right so it's kind of a nice little cool hack as well all right if you didn't know so now we've got a message that we're going to go ahead and eventually push to the database but how the hell do we do this right that what's the next step so what we do now is we basically go ahead and we add the document to the database right so I can go ahead and do this so I can go ahead and say await add doc collection and then what I do is I basically need to specify the collection so firstly import all of the required dependencies that we need so in this case I need the ad dooc I need the collection I need my database object so you see have imported all the above and then I'm going to go ahead and say that we have the users the session. user. email with making sure it's there then we have the um chats chat ID messages and then yep and then the second argument is the so I'm going to make this very simple for you lot sorry I'm going to do so basically think of it like that so first argument is the collection second argument is the message right so typically you pass the message in like an object in this case I built the object above of and we're simply passing in so this what will now what this will now do is it will go ahead and actually um add it into the database so when I type in and enter a message it adds it into Firebase okay so that will add it in then next thing we're going to do is a toaster notification right so we'll add that in afterwards right so toaster notification and then what we're going to do is create a fetch method to the back end which will then go ahead and start basically communicating with our own AP so I'm going to say await fetch okay and then here what I'm going to do is I'm going to say for/ API which is our API and then we're going to say ask question okay so we're going to create an API endpoint and then this is going to be a post method I'm going to pass headers of content Json for the application because what we're doing is we're passing in Json data so this is all going to be in the form of Json and then we're going to pass in the body and what I'm doing here is I'm stringifying a bunch of information now I need to send a few few things to the back where basically I need that information first one is going to be the prompt right and that is going to be the input that we specified earlier and we trimmed the second one is going to be the chat ID the third one is going to be the model that we're going to use and I'll show you why we haven't got a model right now I'll show you how we get that model and the final one is going to be the session itself okay so these are all going to be things that we're going to need now for the model the reason why we don't have a model yet is because we need to go ahead and eventually Implement use SWR to go ahead and efficiently get the model so I'm going to show you how we do that afterwards but I'm going to say use SWR to get the model I swear it's listening to me sometimes use S SWR to get model and then here I'm going to say const um just for now it's just going to be the text Da Vinci model so these are a bunch of different models but for now I'm just going to have this but I'm going to replace this with that so to do use S that's an extension by the way right so in this case and you can watch my top 10 extensions video to go ahead and find out which one that is so in this case we've got the following going to the back end okay so now what we should find is that this will go ahead and uh do what we need it to do we need to obviously create this but after that's done we're going to go to the then block right and if it's successful what we're going to do so the then is always on the successful uh execution of it we're now going to go ahead and say the toast notification um to say success okay um to to say loading right so we need we've got a few things that we need to do right so that's to-dos that we need to go ahead and Implement right so first up let's go ahead and do the uh toast notification so that way we can get that in uh ASAP and then we'll test it to see if it pushes the um message into Firebase and then we will create our API Endo so three game plan right and then we'll do use afterwards so react hot toast so um react hot toast let's go ahead and do it right now documentation we're going to do yarn add react hot toast and this is amazing for this what you see right here okay so going into my second terminal bam Yar add react hot toast and now what we need to do is we need to import it into our app at the top level but uh we're using nextjs 13 that's not as simple to do in this situation so we have the layout okay but in this case the layout is a server component what we're trying to do here is definitely a client side component functionality right so the way you do this is you can create something called a client provider okay so client provider and what we can do here is we can use this pattern to basically push anything that needs the client at the top level we can inject it at this level okay so I'm going to go ahead and create a client provider component. TSX so RFC oops RFC so sometimes I get this and it's super annoying it doesn't allow me to do it that's fine what I'll do is I'll show you guys what I need instead so I'm going to have a client provider that's fine and this will return the following right so this will return a basically a fract fragment and it's just going to have a toaster inside of it right so toaster and the position of all of my toasts is going to be the top right so you can go ahead and specify a bunch of different ones like all of these directions and you can customize even further I'm just going to keep it very simple for now this this is going to be a use client so this is going to be a client component right now think about the magic that I just did here so imagine if I had loads of different comp uh client libraries so client library number one client library number two client library number three so they're all going to get injected and all of them are going to use by default a they're going to get rendered in a client basically a wrapper right so that's going to basically tell next chest that these these things are client components right then what we do is we simply inject it over here and now just like that we have it at the top top level so that's how you do a replacement for that in nextjs 13 if you're wondering smash that Thumbs Up Button because that was very useful information if you're coding in xjs 13 okay so now we can go ahead and actually make calls to the toast API okay because inside of our app we have access to it so let's go down to um chat chat input right so chat input there we go boom okay so toast notification to say loading so I'm going to show you how we do this now so at this point let's go and say constant notification I just know it right so this one we basically say toast Dot and Bic we import this from react toast at the top okay toast. loading and then what I say is I say chat GPT is thinking okay it's thinking ooh okay and then basically it gets assigned an ID of Lo notification right so in this case we trigger it off so it's going to basically pop up saying it's thinking it's doing something and then once it posts to our API right when it comes back with a success response then I want to say that the toast was successful right so what the way you do this is you basically go ahead and say chat GPT has responded and then your second argument is basically going to be attached to the ID of the notification of the first one so this one will basically be there and then this one will replace it so that's why we passed in the ID all right so in this case chat GPT has responded so let's give it a try right let's if this actually does well actually it'll get stuck I'm telling you say if I type in test boom so see how it says chat GPT has responded because it just basically it hit this end point it didn't do anything right so it it believe it or not it didn't work the way we wanted right so I know it might seem like it but it didn't do what we wanted because right now we don't have this endpoint okay so what we need to do now is basically go over to and you do get the response here if you ever do want to do anything with it by the way right so now what we need to do is create an API endpoint for asking the question okay so now what I'm going to do is I'm going to go to my pages API hello right so at this point where you've got hello what I would do is I'll just copy this right the reason why this is good is because this you can actually use this as like a template for your starting portion right so if we were to go ahead and even copy that and then I was to go ahead and type in our endpoint so now I want to do a ask question remember this is actually going to be the API endpoint route so do not mess it up it should be. TS yeah we paste it in so this is going to be our route so let's go ahead and get this set up the way we wanted firstly the response type of data right so in this case we can Define the response type here so we're going to send back an answer and this is where we basically start doing the magic to go ahead and communicate with chat GPT so if you're excited for that this is what you've been waiting for right so in this case we got the answer right here so I'm going to make this an asynchronous function because this is going to be um yeah this going to be an asynchronous score and then we're going to basically strip R out all of the things that we sent over so think of it this way right when I have my chat input so let's go over to my chat input where is it going uh chat input and you can see what happened is I sent over the four things in the body right so what I'm doing is I'm essentially reversing it now and I'm getting them out right so what I do is I say const and I start getting out the things that I sent along so prompt chat ID model session all these things I'm going to go ahead and get out of the request body so I'm destructuring them right then what I'm going to do is I'm going to do a few fail safes so I basically want to return a 400 status if you don't pass in a prompt and if you don't pass in a chat ID so this is basically like an API we're building right now so if we don't have a prompt I'm going to say please provide a prompt and return a status of 400 like an error and then the same with 400 that's basically saying like you're missing some data you know you need to return something okay then what I'm going to do if not I'm going to do a chat GPT query so this is where the magic happens guys this is the moment of truth this is where I'm going to do it I'm going to say con response equals await query and we're going to create this query function and I'm going to pass in the prompt the chat ID and the model okay so we need to create this query function so what I'm going to do is at the top level of my code I'm going to go ahead and create a new folder called lib right so you can call it lib or util or whatever you want to do I like to call it sort of like all my utility stuff lib so in this case I'm going to go ahead and type in uh query API dots it's like a helper file right and inside of here is where I'm going to have the magic that goes ahead and connects to chat GPT so I need to create a new file as well called chat GPT uh in fact we'll just do a lowercase chat GPT and I need to then install the open AI Library okay so in this case I need to go ahead and type in Yar add open AI so now we are installing the open AI mod modules and libraries that kind of stuff right all right so we've got the chat GPT Library installed and this is where I need you to go ahead and get your API key so we need to install the following oops install the following configuration and open API um uh modules from open API open AI wow I keep messing it up um and now what we need to do is basically get into it right so remember in the beginning I went to here my platform open API and we had the API key section so I've already got an API key right so you need to create a new key so you just simply go to open API open a.com personal and then you should see view API Keys click on create a new secret key and your key will pop up all right so I've already got a key so I'm going to show you how to import your key or how to do how to add your key where to add it so next thing you want to do is environment local so I'm going to hide my screen for a second you guys thought I was going to slip right you guys thought I was going to slip all right so now I'm trying to see what's my hide on I always forget it um oh screw it all right so at this point I'm going to go ahead and just [Music] do okay so there we go okay so in this case we're in my environment file and then for you guys what I need you to do is you need to have your open API key here so basically that value that you just saw on the other screen paste it here so paste it here right okay so now what I'm going to do is I'm going to paste my value and I'm going to come back to this I'm going to save the file and I'm going to close this okay so I'm about to paste my value put in my Google secret obviously and then close this file so we're going to do that right now so I'm pasting my open API key I am pasting in my Google secret once again I'm closing my environment file cool so in this case we've got um now I've got what I need so chat GPT I need to basically create a configuration to it so we are back in chat GPT land so the farm and now we're going to say const configuration configuration equals new configuration and we pass in an object right and in here I pass in the API key so API key and I say process. n doop AI API key right nice and this will basically connect to my API so now I need to connect to open API right open AI okay forgive me open AI wow open AI equals new open AI it's a proper tongue twister right and I pass in the configuration and this basically is like a key to access my open AI API right and then what I'm going to do is I'm going to export default open AI ah nice so now what I can do is I can essentially use this single ton object um not single ton we use this config object which has a connection to the open a API and basically make my chat GPT calls right so we're going really strong trust me but we're actually going very very strong right now now going over to the query API we can actually use that stuff right so I'm going to import my open AI from my open AI file okay oh sorry from chat GPT what am I doing okay then I'm going to create a query so con query equals this is a helper function async async there we go and it's going to take in a prompt chat and modu and uh the prompt is going to have a stream value so this just our type values just going async async yeah the chat ID is going to be a string and the model is going to be a string as well okay um command J someone said I for literally said Jay um so then now what I'm going to do right is I'm going to make a call to open AI now so this is basically where I do I pass in what the user types in I'm going to make a request to chat GPT right now okay so basically and what we call this is a completion so I'm passing in the information at this point and then it's going to go ahead and uh and do and do that so so at this point now we go ahead and say const res so the response equals wait open AI Dot and then you can see here we've got open AI dot create completion so you see we got loads create image create completion opening ey is incredible and if you want me to do more videos on all of these things just destroy the like button and I'll literally work out how to do this stuff and I'll teach you all right so now we've got the create completion and now what we do is we have to pass in a few things okay so the first thing is the model now the model remember I I had the text D Vinci you know that thing put being passed in so model I'm passing in through our value here that's going to be the text of inci okay um and then what we do is just aut to make the okay they could get expensive yeah you're right exactly yeah and then we've got the prompt right so this is what the user has typed in so the prompt and then and bear in mind this is actually a value that they expect so you see if I do control space bar you can see all these different values and then you've got a few different okay so these this is quite important here right so in the docs I'm not going to go too far into it but you have something called the temperature and the top p and what you do is by manipulating these values you are basically telling your chat GPT or open AI B that you want it to be more creative or more logical right so by having a 0.9 I believe on the temperature it's more of a creative answer so you can come out with different angles sometimes if you say write me an essay and you had that value super low it would be very like direct whereas creative if you want to inspire the creativity of the model or .9 is a good value right so you can go ahead and mess around with that yourself but in this case I'm going to give it a temperature value of 0.9 Max tokens is essentially what's we're limiting the number of tokens that this one call can do I'm going to pass a thousand in at once right and then we're going to say the top p is one so these two values are the ones right so you can manipulate these and it will give you different responses from your model and then you have something called a frequency penalty and you have a presence penalty I'm not going to lie I don't know what they fully do these two so feel free to research them I just left them on zero for now I'm just being totally honest with you I would have to look up at this right but um so at this point once it's done what we do is we say then we get the response back and I'll show you what happens right so inside of response you see we get all of this back right so we get the data back and then you can see we actually get the type definitions because we've used the open AI Library so in this case we get the choices and then we're just going to pick the first text from the the first choice that comes back that text because what can happen is it can return like maybe three choices right but we're just going to get the first one we're going to pass text and if there is an error right what I'm going to do is I'm going to get the error and instead of just console logging it I'm going to do an implicit return right I'm going to implicitly return and I'm going to say chat GPT was unable to find an answer for that with the error message right now the reason why I find that this is particularly handy guys is because what I found was sometimes it would actually error out because you would be rate limited right so You' get a 429 error code which means that there's too many requests and that can happen quite frequently especially if you're spamming the hell out like I was right so you want to make sure you catch that and then that way you can go ahead and forward it through and do the same thing okay return res and then what I'm going to do is I'm going to export default query so now we've got our helper function to essentially carry out the the the prompt to chat GPT and what's really cool about this guys is that firstly we didn't use the chat ID so that can actually get rid of this right so we actually don't need this the reason why I included that is because what you could do is make a call at this point to get all the previous messages of your chat and build your prompt up on that so that way you have contextual chat so that's if you if you're wondering how to do that that's how you would do it um but yeah that's that's actually how you would do it right you could do it that way um but I don't want to go too crazy on it but yeah okay so at this point now what what's really cool is that if I change the model of the input here it will go ahead and use different models so once we get that bit set up it will just literally click and play into this right so now we've got a query done so we can go back to our ask and we can go ahead and import our query helper from our library right so now we've imported it from our library now we can go ahead and build out the rest of our um our thing so this point we got ask question so yeah um so at this point we've got the I'm going to create a message now so message and the reason why I'm doing this is that way I keep it consistent with the previous message I made all right so at this point we're going to go ahead and say that the text is going to be the response or it's going to say chat GPT could not find an answer for that right so text or chat canot find an answer for that if there was no available thing that come back and now this is the important part okay so I need to get the admin right so I need the admin's fir store details because what I'm going to need to do now is from the back end I need to basically create a uh a document right so I need to go ahead and add in a uh a document into the messages collection but from the server end which means I need a special admin right so in order to do this I'm going to show you exactly how and this is very powerful right so listen very carefully so at this point I am going to pause at this and I need to set up Firebase admin because we need the uh time stamp and a bunch of other things so I'm going to go into where Firebase is I'm going to create another one called Firebase admin and this is a different Library huh so it's a Firebase admin API right so in this case now what we're going to do is we're going to install Firebase admin into our project so command J uh Yan add command uh Firebase admin there we go all right so I'm going to do my import so very similar approach where we have the get apps and we you know we import it so same similar thing except now we need something called a service account key right so let's head over to our Firebase so over here and then I want to go into our uh Firebase uh build it was um authentication yeah auth indication and Now settings um okay so I've completely gone blank here but let's find it don't worry about it let's find it together so it's called fir store database um usage fire store rules where is my admin stuff I forgot I've completely gone blank um I think it is in authentication right oh no sorry it's in here project settings there we go so project settings then you want to go to service accounts yeah so at this point you can go ahead and click in create service account so here we've created a service account and then I want to go ahead and do node right and we need to generate a new private key so this is the the code that they give you I'm going to show you a better way to do this but we're going to generate a new private key right now I'm going to click on generate and what's going to happen is I'm going to download a file so I just clicked it it's just downloaded a file for me so I'm going to show you the different approaches that we can take to getting this the way we want it right so I've just moved that off the screen because I had something in there so it's downloaded um the file that we want and then what I recommend you do is you take the file that it going it went ahead and gave you so I'm going to go back to my screen right now you take that file and you copy you just drag it over here right so right now I've got this now what I'm going to do is I'm going to rename this to Simply my service account key right but you see right now so this is good in my local Dev environment but how do I do this if I was to go ahead and like deploy this I don't have I can't just give this to an environment variable right so there is a way of doing that though so what I want you to do is I contr a copy this right copy this I'm going to show you a trick now right so locally this will work with a react app but when you want to deploy it it's a little bit different right so I'm going to show you how you can actually include this in a environment variable right so yes you can do that all right so what I want you to do is head over to I've got the here just to help out actually so you want to head over to this website right now so text fixer.com SL tools SL remove line brakes right then you want to go down and paste in your um your your your block right this point we're going to do um go back to my service account key copy this go back over to my uh this one and paste it and you see all I need to do now is remove the L line breaks so remove line brakes and you'll get this okay so you want to copy this and again this is actually all in um all in the the the papa get repo in the example environment file okay so basically you want to grab this copy this and now I'm going to show you something else it just blow your mind I I was like whoo that actually worked like holy crap when I found this one out yeah so now rather than using the service account key because again you don't want to commit you don't want to push this file right absolutely don't want to push that file public right that's a private file which means I should I should get ignore that which I will in a second right um somebody remind me so at this point now in my environment file I'm going to hide for a second I'm going to uh hide my keys for a second as well so I'm going to take this key away I'm going to take this key away okay and then what I want to do is come back to my screen and then now I want to type in Firebase service account key equals right and what I'll do is I if I was you I just pop it down there okay and then I'll show you how we do this so that value that we copied earlier uh I just I copied it in my clipboard I'm just going to grab it now so you copy the value that I talked about the massive one and you just paste it in guys like that's literally it you just paste it in right I kid you not you paste it in right and we can do this when we deploy as well right so you have to do that line break cleanup otherwise it won't work as an environment variable but that's how you do it so I'm going to go ahead and put back with these environment variables save the file and then close it okay so I'm doing this now so I'm going to go ahead and just pop these values back in um I'm going to go ahead and pop in this value right now as well boom and now we have our value okay so this is good so going back to Firebase so at this point what we could have done before is if you want to keep your Json account in your directory you can do it right you can do it with this call but again as I mentioned you don't want to commit that right you really don't want to commit that to your code otherwise every somebody can see your your service account key um so I wouldn't do that right so firstly what you should be doing is if you are going to go that route is get ignore it so service account key should be then grayed out so that's good so you want to add it to ignore file but we want to do it from our environment file so that way we can do some cooler stuff with it right so now what I want to do is you basically rebuild it from your Json so you say service account equals json. pass and then you get your account key from your environment file and then you do as string right uh at this point Firebase admin um yeah there we have it so we got the service account rebuilt out basically and now what I do is I say if there is no get apps uh. length right so no get apps. length right then what I'm going to do is I'm going to say admin do initialize app okay and this is a single G pattern and we say credential admin certificate service account so basically we rebuilt it back from this environment variable and then we initialize the app with it and then what I'm going to do is I'm going to say admin DB equals admin do fire store and then what I do is I export my admin database and now what I can do is I can make admin calls from my back end to manipulate the database with zero uh permission so and remember admins this is why you have to hide that key admins do not need permission level requirements they can just go in and just delete everything right so you have to be careful with this okay um right so in this case we've got this here so now I'm going to go to ask question and where basically we're going to go into our code and start doing the uh finish off our API query okay so now where I have I need to get the time stamp from the admin database right from the database basically but this is on the noj this is a back end this is a server level right so I say create app and then I go ahead and say admin. firestore do amp do now okay so do now like that right and then I basic basically have this oops no yeah and then I say user I'm going to pass in a user object my user object is going to have an ID of chat GPT so this going to be chat GPT the um name is going to be chat GPT and the Avatar in this case I've actually got an avatar of chat GPT that I've saved feel free to use it there you go and then we have it okay cool uh use it at your own risk basically I'm not I'm not I don't own that all right it's just a logo I I I'm not assuming ownership whatever chat GP I'm just trying to spread love you you have to say these things now so now we've got the message ready I'm going to go ahead and do the install so we say await add to the database we say await admin DB do collection right so I need the admin DB firstly as import admin. collection and now this follows the old approach right so I don't know if you've done this before but this will follow the old uh V8 approach that we were used to back in the day so be session do um so okay so all I'm going to do is I'm just going to write this one out for you so it's a bit easier for you to just understand otherwise I'm just going to f it a bit when I explain it so a wait so collection users doc session collection chats doc chat ID collection messages add message right add message into this collection that's what we're doing now you can go ahead and specify this in a in a single doc string but I want to just do it like this right um so that's pretty cool um okay so Tina I I I'm looking into doing new builds yes so CLI I'm going to add it there right so at this point now that will actually do what we want so res. status Json I'm going to send back the answer and the answer will be the message. text cuz we already have it right so if all of this goes to plan what we are doing here is we are from our chat input loads of stuff happening right from our chat emper we are making a API call so basically we are adding to Firebase firstly from the client the client then queries our own API right so you can even shift this if you want to the back end but it's fine right so then what we do is we make a request to our API our API will then go ahead and hit our own name a ask questions end point then we hit this point we strip out all the values that we passed through we then go ahead and say we check that make sure we got the details we need we then query chat GPT chat GPT will then give us back a message right so the response we package this up into a message we then add this from the admin so the back end into the uh fir store database right and then what we do is we return the answer as a bit of text okay and then because it's all connected uh in a real-time Fashion on the front end already we should see that being updated okay so let's go ahead and refresh and see what the hell's going on so firstly I've got an issue going on here what is happening um chat GPT da da da so server error at this point what I would do is just we've we've installed a bunch of stuff closes the server run it again and let's just see what's happening um okay so oh no please I should have spotted that when I seen it maybe it would have been oh there we go thank God I was thinking damn I was like yes s so at this point now if I was to go ahead and click into these cool and then what I want to do is I want to bring out my um Firebase database where is it gone let's just pull it out here so I'm going to pull this over here so we can see it so I'm going to go to my fir store database and let's go ahead and type in a message into one of these so you can see here that these have the IDS at the top right so we've got wo this one is DZ T right so DZ T in chats let's go to DZ DZ T this one and then you can see we have no messages right now so if I type in hello world enter right it will say chat GPT is thinking so remember our loading has punched off FLIR messages it went ahead and added in on our message of hello world now it's asked oh sick now it added in chat GPT and then from the admin it added in the response which was some some yeah some some Chinese text I guess or I'm not sure what that is but yeah so at this point let's go ahead and say what is the color of the sky and let's see what happens right so look I client side added it we then make a request to our back end and then the back end says the color of the sky can vary depending on the time of the day in the weather but it's usually a light boom let's freaking go guys right that is so amazingly powerful right this is so cool right this is so cool yeah so you guys can see that that is literally pulling it in and you see the way it's doing it is nuts right it's doing it from our back end it's just oh so good right now we can now we've got the messages we can go ahead and do the front end so let's go ahead and keep the momentum up cuz we still got quite a bit to build right um but it's all going to plug and play now I promise you and we use SWR for the model selection as well so now we've got the chat so we've done if we go to our a chat page page. TSX over here we've got the chat input which is pretty much done and then we've got the chat now what I love about this build is that we aren't connected to anything so chat input is completely independent of chat which is so nice right all right let's go ahead and do the chat directory now right so firstly we need the session so we need the DAT this bit a breeze now cuz we've done this before right so we need the use session react context is unavailable in server components yes because chat needs to be a client component there we go all right so we've got the chat there we go bam and now what I'm going to do is I'm going to go ahead and map the um the items from the uh collection right so in this case we're going to get the messages remember you get the loading and the error State as well we don't care about the error and the loading for now we're just going to use collection uh no uh use collection yeah use collection there we go and then I'm going to going to go ahead and say if the session exists and uh query so now we've going to have a like an aggregate query remember how we do this we say firstly we say the collection uh that's actually spot on with what I wanted yes that is correct and then messages yes and then the second argument would be uh order by created app so I need to firstly pop in order by collection so this is very similar to what we did for guys I import all of the things I need users session email chat chat ID messages and so forth right but this case we're just double checking the session exists before we go ahead and do that right right now we're going to go ahead and map out the messages here so in this case we're going to go ahead and say messages. docs. map out for every single message I want to map out a message item so message and we're going to pass through the key firstly the key is going to be the oops message. ID remember you should always use a key when you're mapping through right and then we're also going to pass through the message and this is going to be the message. DAT from Firebase which is going to be the content of that message now what I'm going to do is go ahead and create a message component so here I'm going to say message. TSX and then here RFC message like so and inside of here we get the actual message itself so the message contents and we can we actually get the type definition from this from Firebase which is documents so in this case I going to say type props equals message equals document data and then here I can say we get the message come back through like so and I can map it to the props right and just like that we now have the perfect type definitions mapped in this one's freaking out because message only refers to a type but it's not being used to a type um oh I see see see so uh that's a problem because we don't want to have that oh yeah yeah so I'm not actually that's my bad I haven't imported it what am I doing uh there you go yeah need to import it and now what we should see on our message hey look at that messages are coming through yeah so if I type in like Hello World you'll see that now you just see like another hello world and then while it's stinking it will basically wait for it and pop in the other next one yeah so at this point we've got the div now I'm going to have a div uh and inside of it I'm going to have a P tag and here we're going to have the message text so the message. text and wait for it I'm not going to hit save yet I'm not going to hit save I'm going to wait for it right so the source here I'm going to say message. user. Avatar yeah and then we're going to style this up a little bit so I'm not hitting save I'm not hitting save I'm trying to I'm going to show you how it pops in and it's going to be like wao moment right so do class name oops uh pt1 uh text should be small and then the div on the outside should be a Flex container space along the x-axis of five padding on the xaxis of 10 Max width of 2 XL and margin X of Auto and then obviously we have the outer one but before I do that going to hit save now 3 2 1 boom oh look at that look at that guys look at that it's so cool it's coming in so let's go ahead and do the finishing touch on this we're going to say uh we're going to do a string interpolation because we're going to use a bit of a uh we're going to check a variable here so say panning y of five there we go bit of breathing room text should be white and you can obviously add in do mode do all that good stuff right and say is chat GPT is chat GPT so firstly I need to determine if I'm chat GPT and the way I do that is very simple right the only way you're going to be like you're going to know if it's the robot because if the admin added it their message name will always be chat GPT otherwise it will be your email address so we can safely confirm by using this variable here by saying is chat GPT and and and then we say BG and then we basically pass in the color of the one that I want so I'm going to actually have like the striped approach that they have and then wait for it 32 one pow oh my goodness look at that like Oh my days that is so clean all right and now I type in um what is a YouTuber and wait for it chat GPT is thinking wait for it wait for it wait for it wait for it wait for it come on come on sometimes it will bug out and I'll say 49 YouTubers individual creates and uploads video content to sharing on YouTube oh this is so cool if I go into another one here new chat you will see and also look at the last words are coming in right in here if I say um explain what coding is right and wait for this check this out Kung cot asked the question we answer that kind of stuff in zero full hero dude um look at that fad says if these messes prob I'm about to lose my mind yeah dude so sick right look at that look um are you a human look at this chat is thinking wait for it wait for it wait for no I'm not human a just so cool man so cool and look you can go ahead and go through the different you things and all that kind of stuff but yeah this is absolutely amazing and you can go ahead and delete old stuff and you can go ahead and click through and look it takes us back to the home screen if you delete amazing amazing stuff right so this is so clean right now obviously we still got some UI stuff we still got the model selection to do we still have a few areas that we need to fix right what we now need to do is go into where my code out let's see so we'll go into page. TSX and we had overflow hidden here but in here I believe we wanted uh overflow scroll yeah so here is what I wanted to do so Flex one but I wanted to say overflow y of scroll that way if it ever got too big it would be the scroll right you can do auto as well right so only if it goes past that point it will go ahead and pop in and you can say overflow X is hidden yeah well because we're actually wrapping around anyway so this works really nicely uh who is Pap react ask chat GPT I don't I don't even know if you ask this right who is Papa react who knows right if it does that I'm going to blow I'm going to lose my mind right so someone says who ISAT um let's see I I I'm nervous I don't know what it's going to say education organization helps provide resources oh wow off Serv such online course focus on yo that's that's pretty crazy I think that's I think that's spot on I think it is right we are an educational organization a I guess I'm an education organization they forgetting about Jay hating on it but it's that's amazing that's so cool um wow so uh at this point this is so this is a really cool build you see what I mean right so we've got this down and now what I do want to do is I want to say if there is no messages I actually want to um have a little sort of like a nice little prompt right so I'm going to say messages um dot empty and then what I'm going to do is I'm going to save us a bit of time here by just popping in what I need so I'm going to go pop that in and I'm just going to pop in a fragment with an arrow down Circle icon right and what this will do is I'm actually going to have an outline so now what we'll do is basically if there is no message Watch What Happens now so new chat takes me to new chat wait for it type in a prompt below to get started hey look at that that's so sick right you're so famous that even open the eye I heard about you ah it's pretty cool right it found me um so so at this point even if we delete it you see how it will take me back to the home screen but this is what I'm saying like you're actually getting different messages right which is absolutely incredible you're literally getting the different messages you're getting new messages um it's it's really quite powerful right like what's happening here and you see like the last thing so the last message here hello world po reactor educational organization this is amazing right so um just want to type in test on I just want to see something uh this one for some reason is it's only showing the top one which is strange but yeah they should show the last message uh on here um wait for it okay but let's let's move on cuz I don't want to get stuck here messing around with this but you see how the even the Overflow comes in when it when it's needed yeah so um sometimes if you can't figure it out it'll say chat GPT has no answer for that or you know how we did it okay so uh at this point now let's do the model selection while we're going hot let's do model selection so now what we're going to do is react select so react select okay so react select let's keep going strong we're going to use this to create a select right so first things first I need to make an API call which will allow us to get all of the engines so I'm actually going to save us time now and do that right now so inside of our API I'm going to go ahead and create a API call called um get engines get engines. TS right and what this API is going to do is essentially we're going to go ahead and pull in a bunch of stuff from so in this case I'm popping this and I'll explain and everything so this is no different to our previous API core uh layout right so the same layout is is is what we're dealing with except we have firstly on a type of options which is going to be what we end up returning in the select field so that's why I've created the type options here is the return type and what we're doing is we're simply returning a type of model options which is option uh array right so this is the reason why it's because you know those little select drop down Fields the way they expect data is in value label pairs so so what I've done is I made a type definition for that value which is called option value label Pairs and it's an array so model options is basically going to be the drop down options then what we're doing is we're basically making a call to open AI we're saying list all the models and we're simply passing the data from it right and it's data. data because inside the data block is is inside of dot inside of data is literally what we wanted right uh F said ask who is Sunny who is Sunny s Pap at YouTuber let me actually do that I'm actually going to try um in the background I know I'm getting distracted I'm only going to do this one thing oh wow my God that that gave a big prompt um I actually want to do this I want to see what it's like uh who is proper at YouTube while it does that let's go ah and do this so then uh carrying things on we're then mapping things out so that way we're basically extracting the data that gets returned and we're just lab we're mapping it into what the the thing that we need so all we can about was the ID that came back so the IDS and each one was like text Da Vinci Da Vinci had the the other add models and those kind of ones loads of models and then we're simply returning it in a statement right as then we're returning it in the response okay sunny s papa is a popular British YouTuber and uh reaction videos okay he has over 84,000 okay so we' traveled forward in time uh over 120 million views since you began uploading in 2014 I [Music] mean it's somewhat there we'll get there we'll get there and reaction videos maybe who knows all right this so jokes okay let's stay focused now um so we've got this uh get engines available and now what I want to do is um I'm going to make a call to my get engine so uh what I need to do now is I'm going to go to my um my sidebar and where we had modal selection right so here so what we're going to do inside the sidebar guys is we're actually going to go ahead and say okay this sidebar by the way is going to be so I I want to hide it here I want to have the modal selection at the bottom on Mobile screen and I want to show it there on a big screen so what I say is I say hidden for mobile and show on um small screens and above right so small screens and above inline it and then what I'm going to do here is create a new component called modal selection right and this model selection is going to be our special thing that we have access to so it's basically going to be the one that we I this is going be really powerful and it uses use SWR so stay tuned right so we're going to create a new component called modal selection. TSX RFC either and um and then we're going to do import it like so okay and now what we should see is you see we've got the Modo selection on a big screen but it hides on that screen that's perfect right and I'll show you why we did it that way because I want this to be uh pretty flexible in how we use it right now okay so next thing I need is use SWR now if you not have no idea what use SWR is it's basically I I'll handle react select afterwards it's react hooks for data fetching by the guys over at for cell now the reason why we want to do this is because it allows us to fetch data in a really efficient way because now we're fetching it based on cached key value pairs which means that it doesn't matter which component on we're in we don't even need a global data layer like Redux or recoil we can just do it with something like us W are right and it handles it really well when we're doing things like data fetching okay um that's so sick uh Chat friend goes everyone subscrib to chat GPT comes true let's go that's it guys let's go um let's keep going strong so we're going to go ahead and install this so s SWR so if you click on get started you can see y as s SWR and then they've got their sort of explanation and I'll explain it briefly as to how it works but it's actually really really powerful in that what it can do uh we do go over it and zero full St curo so I'm going to do y add hide this and then what I'm going to do is go into um my yeah there we are and here you can see so basically what we do is we basically say that we we provide a key so this doesn't actually have to be the Endo just any key it can be anything and then we have a fetcher the fetcher is basically what we do to get the information and then we have all the three states we have error is loading and data State and then you can do like refresing refret on click loads the St like that so what we will do is we will go ahead and make it a client side um component so this will be a use client okay and then we're going to go ahead and pop in the following we say import use SWR from SWR and now what I'm going to do is rather than make a simple fetcher function like this I'm going to have something called Fetch models right so I'm going to create a helper function here called Fetch models uh fetch models models what am I doing models I get so CAU up right and this will be a function which goes ahead and just returns simply um it's an implicit return so we don't actually need this we can just go ahead and say fetch and we're going to make a call to our own API and this one is remember we made an API in point called get engines right so I'm calling it engines but really it's uh I guess it's models right get models get engines you can rename it and then we're going to pass the Jason response right so get engines get engines what did I call get Engineers did I engineers get no get engines yeah get engines right and now what we can do is we can say const uh data uh we're going to rename the data to models and then we're going to say uh is loading I don't care about the error State that's fine and then we say use S SWR oh Marios is in the house what's up dude I remember the key so this key doesn't have to so a lot of people what they'll do is they'll make the key like the the the route you actually ended up calling right but you can actually make this key anything that's the really cool thing about this right so what I'm going to do is I'm just going to call this key models right and that's a lot of the time when I teach this they get pretty confused but you put the function for fetching the information as a second argument so this is the fetcher and then we have the fetching like so right so now what we can do is this will fetch the information for us and um and then what I'm going to do is actually have rather than a piece of state to keep track of what the user selects in the drop down list we're going to have another cached value um in using use SWR and then we're going to share that between different components really powerful I promise you I'll show you how we do this so next thing up we're going to import this uh react select we're going to install it's a really good library for handling um dropdowns that kind of thing I'll make a little uh Instagram real on it or YouTube short on it it's actually pretty cool it's very nice and it's searchable as well so you can say like uh let's just type in like red for example you see how it's searchable it's very nice um they show you like that's the when I was talking about the type definition uh making sure it was in this format and we ma through it that's what we did on the back end right so we made sure it was in this format so now I'm going to go ahead and pop this into our code like so so I'm going to pop this over there and now I'm going to use it so over in my div I'm going to say select like so and it's a self closing component so something like this and we're going to go ahead and do the following so class name here margin top of two very simple the default value is going to be the models right the mod uh the model we don't have a model yet right so we don't have a default value yet so I'm going to do afterwards we're going to say is searchable is true okay is loading is going to be attached to the Loading and what this does is it gives a really nice UI it shows actually how things work uh menu position is going to be fixed okay and then we have a class names and this one is going to be um basically the way you do this right is you have in here you have something called control and the control allows us to basically have the state so is it being in hovered right now is it what is it doing so this if I type in state DOT you see we can say like is it disabled is it focused is it kind of whatever in this case we we don't really care about any of that we just want to go ahead and say that I want the inner styling to be a color that I want rather than your color so I'm going to customize it to have it our own colors right that means that that that doesn't play an effect and then we go ahead and actually oh you can leave that in there yeah and then we have the placeholder which is going to be the model as well um which we don't have yet so I'm going to go ahead and just comment that out as well and then we have on change which is for the model and then we have options which is the actual options for selecting so first thing we have is the models uh and then remember inside of the response it was called Model options right so model options and then we are going to prepare another piece of state but in this time we're not going to have a fetch right so you don't have to use SWR when you're data fetching externally you can actually use it as a lot many people don't know this but you can use it as a like a local uh way to transfer like rather than having a global store you can just use it as a way to kind of use it between your components right so it's pretty cool you can have a mutate function and this we're going to rename to set model and then I'm going say use S SWR and in this case I'm just going to say model or model why do I keep saying Mo my God sorry guys model model Mo model yeah and then here what we do is we say fullback data and this is basically the way you say it so fullback um one second why is that being weird fullback data equals text Da Vinci 003 okay and now what I'm doing is I'm basically setting this is like very similar to a um uh very similar to like a used state right cool so now what we can do is we can go ahead and give these default values and default Place holders and then the set model we can go ahead and use on the onchange right so here we can say onchange and event gets fired off and we just use the E do value to set the model and we're doing the exact same thing and it's super Tina say sun I'm using S SWR with react native and it's making it blazingly fast with caching exactly because it caches the value so if it makes this call here and we re EST it in another component it doesn't need to make the the same fetcher request again unless you can set obviously refresh intervals and that kind of stuff but it's so good in that sense so imagine you have loads of uh different requests being made it just reduces the number of requests in your app right so absolutely incredible so now let's go ahead and have a look what's happening so let's look inside of our sidebar and we have our model so let me go ahead oh look at that nice and oh look at that guys it got it our API is working text to Vinci Ada babage these are all coming from the back end that is amazing right text Vinci cool the only thing I see here not being cool and not working the way I want it is um class names so this is not looking the way I like it so that's it that's why I don't know why that wasn't doing what I wanted um but in this case if we did like I Da Vinci I think this because I did text white maybe was it no okay no I'm not sure honest there you go that's better text white didn't really do anything there we go yeah okay so that's it it just took a little bit of refreshing right so save refresh and then you're good right so I think my my Tailwind is being a bit buggy there you go cool so text avinci O3 and you can see we pop it out nice right and then on a small screen it's hidden right that's cool and obviously there's a bit of a spacing issue here that I'm not liking um so firstly let's make this a margin top to uh that's nice and then secondly let's go out of here and do in our sidebar I believe it's here that uh is what I'm having a problem with um so in the loading so where we have our chats being looped through uh it was actually here so it was Dev this will go inside of here and then we have a class name I would say Flex Flex column uh space y of two and a margin y of two right so that's going to give us a bit more breathing that's better there you go nicer yeah and then if it's loading the chats I'm going to say it's loading the chats so here on this one just while we're coming back here I can get rid of the console log we don't want console logs in production um I can go ahead and say loading uh and and and then I've got a nice little bit of text that will pop out here to see if it's loading cool okay now what we've got here is you'll see it's going to load on here as well as well as here the loading chat and then here you get the nice little what I love about this is we passed in loading so you see it's loading and then bam oh so clean so clean guys right Gabriel says it looks like I'm late don't worry dude it's going to be up afterwards uh just smash that like button if you're coming in late to enjoy the video right so now what I want us to do is we've got this down which is looking awesome I now need to feed this through right so obviously I'm not sure what the color is glitching out there but it's fine I need to feed this through and firstly I need to make it pop under here as well so chat input let's also do that one so chat input I will show you where we're going to put it inside the chat input so remember I had a modal selection down here the reason why this is genius right is because now what I can do is I can make the chat input appear over here if it's on this certain screen and appear here if it's on the other screen so now what you do is you wrap your component in a div so for example in this case a model selection will go here and we just do the opposite in towin we just say on the medium screens it's hidden and now look at that guys look at that so on the on this screen it's there and on the um smaller screens it's there lovely right look at that so on a mobile view you can actually select your model underneath and it works now how do we feed it into the house f is it live yes um how do we feed this into the actual prompt right so where we actually did the chat input now model was being used up here right so remember the to do we left it saying use SWR to get the model so this is fairly straightforward now all we have to do is is we match up the uswr with the previous uswr that we had so in this case where we had the um the component for model selection look at this right so I'm going to pop this over to one side and I'm going to explain a little concept here so rather than doing this right which is rubbish we're going to basically do this so I'm going to go ahead and get the same um same line of code here so the the users model so in this case I can go ahead and get the access to it here so we're going to say data model use S SWR and the only thing you need to make sure that you do right here is actually go ahead firstly import that is actually go ahead and use the same key so the same key is being used here notice how the same key the fullback data Remains the Same that's fine uh the text is fine we can go ahead and get rid of this and we're not actually using the set model or the mutation so we can actually get rid of that as well just to be a bit safer and now what you can see is is and I'm going to prove this a point to you right so here if I change this to daini if I go over here now notice how it's da Vinci if I change this to babage similarity and I go over here now notice how it's uh babage oh so I've actually messed that one up sorry um text D Vinci B so I messed this one up a little bit I think I haven't saved it or something but yeah that that does work right just just trust me on it it does work okay so at this point now we got text Vinci my my react select box is bugging out as well I don't know what's going on but anyway yeah so the point is that this box now I can actually get access to it okay so that's the main thing I'm trying to point prove a point to and the way that I can show you this is basically if I was to go ahead um we're going to go ahead and show you something so text Da Vinci is quite smart it's the smartest chat GPT model it's the one that the one that you're using on the playground is probably that one so if I go ahead now and type in explain what programming is right now you can see chat GPT will think and it will give me pretty good answer right unless it if it errors out for whatever reason right it can happen don't worry about it right so Clayton says amazing Pap look at that programming is a process of creating instructions for computer blah blah blah now if I change the model to something like adder and I ask the same question right now because remember all I'm doing with the chat input is feeding in the model into the prompt right so imagine remember the initial prompt that's the one that's going going in so now all I'm doing is I'm using the same thing explain what programming is but I'm doing with Adder now okay to me and everyone else about the Au sleepy bed it doesn't make sense right so add is not as good as understanding right and then also you've got certain ones for coding so there was like another one code D Vinci I think it's another one code Vinci so if I type in code vinci2 I said write some write a w Loop right so in code D vinci2 the see this wait for it a while loop and now you will see it will give me some kind of w Loop that will come back I guess wait for it chat GP okay so to go through five questions code number questions it gave me like tons right but if I was to go to like text D Vinci write a while loop obviously my prompt could also be better I could say why while loop in JavaScript right in this case it hasn't that starts with zero and ends when it reaches so yeah you can see Tex Da Vinci is by far much more of a better model right so it's it's the best trained model at the moment but the point is is it works it actually works right and you can prove it by logging it out on the server and see what for yourself what it's calling but this actually works you can change model and it works okay so that's beautiful everything looks great um for some reason the color I'm not sure why that keeps happening yeah I guess it's just whenever I save it it's hot reloading it in but that will be in the final build in that color right so that's really beautiful guys who's enjoying this so far right so I think at that point we've actually completed everything that we needed so we have the ability to create new chats we have the ability to go back to the main screen we have the ability to go ahead and put these in SWR someone asking is a way of fetching um it's dat of fetching react hes for data fetching but by the guys of reversal so I recommend you read this and have a look for yourself right so in this case that's great right so somebody says don't understand why there around Avatar that's my log out button Liz is asking so I I was lazy all right that's the truth that's just a logout button if I click it you see I log out yeah that's that's that was me being lazy um now we've got the deployment right deployment to Vel and then we're going to go ahead and map it to our own custom domain name that's what I'm talking about right so now I'm going to go ahead and do sun s so I'm going log into my account and we should see all of the chats I previously had so look loading chats bam just like that we have it and if I was in my other account the other one you'll see that there won't be any chats right so if we go ahead and log into that one so let's log into Papa react and then we're going to deploy it yeah just what I'm talking about we're going to deploy it to Vel all right so op. team look at that loading chats oh there's no chat right so we've got a new chat let's go ahead and click new chat now we're in the our chat and let's go ahead and type in hello world and then let's see if it comes back back with something and notice how we're completely different so these chats are the ones that are inside of Papa react with his image and all that kind of stuff and then in the other account we've got the messages from the other one so you can see it actually works right so I'm going to show you how to deploy let's go guys right so now what I want to do is I'm going to make this super easy for you right so firstly click into your environment local file I'm going to hide it for a second okay so I want to I want you to click into it and I'm going to do the following so I'm going to just hide a key here here and hide a key here just for a second right so once you're in here what I you to do is control and C command C right so I want you to grab this and command C right now you don't actually need the next URL right so this one you can actually probably leave it uses the when you deploy to V you can basically copy everything else right copy it all and obviously have your keys in here right so I'm going to go ahead and put the keys back and I'm going to copy it okay so copy everything uh and yep so we're going to copy it all and now what I'm going to do is I'm going to close it okay so I'm going to copy everything and then I'm going to close it okay so copy everything close it and now what we're going to do is command J and you're going to type in you need to make sure you've installed the Vel CLI so I'm going to do it through the CLI and I have a whole video explaining how to deploy from the CLI right so in this case all you need to do is install it so you can do it with any of these I've already done this command so I don't need to do it and then you can type in Vel and if you aren't logged in it will go ahead and log you in right go ahead and type in Vel if you're not logged in at this point you'll prompt you to log in otherwise it will say set up and deploy so we're going to click on yes and then we're going to say which scope and in this case I'm logged into Sunny s you're going to hit enter link to an existing project enter for no what's your project name I'm going to hit enter for the default in which which directory is your code located this one okay and then it's going to upload the code now what you'll find is this actually want to modify the settings so we say no I deploy right so this will obviously break the reason why this will break is because um we don't actually have environment variables set up here so I'm going to click into inspect on the link it gives me and then it will take me I need to log in and it will take me here at this point I go to chat GPT messenger YouTube I go to settings and I go to my environment variables okay and what's so amazing right about this is that you probably didn't know this right I saw it from Le Robins one of his uh Twitter Fe feeds if you have watched this well done dude that's awesome feature and thank you for sharing it you just go ahead and contrl V you paste so if I go ahead and paste right now boom look at that that's so sick so I go ahead and I do it no environments created okay so I made a mistake here oops um environment rils okay let's do it again oh yeah here so production preview development save there we go and now I've gone ahead and created it I know I just exposed it it's fine it's the end of video right so in this case boom you do that and then what I'm going to do so now we've gone ahead and and deployed these and so now we've got the correct keys so I go into my code and I simply go ahead and do Vel d-r so I'm going to do another deployments but to production right so now we're almost there guys almost there right we're going to have another issue that's going to pop up we're going to fix that and this is going to be related to more so um the Google Authentication being allowed to we need to whitelist it but after that's done that's pretty much it guys so I need to go ahead and just double check this so let's go ahead and do this so so you can see I've got a domain name here so I'm going to copy that just for now visit right and now you can see if I go to this URL sign in to use chat gbt if I click it we should get a I probably get an error now yeah there you are so see error details we have the redirect URI you want to copy this URI remember if you once you buy your domain name you're also going to need to repeat this step but you're going to copy that now you're going to go over to your uh Google Cloud so Google Cloud console okay so I'm going to go over to my Google Cloud credentials so I'm going to go over to my Google Cloud I'm going to log into my correct account and I'm going to go into my API credentials okay so here so now I'm going to go into my chat GPT messenger go into my o or2 client credentials and then I'm going to go ahead and P firstly pop in the redirect URI and secondly I'm going to add in this so the first part of the URL so you need to repeat this if you deploy and change your domain name right then we go ahead and click on save so uh this one get rid of that sorry and then save and now let's go to our deployed URL so let's go to our Vel app sign in to use chat GPT boom look at that oh my days then we go to Sun s and then hopefully hopefully it works on the back end let's see so I see all my chats and let's go ahead and say hello um explain what explain the meaning of life enter right and then we see chat G is thinking firstly it posted it which is good let's see if the Firebase admin key actually that it worked it worked amazing amazing and I actually didn't even test that before I went live right so that was actually I I didn't know if it was going to work live in stream right now I'm I'm not going to lie I thought I might run into issue but that is so cool deployed and live all right so I'll show you how to do that as well cuz I'm going to do it right now so to basically invalidate it all you have to do is generate a new key and then you basically okay so that's a bit exposed but that's fine and then I just go ahead and revoke the o key and just like that now you'll see the old one will stop working so if I want to go ahead and typed in hello world now that API key this one will post but it will say chat GPT is thinking and then it will basically yeah so console oh I mean maybe it takes time I guess to to carry on um okay I mean anyway that's how you do it right we went ahead and built out a fully functional chat GPT clone right so this was a fully functional chat GPT clone it had Google authentication you get authenticated with next off it went ahead loaded in your chat and then you can go you've got the ability to go ahead and you know speak with chat GPT it had all of the amazing things like this right so in this case we've got all this good beautiful things going on we've got our you know our API working over here in this case I've got a little bug there I'm sure we'll figure that one out yeah you can go ahead and debug it all that good stuff you can goad and delete different chats it's absolutely incredible what you can do right let's talk about some of the tech we learned right we learned we we obviously learned more about our reactjs skills we learned about about react Firebase Firebase is fire store we use Firebase admin SDK we use the open AI API right open AI API right we use next or with Google authentication we learned more about typescript we use the react select Library we use Dynamic paging use SWR we did Firebase Rea react Firebase Hooks and we did react hot toils notifications I'm probably missing so much as well right and we also learn all about the next js13 folder structure server components client components how you use it all together it was an absolute incredible build I hope you enjoyed it and we're done with our first AI app you just built the chat GPT messenger app you can now go ahead and add that to your digital portfolio and show it off to the rest of the world now remember guys if you want access to the code or you got stuck at any point in time you can simply go ahead and check out the link in the description to get access to the GitHub repo where you'll find the code for this build will be stored and of course if you got stuck and you want to level up your skill set even further then definitely check out our course and Community 0 To fullstack Hero it's the first link in the description you will not regret it now moving on to our second build of the AI crash course we have the DI 2 image generator app built with Microsoft Azure services so in this app we're going to be using nextjs 13 which of course will increase your reactjs skills as nextjs is a react framework we're going to be implementing the chat GPT API inside of the build as well as introducing the Del 2 image API so that way we can generate images on demand using open ai's AI service and to support all of this functionality we teamed up with the guys over Microsoft to bring you an amazing build today powered by Microsoft Azure in particular we're going to be covering the Microsoft Azure Cloud functions and the storage blob service so that way you'll be able to understand how to store those images securely on an Azure service and how to go ahead and leverage Cloud functions to help you do just that we're going to keep the code robust with typescript we're going to style it to make it beautiful with Tailwind enjoy the build guys let's jump into it check it out Boom the papa Farm AI image generator a fully responsive gorgeous build like look at the state of this build I absolutely love it I'm proud of it look at this this is all made with nextjs 13.2 typescript Microsoft aure we've got two Microsoft Services here we've got Microsoft Azure and we got Microsoft storage containers we got d 2 producing these beautiful images and we even have the ability for chat GPT to think of suggestions for us guys yes we are going to make chat GPT think of amazing suggestions let's try out right now let's give it a real demo right as you can see let's create a modern abstract 4K painting of a butterfly with vibrant colors I'm going to use that suggestion right now you can go ahead and create it's creating it for us we've got this nice little popup we've got the ability to refresh images Watch What Happens automatically that refresh is going to trigger Trier the image is going to get developed and just in a second d 2 will produce us a unique one-of-a-kind piece of art on the screen it's always a nice surprise as well look at that I mean wow that's created by AI guys so this is open AI d 2 we're using chat GPT to power our suggestions and you can feel free to of course write whever you want and look at that I've even made it pop the suggestion down here when you type in there so it's beautiful this application we're using CSS grid to power it all up oh it's just it's so good it's so so good let's go ahead and take a look we even have lazy loading guys so this is absolutely incredible so let's break down the tech stack that we have right here okay so this build consists of the following guys we've got react right we have typescript let me go ahead and just get rid of this screen for a second we've got typescript we've also got things like nextjs but we're not using just normal nextjs we're using nextjs 13.2 yes we're using the brand new routers inside of nextjs 13.2 we're also powering up the image functionality with Del 2 yes guys you heard it right Del 2 and we're using chat GPT to go ahead and generate the suggestions so we have loads of stuff to look forward to right and we also got things like Vel we're going to be using um typescript to make sure our code is robust we've got tailn CSS to make it completely responsive and most importantly none of this would be possible without Microsoft right so we have Microsoft Azure and this is essentially Cloud function fun right so we've got Cloud functions which are going to execute our code and they scale extremely well and you get free $200 worth of credit just for signing up so it's bloody amazing right so you got Microsoft as your and we're going to use as a storage service so these two services are going to power up everything you see here so it's absolutely an incredible Tech stack that we're covering today okay now let's dive into the back end let's see for ourselves what's running we have Microsoft aure don't worry if this looks scary I'm going to make it seem so easy and you're going to be able to follow along just right next to me okay we're going to be using our functions so this will allow us to have essentially Cloud functions which run in the cloud which essentially just endpoints that we can go ahead and say generate my image go ahead and give me all the images all of that stuff happens with Microsoft's your and it's so easy to set up and they've got such a nice integration with VSS code because Microsoft own vs code so a lot of fun stuff happening today and storage account is going to be used for storing all of the images that you see inside of this build and just generally guys I'm so proud of this app right look at this it works perfectly on a phone it works perfectly on a tablet and then as you just scale up you just get this beautiful responsive design and I think this is something that you should all aim towards in regards to just impressing somebody with a build like it should look beautiful okay so before we get started you can go ahead and install the Azure functions core tools so you can go ahead and head over to the website I'll show you everything that you need to do but we are going to use Homebrew to install it so you can simply run this command if you've got home R if you haven't just simply Google how to install the Azure function core tools it's very easy to do so right and then you can go ahead and get set up with that but it's it's pretty simple I'm going to show you how we do it okay let's go ahead and dive into this build we're going to get started off why with a template so head over to TN css.com and we're going to create our first project so we're going to go ahead and start things off by running this command if your MPX does not work all you have to do is install the node tool right so you just have to go in Google node and just install node okay then you get MPX so that's basically node package execute all right so in this case we're going to run this and this sets up a nextjs project with Tailwind CSS a starter kit right and then we're going to go ahead and sort of fast forward everything after that so we're going to open up our terminal right I like to do things inside of a nice directory you don't have to it's completely fine I put everything inside of documents builds so it's just a cleaner and then I'm going to go ahead and paste in that command now I'm not going to hit enter I'm going to change this and I'm going to give this a title we're going to call it AI image generator and in fact I didn't actually give you guys a chance to do something why don't you give me a prompt so I have an idea think of a prompt for a piece of art and I will put it inside right now and show you that it works while we run this command Okay so we're going to create the app AI image generator and we're going to go ahead and say Microsoft build okay so AI image generator with Microsoft and hit enter so this will go ahead and start up our template right so our nextjs starter template and it does it with nextjs 13 however the code is originally set in nextjs 12 and I'll show you how to migrate at 213 now if you do want an indepth breakdown of how to transition over I've done so many coaching calls in our community Z full stack hero and I've also dropped YouTube video all right so with that said we've now created our AI repository so in this case we can go into that so we can say CD I'm going to say AI image and then oops and then generate a Microsoft okay and then what I want you to do is type in code Dot and if you don't have the code dot command once vs code opens I'll show you how to get that code. command so you want to go ahead and actually okay that what is that that did not do what I wanted it to do um let's close that let's double check I want to check if there's anything in there okay so we don't actually that didn't do what I wanted it to do so I'm going to go out of that and run my command again let's do that one more time guys let's create the app and let's call a AI image generator okay let's run this again it did not seem to actually create my um my app okay so in this case I actually might need to update my no we don't have to do that create AI image next just interesting okay in this case we're going to have to set up the old fashioned way which is fine a little bit of a headache but that's okay happens I guess they've pushed a weird update then so if I go into my AI image generator or already started debugging okay yeah so that's not setting up my project so if you run into this issue it's completely fine so we're going to I'm going to show you the raw way of doing it right so nextjs I'm going to show you from scratch how you can go ahead and do it if we want to get started we click on getting started and then you can see it down here now we are going to go ahead and set up with the latest right and we are going to be using typescript so we're going to go ahead and copy this command create next app and here we're going to do the same thing so create next app with typescript hit enter and it's going to go ahead and say are you okay to proceed we're going to say yes we are fine to proceed what is your project name so now I'm going to say AI generate AI image generator YouTube Right build okay I'm just going to name it that for now would you like to use es Lin yes would you like to use Source directory um did I use a source directory I believe I did not let me just double check I did not use a source directory in this one so we're going to say no would you like to use the experimental app directory in this case yes I do want to use it okay import Alias would you like to configure this just hit enter for now that's fine and then we're going to go ahead this actually is pretty handy um so this will install the dependencies get everything set up okay so don't freak out sometimes things don't work like look we've just started the stream our template didn't work it was working yesterday it's fine we just figure out the next way to do it okay this happens all the time when you're coding trust me it happens to me a gazillion times a day don't freak out you're fine do CD after that's done AI image generator so image generator D YouTube bu whatever you've called it you need to do that and then if I do LS there you go I've got stuff inside now so if I do code Dot and I start things up you should see the following there we go guys that's more like it now we've started in the correct in the correct way so I'm going to update later that's fine now what you can see here is we have the new app directory with a bunch of things already inside right we've got some CSS modules and that kind of good stuff but we're not going to be using that so I'm going to show you how to add tailn CSS manually into your application so now what we're going to do is go back into what I previously said if you to the install Tailwind now in this case if you did the starter project and it worked great you can go ahead and carry on if you if it didn't work for you then you have to go ahead and install the following right so in this case we are using Yar oh no we're using mpm here so we're going to stick on the track of using mpm and uh if you're using nextjs 10 or newer we need this so in this case I'm going to copy this command okay I'm simply going to go inside command J I'm going to make my screen a little bit bigger so you guys can see what's going on a bit easier and I'm going to go into my terminal so output and you see we have the terminal on the left right so here let's close these there you go and now what I'm going to do is mpm or install dasd means only a developer dependency okay then we're going to go ahead and hit enter this will install all of the tail in set up for us okay so very simple we're going pretty fast and straightforward with it now at this point while that's installing after that what we're going to do is is we're going to go ahead and do MPX Tailwind init DP and this will set up Tailwind config and a post CSS config file for us okay so let's go ahead and do this so in this case now I'm going to go ahead and paste in the next command MPX Tailwind in it- p and then what this will do is it will create us our new files there you go right so now what I need you to do is go into your Tailwind config okay so once you have your Tailwind config up on the screen which is like so I now want you to go ahead and you have everything looking like this so it's pretty empty at the moment right what I want you to do is go ahead and pop in the following okay so inside of the content I need you to go ahead and add the two following lines and what this will do is it will compile anything or search for Tailwind uh utility classes inside of components folder and inside of the app foldo any file inside with the following extensions it will go ahead and do that for us okay so simply hit save and then you're good to go on that front now the next thing I want to do is I'm going to go ahead and just double check in my postcss config this should be empty at the moment we don't need anything there okay now the final step that we need to go ahead and figure out is we need to have a Global's CSS file so in this case I'm going to go ahead and create a folder called Styles and inside of my stars I'm going to say globals do CSS right now inside of here all you want to do three simple lines to import all of the CSS based things that we're going to need Tailwind based Tailwind components and Tailwind utilities go ahead and hit save and then you simply close it right easy as done head over to the app foldo this is using next Shar 13 because we see the app folder if you see a Pages folder then you're likely using nextjs 12 or you could be using nextjs 13 except they just have a migrated over to the app folder you can have actually both at the same time and shift over in an iterative manner right so in this case we're going to our app folder and firstly before we do anything further I need you to go ahead and firstly let's just double check if we got any more setting in this case we've already done that as much as we wanted yeah you see there's also the lines over there that will tell you here we are yeah so it says to include Tailwind all that kind of good stuff now I'll show you a nicer way of doing this because I don't like doing it that way I like doing it this way yeah so now what I need you to do is go over to your layout right this is where things start off and this is using nexts 13.2 because we have the new SEO meta data right so at this point we're going to start our application so heading over to your terminal I need you to go ahead and type in mpm runev now I've already got an app running so I'm going to quickly cancel my app that is running on the other screen and in fact what I'm going to do before that is I'm actually going to go ahead and screenshot so that way I don't lose all of my stuff that I've got going on right here so I'm going to keep this as a reference screenshot so that way we can begin to build out the application as we need to and I won't lose that if I need it later on okay so give me two seconds I'm just going to put that over to the side so that way we have something to look at after afterwards cool so now that that's done what I'm going to do is head back over to my code and what I want you to do is if you have multiple or you have a single screen create make your workspace easier right have your code in one side and just shift between the two it's a lot more efficient to do it that way now mpm run Dev and but I need to do is cancel my old app there we go to cancel it mpm runev what this will do is it will start your app on server 3,000 you might get this popup just click allow that allows you to have typescript reading in your app and then what going to do is head over to our code and I'm going to refresh at 3,000 what you should see now is a starter template there you go nextjs 13 beautiful looking starter template right so what I want to do is kind of get rid of this and make it my own Fresh Start so we're going to go ahead and where we have our layout function layout file and it's importing from global. CSS first thing I'm going to do is where is globals at the highest level is here right I'm going to get rid of their globals right so not my one my one's in Styles I'm going to to get rid of theirs then I'm going to get rid of page. module. CSS I don't want their Styles I just want my own which is using tailwind and as you can see at the top here I'm going to get rid of everything I'm going to get rid of all of the stuff inside a page and inside of uh the main block I'm going to go all the way down I'm simply going to remove it all right and here I'm just going to type in something like H1 hello world right and as you can see we've got a class name here just get rid of it right so this is should be your page. TSX file very simple and straightforward and what you you see is you might get an error just simply hit the refresh but the error is actually coming from layout. TSX right now where we're importing from global. CSS instead we need to import from a level up so in this case we're going to say import from a level up and we're going to say globals oops I'm sorry Styles global. CSS right simply hit save and now what we can see is we have a Hello World where our Tailwind CSS is working so I've simply zoomed in here to show you that and what we can do to test it is go to page. TSX and simply type in class name and do something like a text red 500 to test if our TN CSS is working or not okay and if it goes red hey we're good right so this is a good starting point for us now if you want all of these nice little kind of popups or Auto completion options all you have to do guys is go over to your extensions and install the following and while we're at I'm going to make you install a bunch of extensions because you need them for today right so a few things that I want you to install firstly tail in CSS simply go to Tailwind CSS intellisense install this this is going to help us out it's got the intellisense auto complete options when we're using our utility classes next thing I want you to do is type in Azure okay this is Microsoft Azure now what I want you to do is install the Azure tools I need you to then go ahead and install I've actually installed the app service it's up to you if you want to do that Azure storage you're going to need okay and then you also need to go ahead and install the Azure functions and you can feel free to install the extra things like the account databases they have honestly so many it's really really cool and they even have the Azure CLI tools if you want to do everything by the CLI but I'm going to show you how we can do it through the extensions on vs code it's a really nice integration right so after those have been installed we are at our starting point right so now using our reference let's start building out our application so if we look at our application I'm going to go ahead and make this a little bit smaller so here we can see our reference image so as you can see from this reference image we can go ahead and take a look at this and we have firstly starting off with a nice sort of top section so I'm going to go ahead and start annotating this so we want to build out this section first okay so this is our header section so let's go ahead and start off with that so first thing I want you to do is go into your page and in fact we're actually going to be building this using the new layout. TSX file sort of structure okay so the layout is where everything it can be sort of separated in terms of you you can have your visual component components at a higher level and then have your page contents at a lower level right so I'm going to show you how we can break all of this down so at the layout level we inside of the body what I want you to do is very simply go ahead and type in um here we're going to type in the header so I like to sort of common things out as we do it right and then we're eventually going to have something called The Prompt input right so this is going to be responsible eventually for this portion here okay oh this song's a banger I'm going to keep this up all right so we have the promp input afterwards so we have the header at the top and then we have the prompt input at the bottom okay and then this would be the actual page content where we render out the images so fairly straightforward we're componen tizing everything right smash the Thumbs Up Button if you like me showing things more visually I'll keep on doing that right so in this case hit save and now I want to go ahead and build out my header component right so first things first I'm going to go into my app and at the package Json level I'm going to create a new folder and I'm going to call it components right so components folder and inside of the components folder I'm going to create a header. TSX now with the header. TSX I'm going to type in RFC I've got a nice little snippits tool if you don't have that little ability that I just did there all you have to do is simply go here and type in es and you should get a nice little es7 Snippets pop up you want to go ahead and install this you know it's the right one because it's 7.8 million downloads right so in this case really awesome uh tool so make sure you go ahead and install that is for to get those Snippets I just showed you okay so go ahead and you don't need this anymore at the top and this is going to be our header so first things first I want to get this shown on the screen so we don't need that there we can go to layout and I'm going to go ahead and type in header okay and I'm simply going to go ahead and close it off and if you see what we can do is we can add components do header now the reason why we've got this at is because it's automatically set up aliases for us so this automatically goes to the top level now how do we do that right this was actually inside of it wasn't the nextjs config it was in where did they do the Ales completely forgotten it where we put it but I think it was in was it typescript config yeah it was here so in the typescript config if you want to have a shortcut to get to your top level you can actually do aliases so whenever we at for SL anything right or you can have as many different ones you can have components at for SL and so forth and then this will go ahead and direct us to this level right so that way you don't have all these nested things it's really nice actually and you can see my intell actually picked up on it cool so good stuff let's go ahead and see if that Rend up so on here now you can see I've got the header and hello world and again remember I am Zoomed In which is why it's big but on your screen it'll be relatively small I'm just doing that so you can see on the screen what you're seeing okay now first things first let's go into header so at this point I want to change this to header to get syntactically a bit more correct and then I'm going to go ahead and begin things off so the header first things first let's have a div and we're going to have two sides of our header right so you can see on the header we've got the left side so this left hand side and then we've got the right hand side so you can see we've got the first div on the left and the right div on and the right div so this means we've got two divs and then we simply use flex box to justify the space between them okay so let's go ahead and do that right now so inside of here we're going to have our left div and then we're going to have our right div okay it's very easy then inside of here we're going to have our first div and this one's going to consist of an image and then some text so the image being this image and then we're going to have some text right so I'm going to firstly show you how we do this so I'm going to import the image from nextjs image component we're going to fill that out in just a second then underneath that I'm going to have another div and inside there I'm going to have H1 and an H2 the H1 is simply going to have the papam AI image generator where I span a style in okay so I'm going to go ahead and pop this in like so and this is simply going to be a H1 with the following inside and it just means that it colors only the AI because I'm spanning only the utility classes around that portion now for the h 2 I'm going to go ahead and just simply say powered by Del at 2 and chat GPT right so powered by and in fact it's even got more c tech than that so let's go ahead and include that and Ms so Microsoft as right so Microsoft aure so we've even got Microsoft aure in this so there's a lot of power behind this and I'm going to go ahead and start this and say that this text should be extra small and this text should be bold right very straightforward now now for this image we're going to give it a few things firstly I've made life easy for you I've actually shortened a bunch of URLs such as the open AI um logo so you can go ahead and use these for reference and remember if they do ever stop working simply replace it with a URL that works it's not very difficult right so in this case we're just going to give the old text of logo because now that's mandatory as well as a height of 30 and a width of 30 so that nextjs can do its optimizations correctly on its side right so that's great right now you can see we've got the images up and then you can see now if we go over here we will get an error so if I go back here and I refresh my page we will get an error because what we now need to do is whitelist this domain basically when we pass in images into the nextjs image component what we find is that we actually need to tell it that these domains that you're pulling the images from are safe if you do not do that then what you're going to do is you're going to be optimizing all these images and xgs don't want you to do that so they don't let you do that because somebody could easily misuse that and then you're actually using a lot of resources because images are heavy okay so in order to do this what we do is we go to next config and it's very simple right underneath the experimental feature all we simply do is type in images and then we added object and we say domains and now instead of this URL we pop in links. rea.com or whatever domain you actually pop in yourself they in fact to give you the host name there so you can actually save yourself a little bit of headache hit save and now what you'll find is if you open up your uh terminal with command J you change the next JS config you have to restart your server so command contrl + C and then we need to go ahead and run our mpm run Dev again that means what we did is we changed the configuration then we restarted our server so that way used the new configuration okay so simply uh simply put so in this case now we can go back to our app hit the refresh button and we should actually see an image so let's go ahead and see hey look at that we got the nice little image at the top so let's go ahead and lay this out in a bit of a nicer way so for that div what I want to do is actually lay it out so remember if you give a div a flex boox rule so Flex in this case first if you want to know what that translates to Simply hover over it that intell a sense from that extension that we installed earlier will give you the CSS it translates to we're going to say space between Space X of two if you by the way if you give it Flex by default the children go into a line so they're in a flex row okay and then if you want change you do Flex column so in this case I say items should be centrally aligned as well so hit save and as as you can see it just simply pops in and in fact what I'm going to do is because I want you to see this as I actually code it I'm going to pop this on the side like so cuz I know you guys like it when I do this kind of thing right so let's go ahead and pop that in and that's a lot cleaner as well to go ahead and read so now for the right hand side what we're going to do is we're going to say we have a div and here we're going to have a link and these are going to be two links okay so the first link is going to have join zero to full stack hero and the second one is going to have the GitHub repo okay so let's go ahead and pop those in and in fact what I will do is I'll pop this over here for reference okay I can't right now so I'm being super lazy and I'm going to do something super super lazy okay cuz my screen oh God damn okay we can't do that that's fine I'll keep it all right so at this point we're going to have our div and we're going to have a link tag so you can see install importing it from next link and then this is a uh this takes a child which is the text and the text here would be join zero to full stack hero remember if if you want to learn how to code and you're sort of nervous in the industry or even if you're confident you can join us over at 024 stacko and get your coding skills up to Elite levels and land your stream jobs right so go ahead and feel free to join us so this is the link that I'm going to pop in there feel free to check out right you can add this you can obviously if you're going to make this for your own kind of uh website you can actually have your own links right so feel free to change up however you want and you can see we've got our nice little link and then the second link afterwards is going to be for the GitHub repo which I've actually made it very easy for you to access this will take you to the uh Microsoft page now you can see GitHub repo and join a zero to full stack hero now you can see the two children are actually not stacked up properly whereas we want it to be on the form of their next to each other so what we have to do is set Flex to the header and then we have to justify space between and we'll get that appropriate outcome okay so let's do that exact thing that I just said on the uh build right now so let's go over to our header and we simply go ahead and say oops not that definitely don't do that we're going to say class name and we're going to say flex and immediately they go into a row that's a lot better and then we say uh I want to give padding of five cuz I don't like it touching the sides justify the space between them so use up the space between yourselves I want to make this a sticky header so that way it sticks to the top as I scroll down so it's got this nice kind of floating effect we say top is going to be zero the background is going to be white so that way when it's floating down above over the images we can see it Z50 means it's going to be layered at the top so that way it's not kind of buried behind images as we scroll down and I'm going to give it a shadow medium to go ahead and have a nice little drop shadow effect and as you can see we get this although this side right now is not being behaving with the space okay so now what we need to do is just make it a little bit more clean in terms of its space usage so let's go over to our second div over here simply go ahead and add in the following Flex right so that way it puts it into a row then I want it to be text to be extra small as we get to a medium size screen I want the text to return to a base size okay so as you can see on a small screen cuz remember it's mobile first which means all of our rules are applied first then you hit these break points and you say if we hit that size screen then apply the following star okay so if I go ahead and increase this you see it gets bigger after we hit the medium break point that's awesome that's exactly what we wanted Okay so we've got that down and then we want to go ahead and add in a nice little trick here what we can say is we can say divide X and what this does is it adds a little line between it which is really clean right then we can say items it should be in the center and once you learn how to use flexbox correctly it just does all the hard work for you right and then what we say is text Gray of 500 I want it to be a nice little gray tone and look at that just like that beautiful looking header already built so so easy to go ahead and do that with the correct foundations right so check this out very clean at this point we've got the header done so win right next thing we need to do is go to our layout and we're going to add start adding in the prompt input now this is probably the most crucial part of the build right so from this prompt we're going to have a few different features and it's also going to be fully responsive to move around so that way it looks nice on a phone as well and what we're going to do here is we got the input this is a text area box and then we're going to go ahead and click on generate and it will generate the image to come down here this is using CSS grid by the way okay and we're also going to have these two IM two buttons here one of them is going to be for using chat GPT to create a new configuration and this one will be to actually use the suggestion that it goes ahead and gives us to generate the art that we see over here okay so very very clean stuff right so let's go ahead and build that area right now so we're going to create the prompt input right now so let's go ahead and create that right now so we we can get rid of our little uh our little edit there and here I'm going to create a component called prompt input and obviously it's not created yet so it's going to error out we're going to go into our components folder create it so prompt input. TSX boom there we have it and then RFC to create a functional component get rid of the top and simply we're going to go to our layout and fix this by doing control spacebar import and as you can see we've imported it like so right and you can really keep things quite neat as you can see we got that new Alias thing which looks really clean and a lot of good stuff right so now we're inside the prompt so first thing I want to do is actually just get the UI down Okay so we've got our div and the and I want to have it inside of a form so firstly we say form and get of the action cuz we're not using PHP right and then we say a text area is the first thing we're going to have and we don't need all of these things right now you can say columns rows that if you want I'm not going to bother with that right now um the text area is going to be there it's going to be a self-closing component hit save and you can start to see like look we've got a text box there right it's a nice little text area cool and then I'm going to have a button saying um generate right so we're going to have a button saying generate another button which is going to say use suggestion so this one's going to say use suggestion right so now and then afterwards we're going to say U new suggestion right so new suggestion okay let's go ah and check this up now once that's done all we need to do is start styling it okay so we're going to give it a margin of 10 so at the top here we simply say my computer's being a little bit slow so it's going to say margin of 10 so there we go we got a nice little margin of 10 at the top and then for the form itself I'm going to give a bunch of styling so we're going to say it's a flex box right so you see how they all went in line and then but by default on a phone so on a smaller screen we want to be in a column so you see right now so right now imagine it's like that right so by default on a phone that's a lot easier to actually use we only want it to change to a um a row when we go onto a uh a larger screen so once we get to a large screen you see how it goes into a row okay so that's how we do that and then what I need to do is I'm going to say shadow uh is going to be medium I'm going to give it a color so you can actually give nice colors I think it was since version three innd and what we can do is we can say forward slash to reduce the opacity of that shadow then we give it a border as well so let's go ahead and hit save and look at that oh it's looking clean we say rounded medium and then we say on only on the large screens do we give that nice little divide X line okay so now as you can see if we go on to a big screen it adds in this divide X line but on the smaller screen we don't have a divide X line so really clean okay really really clean now for the text area I'm simply going to go ahead and say that that should dominate the space so we're going to give that a roll of Flex one so because it's in a form it's a flex we can say the text area should be dominant should take up the majority of the room give it a padding of four the outline should be none okay and then round the corners out so rounded medium so at this point now you can see like it takes up the majority of the space and as you can see we're slowly getting closer and closer to our end design now for the button we're going to go ahead and say class name and for this button I'm going to do the following so this button I actually want it to be grayed out if it's the disabled but we haven't actually done that yet so I'm actually going to go ahead and hold the design here for that one before we do that I'm going to do the other two buttons okay so here I'm going to say the class name should be and then just to save us a little bit of time I'm going to go ahead and pop in the following right so I'm going to go ahead and pop in the following rules for this and this just gives it a padding of four background of uh Violet text white transition only on the color so as it changes color and the duration for the transition bold it and when it's disabled it will apply the foll rules okay so just in the essence of time I want to save a little bit of things you guys can feel free to pause and check that out same for this button we've got a bunch of styling for it so I'm going to go ahead and do the exact same thing a little bit of a different color Choice here we can go ahead and pop it in and as you can see we've got our nice beautiful colors look at that already looking very clean right now for the um the generate button what I want to do is firstly that's the dominant button right so what I'm going to do here say that that is actually type submit so when we're inside of a form we have to allocate one button type of submit and for the other buttons so the other two these I'm just going to give them a type of a button so that means that it's not the submit button because what can happen sometimes if you click that button it behaves as if you're submitting it and that's not what we want right so now you can see if we hit generate it refreshes but if I hit these two buttons nothing happens that's because we've eliminated that as the submit button now to make it a little bit easier to see what's happening now I want to give the text area a placeholder so here we'll see placeholder enter a prompt so look at that it's almost there it's almost looking great right so firstly at the top of the prompt input now when we're using nextjs 13 by default everything in a component and app folder is now a server component server components cannot have things like click handlers and interactive or state because they're rendered on the server which means they don't have a window to attach to right which means it doesn't make sense to have a click Handler on a server side component so what you have to do is make your components at a more granular level as a good practice make those only client components I'll show you how to do it it's very easy in this case I'm going to make the prompt input a client component so all I do is I simply go to the top and I say use client and this allows me to use things like state it allows me to use things like click handlers so I'm going to have a piece of State here and I'm going to call it input so I'm going to say input set input and then we're going to import our U state from react right now this input I'm going to map it to our text area so the value here is input and I'm going to say when I type in and change something it's going to set the input to the value that I type in make sure when you type in now it's actually typing in if it's not typing in you made a mistake with that steper I just did now I have the state captured in a piece of state so once we've got that done we can now use the input to conditionally render certain Styles so what do I mean by this well the generator button should be grayed out if you haven't typed in or it should be disabled if you haven't typed in so let's go ahead and do that right now firstly what we do is we go down to the button generate and I'm going to disable so let go and say disabled if there is no input great right and then I'm going to give it a class name so a class name and then chat GPT is being so aggressive not chat GPT my co-pilot and then what I'm going to do here is actually put in back ticks and back ticks allow me to have string interpolation for my utility classes right so I'm going to go ahead and type in the following I'm going to say padding of four is always applied right but if we have an input so if you've typed in then what we can do is apply the following Styles else we should apply these Styles so if it's true we have an input then apply those otherwise it will apply these so the first set of stars that we're going to apply are the following so you can just go ahead and pop in these values as well so it's going to be the certain colors and then if it's not true so after the colon then it's going to be text Gray and it's going to have a cursor of not allowed right and then before all of this either way it's going to be font board okay so now you can see look it's grayed out and I've got a cursor not allow but the minute I type in O that's clean that is clean right look at that you can't deny it guys this is dope all right look at that that's just beautiful the colors everything oh just nice make it whatever colors you want but this is a nice sort of starting point okay so this is a great little uh prompt that we've generated so far now we also are going to go forward and create the input down here so we we haven't added in suggestions yet until we start using chat GPT and bear in mind this will also use use SWR in this build so I'm going to show you caching tricks and how you can go ahead and generate things in a more efficient way so we have the following now is the exciting part right so now what we're going to do is actually go ahead and set up our Microsoft Azure services and our chat GPT keys and everything that we're going to need to connect to the open AI API so open AI is the company that is responsible for things like d 2 the image generator and for chat GPT the sort of text model that we're going to be talking to and getting suggestions from okay so first things first let's head over to open Ai and I just type in developer portal whatever you want to do honestly just go through that website click in a sign up or wherever it is uh and then you need to log into to your account okay so go past your security checks everything you need to do and then log into your correct account so at this point you just need to sign in so I'm going to sign in with Google so I'm clicking continue with Google I'm logging in to my account right now and then you can see you'll reach this right so now you're in the AI open AI screen you just need one key and one organization key to go ahead and connect to open AI Services right so what we need to do is go to popam physical click on view API keys and here you have your stuff right so you want to go to your uh create new secret key and also in settings you can see your organ organization ID so also you want to copy this right so first things first copy this value and we're going to use this in our local environment file so I want you to go into your folders right close all your stuff go into package.json and then create a new file at the high level here we're going to say mv. local this is responsible for our environment files right so at this point what I now need you to do is type in open oops open AI organization right so open or AI organization and this one I'm simply going to go ahead and pop in the ID that I just showed you okay now the good thing about this is that this by default is only readable on the server unless I add in next public in front of it at that point it's available for client components but at the moment it shouldn't be right it should just be sort of as secure as it can be until I need that access the next one is open AI key okay so this one now the open a key this one you should keep very careful and secret okay because otherwise everyone can use your key and build up your account so what we're going to do here I'm going to click on create new secret key so I'm clicking on that button right now and what has happened is it's popped up and it said API key generated I'm not showing you this because you're going to find my key otherwise okay so I'm copied that key and now I click okay and as you can see I've actually copied the key and you can see it's generated a secret key right now it's hidden the value and you can actually revoke the key if you ever find it's misused or anything like that so once you've copied that value head over here paste it paste it save the file and then close it okay so I'm going to go ahead and paste it save the file it should begin with SK like secret key Dash and then a long squiggly bunch of mess and then you want to close that file now we have our environment file correctly set up so this means we've got the keys that we need in order to go ahead and do the rest of the things that we're actually going to go ahead for and set up okay so at this point now I need to use or set up for open AI so what I need to do is actually install open AI onto the machine so I'm going to press command J head over here and right now I've got my app running right but what I can do is I can simply create another terminal or you can split terminal because I'm doing one screen I'm just going to go ahead and do it like this I'm going to say mpm I open AI okay so all you need to do is install open AI onto your machine very quick Done Right easy as now what I want you to do next is create a at the package Json level so I always refer to it at this level because it's a top level okay and then I'm going to go ahead and create a new file so we're going to go ahead and create something called open ai. TS and this is going to be like our setup file it's going to be following a Singleton pattern so we're going to create an instant or connection to open a services and then we're going to repeatedly use that to go ahead and talk back and forth to open AI this is both for uh chat GPT and for Del because they're both created under open AI okay that's why we only need that one key to do so so first thing I need you to do is import the correct dependencies so we need the configuration and the open AI API next up we need to go ahead and create a new configuration and the first thing we need to do is go ahead and pop in the organization and API key okay so organization and we're going to use those values that that we set up just now so this actually goes into our environment file so process. M do whatever we've named it so make sure this matches up to the file that we used earlier so the M file okay so once we've done that we now create a open AI instance like so and this will go ahead and this object can be used to basically go ahead and communicate back and forth with open AI so once that's done we simply say export default open AI now just like we've done in the past with any of our other apps right like we don't we usually do this with like Firebase or other things in this case we can go ahead and do the same pattern as we do as we like to do so right so that's simplified things we can figure about that now the next thing we need to do is actually create a API m point this API end point is what we're actually going to be pinging against so in nextjs we can actually have API end points in nextjs 13.2 we have these new root. TS files which is awesome right it's super clean and you've got a seamless integration between your a API endpoints and your uh your client and server component so it's all like on the same level now which is incredible and we can go ahead and get rid of the pages photo finally right so inside of the app photo we can go ahead and create inside you see we've got this API and you can see hello and root. TS and this is the new structure and as you can see it follows a very similar approach to express whereby we say get post you know all the kind of standard rest API things that we're going to go ahead and need but in this case you can see what it's done here is it's created an endpoint at/ Aiello and it supports get request and if you don't believe me I will show you right now that that is the case so if you go to local for/ API for/ hello you will see that actually has a working endpoint so this is a full API integration right and it works with the new um sort of syntax from nextjs 13.2 so at this point now what we're going to do is create an API inpo for it's going to make life a bit easier it's going to be used for generating suggestions okay so the suggestions are going to be for how we're going to go ahead and basically get a suggestion now what we're going to do is we're going to have an API Point here for getting a suggestion so I'm going to in I'm going to click on API I'm going to create a new folder and I'm going to call it suggestion okay now inside of suggestion I'm going to create a file called root. TS okay and from our example before you can simply copy that if you want to use it as a starter template and paste it in if you want okay now I'm going to delete that old hello folder cuz we don't need that route okay don't get confused as well that that is inside of there so API for/ suggestion now we've got the that route as a fully functional thing okay so the next thing we're going to need to do is we're going to go ahead and set up what we need essentially to go ahead and eventually now we're going to use our API so imagine our app is going to communicate to our API and then our API is going to go ahead and make a request to an Azure function which is going to then be responsible for essentially going ahead and doing the chat GPT the open AI the DI stuff and then it returns to our API and returns to our app okay so that's essentially the flow that we're following in today's video so what I want you to do is go ahead and say the following so we're going to have a little bit of a Pudo code for now as well we're going to say con response equals and here we're going to say await fetch okay and here we're just going to say um dot dot dot for now okay so it's not going to work for now right so just ignore it and then we're going to do a comma and here we can actually add in caching RS as well right so we're going to say that this is going to have a caching R and we're not going to be caching right now so we're going to say no store that means every single time we make the request I want it to get a new suggestion I don't want it to use a cached previous value right now once we've created our asj endpoint so this will eventually connect to our connect to our Microsoft Azure um function endpoint okay once it's done that we're going to basically replace that there then we're going to go ahead and once the response comes back I'm going to pass the data by saying Contex text equals await response. text okay so you might be like ooh that's different because we're going to use blobs and text today so yeah we're is I knew and then eventually we're going to return the foll we're going to say Jason stringify text do Text data and then we're going to trim it as well in case it has any extra characters okay so very simple very straightforward and you can even go ahead and add in the status 200 if you want to be super explicit about it as well so you can see this is pretty awesome right now we have this so this means that firstly we need to connect to this okay so let's get that part done and then we're going to create our Microsoft aure function and we're going to create the entire flow for the suggestion then we're going to repeat this entire process to get it working for the image generation part so we have our base template for our rout so inside of our application and this also protects you against things like CES and all that kind of stuff because you're making the API request internally which then goes outbound so it's kind of a more secure way to do it we have this looking pretty decent I'm going to go into my component The Prompt input and at this point we are going to make that request I'm talking about previously okay so when I create I need a suggestion now okay so that suggestion is going to come from okay so this is where we're going to use uswr okay so firstly let's create a little uh utility Library sort of helper folder to help us out with a few things so at the package Json level I'm going to create a lib folder okay and this is basically like you know for for any kind of helper stuff and inside of my lib folder I'm going to create a uh get suggestion from a fetch suggestion from chat GPT file right so this has got a function inside of it so I'm going to create a function inside fetch suggestion from chat GPT dots okay and inside of it I'm simply going to have an arrow function it's going to have the name of that file and it's going to go ahead and do something and then it's going to export default fetch suggestion from chat GPT right so we're kind of keeping a nice clean foldo structure here now what I'm going to do here is I'm going to fetch from that URL that we just created so it's going to be 4/ API cuz it's already on our own host Network and then we're going to go ahead and say the for the second argument it's going to say cash no store because again I do not want to cach these values okay so I do not want to cash them now after that's done I want to pass the response now if you remember what we were actually doing from that uh route is we were Jason stringifying it so I want to pass it afterwards right so when it comes back to us I need to then go ahead and say res so get the response and um res. Json it okay so res. Json so we pass it right now with that done we actually have our um our bch statement now what we can do here typically you would have to store this in a variable and return it but you don't even need to do that if you actually know what you're doing with es6 functions so if we only have one line of code in this case this can be considered one line of code because it's one chained command we can actually get rid of the curly braces and we can get rid of this and essentially what we're doing is we're putting it inside of a parentheses which means return okay but we don't need the parenthesis and now what you can see is what we have here is a implicit return so this is implicitly returning when we call this so it's fetching it's returning a promise so you can see it's returning a promise okay so this will return the suggestion so now this will connect to our API great stuff so we've got our helper function down and now what we're going to do is create the actual functionality on this side so instead of doing it the normal you know create a piece of State have a maybe a use fact that kind of thing I'm going to be using use SWR because it's a great way to do things in the fetching and caching space so in order to get this right what I want you to do is head over to let me go ahead and just pop this over here for now head over to the following and type in use S SWR now on the uswr website you'll see react hooks for data fetching now bear in mind these need to be working on client components because they require State okay so in order to get this started we're going to click on get started and we're going to use mpm we're going to install it so mpm I SW R okay so head over to your app command J to pull up your terminal and I need you to go ahead and do mpmi SWR so we've done this now so mpm I SWR and then what I want you to do is you can check this out but essentially you have this pattern where you have a fetcher which we've already created right we've already created the fetch suggestion from chat GPT Helper and then we're just going to integrate it like so and what's really good about this is you can see it gives you a few different options when you do this you basically are fetching the stuff and you're adding it to account cached value so in this case this could be whatever key you want and it caches it then it will give you the data and it also give you a loading so while it's fetching it you'll have a parameter to go ahead and check again so am I loading the data yet was there an error you know that kind of stuff which is really really handy okay so now what I can do is I can go ahead and say const and I can say data error is loading so basically the line that we saw previously and then I can say use S SWR s SWR okay and then I can pop in the following so here what we have is you can have you firstly this is a key value this could be ABC it does not matter it doesn't even need to be 4/ but what we tend to do is set the key to be something like 4/ API 4/ suggestion so that way you directly know that it's the cach key value for that API core okay and then we're going to go ahead and say fetch fetch suggestion from chat GPT right now after this I want you to go ahead and uh first we need to import this from use SWR so we stop getting the error so let's go ahead and do that right now and then after that the third argument I need you to do is type in revalidate on Focus false if we do have if we don't do this what happens is every time we click back onto the screen after we focus out it's actually going to trigger that call again because it's like you left the screen now you've come back and I need to refresh the information so we're explicitly telling it no no no you don't need to refresh the information you're good don't stress right so that's why we're actually going to go ahead and do that way so now this will go ahead and fetch here for the data and it will probably error out because um remember we we don't actually have our Zer function up yet so it's kind of pointing to that like dot dot dot which doesn't do anything okay so at this point we are going to um have the data being uh called so in this case where was it uh we're going to rename the data to suggestion so let's go here rename it to suggestion cuz that's going to be the suggestion that comes back and then we've got his loading and then you can also have a few other things but for this build I don't need the error itself I just need his loading and you also get another one called um is a mutate and you get is validating is validating is when we're actually sort of refreshing the cache just is validating it seeing if it's expired or not and mutate is when you want to go ahead and manually call it yourself so that way it goes ahead and actually manually calls this again and it's really handy because you can do optimistic updates and things like that so I'll explain what all that is in a second as well now at this point we've got this in so what I want you to do is um we're actually going to go ahead and I think I think really what we should do here is create the endpoint because we're kind of at a Hal because it's not going to be calling anything so right now just for context this is calling our API suggestion endpoint this then makes a request to a non-existent Microsoft as function endpoint which we are going to create right now okay so let's let's go ahead and do that so this brings us to Microsoft Azure hey all right so Microsoft Azure is a huge Suite of tools right they have everything that you can possibly think of in the tech space they have a service for it including a new open AI um uh aure function which I was really eager to use but you actually need a wait list for it so I'm working with the team right now to get on that weight list so that way I can build a video to show you it right but in the meantime I created a function myself that does the exact same thing okay so I'm going to show you how we do it so first things first I need you to go ahead and create an account at Azure so I've got actually a nice little link to show you so first if you head over to the following right now so if I show you this right here so if you head over to aure as your. microsoft.com you'll get to this point in building in the cloud and there your free account now it is free to create this right so don't stress you don't need any major money or anything like that and remember you get 12 months worth of free access to the most popular 55 services or something right so if you click on this you actually get access to all of these things so so you get access to all these services so I think it's 1 2 3 4 5 6 and even always free for these things as well so it's absolutely amazing right um now once that's done you actually also get $200 worth of free credit so it's a huge amount of credit to actually do the coding that we're going to do and I always get a push back from this so all you need to do is start sign up right so sign up connect your account do all of that kind of stuff so once you're done with that all right so after that you're going to sign in okay so I've already done this right and again if don't freak out if it starts asking you know you need to give in your details and that kind of thing it's Microsoft it's safe right trust me I've done it myself I've create an account so in this case once you have the account you'll reach this screen okay now this screen can be a little bit scary if you're not used to this so don't stress I'm going to break it down as well well what I want you to do is firstly go ahead and you can see we've got different Services the ones that we're going to be interested in is the function app the function app is going to be for cloud functions right so right now I have the test app which is the one that I just built previously to demonstrate the storage accounts is to store all of the images from our art gallery so everything you see that here that's being stored is going to be inside ofo storage accounts and they're stored as blobs right so these are all just blobs being stored on Microsoft and it's great for storing multimedia files images videos anything like that it's a really awesome way to do it okay and then we've got the Azure function which is going to handle all of our communication and it remember it scales amazingly it's Microsoft right it's going to work so what I'm going to do is I'm going to show you how we can actually set this up from our code itself right so yes I said that our code itself so what I've actually done here is simplified the steps to do all of this stuff what we do is we're basically going to go ahead and close everything here and at the package Json level I'm going to create a new folder called Azure okay now inside of azure what we're going to do is you see it's an empty folder okay so I've installed the Azure function uh extension right so make sure you've got this function uh extension so Azure function now once you've got this you can do really cool things such as you firstly you can see all of your stuff over here so all of your resources you can access your subscription and see all of your different things like your function your storage accounts everything all from a vs code which is actually really powerful right so I can see all of the deployed functions I can see my containers all that kind of stuff yeah and don't worry it's just cuz it's something new it can be a bit scary but I promise you it's really really powerful okay so at this point I want you to go ahead and do command shift p and type in AER and type in create a function right so create function and you can see here create function app right so the first thing we want to do is create a function app in aure so click on create function and then we need to create a name for our new function app so here what I'm going to type in and you can see it's one of three steps so I'm going to type in the foll say Microsoft I'm say Microsoft um AI let's just type in AI image generator so AI image generator YouTube app okay and I think I'm not allowed these characters to be honest with you right so I think I maybe let's just try it let's do AI image generator YouTube app okay so that makes it very easy for you guys click enter and you can see select a runtime stack so in this case you can see I used uh nodejs 18 right so I'm going to be using nodejs 18 but you can see they also support Python and all that good stuff as well so I'm going to go back to that previous step I'm going to type in nodejs l uh this one here so I'm going to go down to nodejs hit enter right then select the location for where you want to deploy it so they have lots of different locations I'm simply going to do the US Fel right so as you can see it's creating a function app right so this is very simple to do so this creates the function app on the back end right and if you hav't logged in it would have prompted you to log in and so forth okay so you would have had to log in at that point if you haven't already now what it's doing is it's creating a function app for us so if inside of here what we'll find if we hit refresh shortly this will be created and as you can see we've got the Azure activity log and this will go ahead and do it for us okay so this is what I really like about this extension is that you can actually do it all from VSS code which is very refreshing because you never have to leave they done a really nice integration with all of that stuff okay so um as you can see it's at step five of six so it's almost done let's see if we refresh now is it there not yet okay it will be there in a second create new function app there it is 6 out of six give it a second and it will go ahead and create the function now the function app think of it as like the house for your Cloud functions right so that one function app can have several different endpoints in once we've gone ahead and get everything set up right okay so there you go we've created the function app so let's go back here and click on the re refresh button so I think here let's go over here and um I'm in my correct account and I'm just going to click on function app um we should see it let's go over here actually and just see maybe I'm in the wrong application on being something silly let's go down to Azure and I can see function app and as you can see AI image generator app so maybe it's just not propagating here there you go okay so just need took a took a second to refresh and you can see this is the one I had previously this is the new one that where we're starting everything off so if I click into it you can see I've got really a huge amount of control over this entire Cloud function and it can be scary but don't worry it's actually really awesome to have this amount of power behind it right so from here I'm going to make it easy don't worry it's actually a lot simpler than you think so we've got our function app created so I'm going to go ahead and type in command shift p and then I'm going to type in asure create fun function app you see we got create function app in asure create function all this kind of stuff so now what I want to do is go ahead and create a function itself okay so now what I do is I go to uh create function and as you can see I've got this so create new project select a folder that will function that will contain your function project so I'm going to click on browse and then what I want you to do is Click into a Zer right so click into a Zer and simply click select right so that means we're basically putting the entire function code into asure which is Nita I like that I prefer that okay now with that done we are going to choose our language so I'm I'm pretty sure I did typescript yeah I did do I did JavaScript okay but you can actually do whatever you want in this case fine for now for the demo sake I'm going to do JavaScript but you can do typescript c python anything that you want so JavaScript for the essentially think of this as your backend round you can have a separate project for this even but I'm just doing in one place so JavaScript and we're going to use mod V4 right so we're using the latest and greatest like I always be daring a bit right now how do you run your Cloud function there's loads of ways right I want a endpoint that eventually I can just call and it can be a get request post request anything like that and you've also got all these other things like timers event grids all this incredible stuff even if you have a blob storage trigger which means when I add data to my storage containers it will trigger the function so you can do lots of stuff but in this case I'm just simply going to do HTTP trigger and we need to give it a name and here I'm going to do is I'm going to say the first one is going to be get chat GPT suggestion. JS okay we don't need yes as well get chat GPT suggestion okay hit enter and this will go ahead and create us a new project so now if you have I open up my Azure you can see we've got our own G ignore we've got our node modules inside of there so essentially we've got another W inside okay and as you can see we've got our source code and if I click into that you can see oh this song is a bang right and as you can see we've got the uh all the code to get things up and running so you got app. HTTP and then it's got the um get chat GPT suggestion which is working perfect and then you can say is it a get post is it a delete put update all that kind of stuff in this case it's just a get request we've got all level Anonymous but this can actually be like you can have a a special admin only can you know access this we're going to do Anonymous all right because Anonymous is basically we want to allow anyone who comes onto the website to just get a chat GPT suggestion right and then we can basically do all of our cool clever stuff here so let's click on Save and now we've got everything looking pretty decent and uh I want to run this locally right so how do I get this up and running firstly you want to code it locally and then you want to deploy it and then you want to change your URLs and all that good stuff okay so now what I'm going to do is inside of my output over here so remember the first terminal is running my app okay the second terminal is going to CD into Azure so now I'm in my Azure folder now in side of here what I can do is but as long as I've got the azer um functions core CLI tools and installed so these are the these are the tools that you're going to need at this point work with the Azure functions core CLI tools right so all you need to do is go down to your operating system so if your windows Mac and so forth and then simply install it so I've already installed this and I've actually ran these commands right so in this case now I can run things like Azure commands in my terminal so if you don't have that or you want to make life a little bit easier you go to package Json and you can see it start okay so very simple now here you can see if we're using package lock so we're using mpm so I can simply write an mpm Run start or mpm start even works and what this will do guys is it will say Port 7 okay so I've actually got this running already on another app so I need to cut that up and let's do it again so mpm Run start and as you can see as your function core tools right and error has occurred unable to resolve stor connection um name storage okay so we need to create a storage uh container as well so let's go over here and let's just double check our setup firstly so we actually need to set up our storage container as well which I actually forgot about um so let's go over here let's go to our function and I want to go to home and I'm going to create a new resource now in fact I think we can even do this from the uh from this side so if we type in aure storage I believe it was so attach storage account create blob container create storage account um we're going to create a storage account okay create storage account and then here I'm going to create my storage account now here we're going to type in like AI um image generator oh we can only contain those okay AI um AI let's just call it AI image lowercase letters and numbers okay so let's just call it a uh image oh my God image generator just to make it easy Right image generator storage okay and then we're going to hit on enter and then you can see where do we want to put it East USS is fine so this is creating a storage account for us and this will be responsible for having all of our storage for our application okay so heading over back to our application now if we go to our function app right here so you can see recent uh you can actually start playing around with a lot of this stuff and go down and you know do all your kind of things and bits bobs um I want to go to I forgot what it was now okay so let's go back let's just wait until it's done and I'll show you how we do it there we go so let that do its thing so it's creating the final account cool then what I want to do is command shift p and I'm going to say aure storage and then we're going to say attach storage account right so which no we don't need to attach it sorry my bad so let's try and do our deployment again so let's try and run this again I think we may be missing something very minor here but let's do it again and um I think it's because actually what I've done here so we've got this re blah blah let's actually get rid of this and let's go ahead and just say hello world hit save and let's run it again mpm Run start okay so con okay where have I got my AO storage let me just see one second host uh extension blah blah blah and we've got this in fact one thing I need to check as well that I'm using the correct version of node so here actually you want to type in MVM so you need to install something called MVM um which is your node version manager so I recommend everyone gets this even when for your production side of things or for you know whatever you're doing but MVM allows us to dynamically switch between node versioning systems so we remember we set this up with uh node version 18 so check out this documentation install it update it that kind of thing you can simply run this command and it'll work for you I'm going to just go over here and I'm going to type in NVM LS and it will tell me what you see you see I'm on the wrong version of node I need to be on version 18 and it's per terminal as well okay so I'm going to type in MVM and I if you don't have it you can just say install 18 and then once you've done that you say use 18 so now I'm now using you'll see in a second it will say you're using now using node version so there we go MVM LS you see now I'm using version 18 okay so let's try and do it again mpm Run start and I think it might still crash out here yeah okay so that's fine can know provider okay that's oh I think it's actually I think I know what I've done wrong um let me just double check something quickly so I've actually messed up here so my azour web job storage yeah so this is actually where I've done silly mistake um I've not got any of my settings I actually need here which is probably the problem that I'm doing so let's go back over so now we're doing a debugging I like this bit okay so we're going to go to uh I believe it was I don't a s mistake previously let's go to my home let's go ahead and just re I just want to see my storage accounts I did have a AI image generator storage there we go it was for the res it was we actually already created one yeah let's see then we've got our image generator YouTube and then we've got functions where is it functions so previously in my old app it was um actually here I'll tell you what we're going to do I'm actually going to check out the documentation myself because I'm a little bit confused so I've actually created it already local functions we've already done uh let's go ahead and do the actual um so I'm using Microsoft Azure storage container right and let's just check out get started and do it ourselves together right so a your blob storage here you go yeah so quick start into this um we've already done this tutorials we've already done this I just need to connect it and I've completely forgotten how I done it so no JS let's see for ourselves right so I've kind of done a same mistake here I've already done my storage count containers all right so in my notes I actually had this quite neatly done um but I've made a Sil mistake so let's go back to our Microsoft so here this case we've got our storage function up which is great okay so let's just see all quickly I just want to see everything that I did last time so I have my test app I have my generator app and then previously I had the test app as well what's happened here that I think the problem is that you can see I've got my storage app and then I've got my it should have been connected to be honest with you I think there just have been a bit of a silly okay so there's a little trick you can do to pull your settings so you can go ahead and type in aure um pull oh settings sorry settings uh download remote settings app service it was download remote settings for functions let's download the remote settings for our functions and then what you'll find is you can get these ones right so Sunny test app or AI image generator so we're going to do AI image generator and this should download some settings for us so let it do it thing oh it's because I didn't run it as well of course right so in this case that will take a second so do you want it override your yes and there you go okay so stupid mistake on my end right uh you actually have to pull it in okay so my mistake right I completely made a silly mistake there so so command P command shift p you just have to click on as your download remote settings because otherwise what you're trying to do is you're emulating without the correct saying to connect to your backend right which which makes no sense so now what I'm going to do is mpm run start and we should be able to get past that little hurdle that we were on right remember you should be on MVM uh your your node version 18 and then what we should see if everything's gone well we should see a this should start up there we go that's what I wanted to see right after all this you can go ahead and see we've it's running it right now at Local Host 771 uh there we go we click on this and what we will find is what I'm going to do I'm going going to simplify this and show you myself CU it open in the completely different screen um we're going to go over to our new new um page and then we pop in you see Hello World so now you can see we've got an the same thing as what we had before except it's literally running on the cloud right but this is emulating it locally so now we can develop locally and then basically do what we need to do so this is perfect this is what I wanted right so what I'm now going to do is have my app we can close that close that we've got the app and then we've got this Endo running over here so you can see Local Host 7071 so this is great so what now I'm going to do is I have my endpoint so if we go over over to my uh app API route okay and then here what I'm now going to do is basically pop in this so now it's going to make a request to this back end right now what you can do as well is you can say if the environment is a Dev environment do your Local Host otherwise do your production URLs for today's build for Simplicity I'm just going to replace the URLs but that is something that you would do in production you would just say if the environment is you know Dev or production then use this URL otherwise use your local Dev URL it's very easy to do that okay so we've got this down and you can see that this is my logs for running so if we were to go ahead and go full screen you can see if I was to Simply say going back to the function if I type in um hey like hello and hit save what you'll see here is it's going to restart my function over there down here so my running function if I refresh it you'll see we see uh it should see execute function hello HTP this is not my logs uh okay so go back to my Azure let me cut this so contrl + C uh cut that off and then go ahead and do mpm Run start and I'll show you a few little tricks here so let's let that run and you can see we've got the mend point if I refresh you can see it says hello and then you've got your output okay so that's great so at this point now we can start coding out that back in at this point we have our we remember we created that connection to open AI right so what we're going to do is we're going to use that same connection to open AI now so because we're using a and we're using a bit of a backend environment we haven't got our import export statements we're instead using traditional required statements so in this case this will go towards my oops we need to go to the lib open AI folder so in this case I'm going to go upper file upper file in fact I need to go up another file and in this case I'm going to go to my lib for/ fetch suggestion from chat GPT this gives me my open AI um um you know what I need to connect to chat GPT and now I'm going to go ahead and say const response so this is the magic part this is basically where I'm going to go ahead and communicate and send a prompt to chat gbt in the form of like give me a suggestion to create a piece of art for Del so that way it generates it and I'm going to say like you know make it photo realistic 4K this way you can have some real fun right so we're going to get con response equals await and then we're going to say open AI do create completion okay and then I'm going to pop in Brackets like so and then here what I do is I pass in a model first right so model and here we have lots of different models right so but I'm going to use the text Da Vinci text D vinci3 so this is the latest sort of chat GPT 3 or 3.5 string right so in this case I'm not sure which one is so now what we do is we go to the prompt so this the exciting part we go to the prompt and then here I say you know what do you want your prompt to be so I've actually created made a nice long prompt that you can feel free to go ahead and copy right so we're not going to use this as a test prompt we're going to go and say write a random prompt for Del to generate an image this prompt will be shown to the user including details such as the genre and what type of painting it should be options can include oil painting water color photo realistic blah blah blah do not wrap the answering quotes full stop right because sometimes it was giving me an answer back and it always had these quotes which was a bit annoying the next thing I want say is give it a Max tokens so we're going to give it a Max tokens of 100 100 right so that means it's going to return an answer of Max like kind of 100 tokens and then the temperature is essentially how random or focused you want it to be so this has to be a number between 0 and two if it's like 0.2 it's likely to give you the same answer every single time if you did something like two it's a lot more random but it's also not focused so a nice balanced middle ground for me is 0.8 and that's going to give us a really nice answer okay then what I'm going to do is we go ahead and we get back right so we get the um so I'm going to log out something like a function saying you reach the end of this thing blah blah blah and then what I'm going to say is get the response text back and I'm going to return it in the body so now wait for it guys response text comes back and this is where we are basically get the text from this is what chat GPT will return and we're just saying it's going to return one answer back so you can actually give it an N value I think it was um and that will give you basically the number of time like the number of options it should return and instead of just hello world here I'm simply going to return the response text okay so let's go ahead and rather than hello world now what we should see if it goes ahead and actually does this again so we need to kind of refresh usually when I'm not on the stream it rebuilds it so if it doesn't do that just simply cut the terminal mpm Run start again okay or you can actually do function um F5 and if we do that it will attach a debug and it's pretty cool actually right so in this case cannot find the module fetch suggestions from chat GPT that's fine that's because I've not basically okay so my import statement is bugged so let me figure out what I've done here wrong so Source functions and then I've made a silly mistake here um because in my app I have not I've done it a little bit different um so we've got a z I'm just going to double check everything now so we've got a we've got our source we've got our functions we've got F get chat gbt so in this case I'm going upper level upper level so I think I've gone too far up to be honest with you I think it should have been there yeah so that makes a little bit more sense actually cuz it's going uper level upper level and then we're in the lib folder okay so let's see mpm Run start and let's see if we get that now okay so um we start another issue so functions JS cannot find module fetch suggestion from chat GPT oh no okay oh my god I've done a silly thing no okay guys I'm so sorry I done such a stupid mistake right so inside of azour all right I've gone out of my actual azour folder which you shouldn't do right so I've completely mixed up my context here so inside of aure we're going to create a folder called lib so we're going to have a lib inside of aure and then here we're going to have an open Ai and open a open ai. sjs sorry and inside of here we're going to have the exact same thing that we did previously except for um it's going to be module exports instead of export default okay that is what you needed to do so I'm I apologize that was my mistake right now the environment variables in this uh basically remember think of azure as a separate app right so you can actually have it in a separate repo if you want but the environment variables for this are actually inside of local settings. Json so here okay so what I want you to do here is actually go ahead and add them in here instead so we're going to add in open AI organization and I'm going to add in the following so I've already got my uh organization key so I'm going to get it from my environment file down here so where I have environment. loal I'm going to click it now and I'm what I'm doing is I'm copying my organization key going back to my local settings and I'm pasting it in as a quote and then I'm doing the same thing for the open AI key okay so what I'm going to do here is basically have the open AI key so let's go ahead and pop it in um open a key these are the environment files for um uh what's it called for Azure okay so now I'm going to go ahead and go into my environment local file on my other one so I'm going to do it just so you guys are explicitly clear I'm going to go to my environment local for at the top level click it and then I'm grabbing my secret key the sk1 and I'm going back to my local settings Jason and I'm pasting it okay so I'm going to paste that in here so now I've got my secret key in there and my local settings. Jason so that's good right that's great now what we need to do is remember that's local okay that's locally happening but what we really needed to do now was actually make it um so firstly let's cut this let's go to chat GPT suggestion and then first let's just double check that we're actually getting from where we wanted to get now so inside of open AI um oh my God I made such a stupid mistake earlier wow that is so bad right so here right so here I'm going to do dot dot for SL dot dot for/ lib for slop AI there we go all right so do not do what I just did that's very silly uh and then we hit save and now we have our environment files so we should be good to go so let's go and do mpm run stock and this will go ahead and hopefully we get past this little issue we were having and there you go okay so let's give it a try now let's going to go to that endpoint and we should see a prompt oh okay we got we got an error so what's the error let's have a let's chase the eras down until we get the correct response so we can see response failure um exception fail 429 so I got rate limited I believe oh no I actually hit the the the quota limit on my my open AI account too many requests okay so I've basically got rate limited from chat GPT okay which is is fine for now what I can do is because I think what I did is okay so I'm going to swap the keys and the organization to have my other account so my Sunny Sanger account instead because I think my papa react account is is got half a million views and half a million people are going on that I think I've leaked my key somewhere so I'm changing out my open AI key you don't need to do this cuz yours will be absolutely fine so now I've hidden everything that I needed to do and we're good okay so I've swapped it out and I'm going to close this out and then let's try it again so this one shouldn't get rate limited so mpm run stop if it is you can just have another account and yeah check it if it does get Rel limited it's because people yeah somehow got access to it I can refresh and let's see if we get it yay there we go guys look at that paint a modern abstract oil painting of a tree with vibrant colors and a cloudy Sky if I hit refresh again I'll get a different suggestion create a photorealistic oil painting of a futuristic cityscape with a Twilight so you can feel free to make your prompt whatever you want and it's going to go ahead and create it so that is using chat GPT to go ahead and do that now which is awesome and you can see it's returning from that API which means we can build the rest of the front end um for the suggestion and then from there it's relatively quick guys there there is then we're going to move okay so at this point now we've got the the Azure function up and running right so we're going to deploy this afterwards I'll show you how we do a deployments after but for now we go back to prompt input and this one is already making a request on our front end so make sure you don't get confused here inside of app API now we've got this API endpoint so get chat GPT suggestion and then remember from our component uh we are using uswr to make a call to our own local API right uh so now we've this is going to go ahead and pull the data in so this will pull a suggestion in which should work so the way that we can test this is we just simply console log the the suggestion inside of our app okay and what I want you to do here is go over to your app and simply open up your inspector so open up your inspector console log and then refresh and see what we see so in this case you can see undefined I ignore this this is actually for my uh I've got extension working right now so that's fine but here that's my Dev tools react Dev tools kind of breaks a few things for some reason but here you can see that it comes back create a mod an abstract thing if I refresh now we can see it will come back after a second create a 4K abstract model U modern oil painting awesome so it's working it's pulling in what we needed which is bloody amazing right so now I can proceed to build everything all right so now we're going to go ahead and actually have a submit uh oh no we're going to have a um we're going to fetch the suggestion right so we're going to show the suggestion here so where we have the placeholder what I'm going to do is I'm going to have a curly brackets and I'm going to say if we have the suggestion use that or use enter a prompt okay so now look create an abstract four piece look at that oh that's nice right look at that so if we refresh you'll get a different one create an OD abstract pointing oh there we go that's clean right that's really nice okay so that's looking good and then what I can also do is I can say if it's loading right and what we're doing is we're actually going to use two different things so is loading is validating or called it separate points is loading is called initially when the um this call is being made so this one remember that's the that's the key cash value yeah the name the key for the cashing purposes right so in this case that could be ABC for example right if it's loading from the beginning that's going to be that if we mutate orever it's going to Val validate so basically what we're going to say loading is determined by is loading or is validating if any of those are true it's going to go ahead and do it right so what we can do here is basically say for the placeholder if you're loading then we're going to say something along the lines of so I want to get rid of that sorry we going to say if if it's loading then it'll show that or it will basically jump to suggestion or it'll say enter a prompt right but here I'm going to say chat GPT is thinking of a suggestion dot dot dot okay so now look at that chat GPT is thinking of a suggestion bam hit refresh Chachi is thinking of a suggestion create a black oh that's just clean all right so nice and it's communicating through our own API with nextjs 13.2 then to an Azure API which does all the hard work and that kind of you know connects to um uh Del and open open air chat GPT okay so now we're going to implement new suggestion and use suggestion right or new suggestion first so firstly new suggestion is fairly easy we just need to go ahead and say call mutate mutate basically means generate a new suggestion or basically mutate means basically execute that again right so if I do attach this to the new suggestion so we say onclick mutate now watch this if I click here so let that do it thing load if I click new suggestion bam just like that look at that giant robotic dog was last one black and white picture blah blah blah next one abstract rainbow over it next one oh it's just so clean so so clean we've done our suggestion point now we need to do generate and use suggestion so that actually comes forward when we do the generate image portion of the build okay but what we actually want to do is if I type in here I want the suggestion to show up underneath right so this is actually fairly cool like a nice little cool trick so underneath the form I can say if the person's already typed in so if there's input then I should generate something here and what I want to do is I want to have a P tag and I want to say suggestion and I basically want to Span in a few things so I'm just going to save a bit of time here by popping in the following so I'm basically spanning in a violet bit of text and then it says if it's loading chat toing otherwise show suggestion so you see this if I do this but if I get rid of it you see how it's there but the minute the user types in you still see the suggestion because that's really handy right you might not want to lose the suggestion like inv visibility so that's great so that's a nice little cool trick if you want to do that so then we say italic panning on the top of two paning on the left of two and I want the font to be light so it's like super crisp right and if I type in you see that suggestion stz 4K abstract it's just so nice I really like it yeah so look at that awesome so now let's get on to the interesting part let's do the generation portion okay so let's actually be have the ability to generate an image and then actually go ahead and create an image with d 2 and then we're going to upload it to uh Microsoft the the the sort of blob containers so storage containers and then what that means is that we're storing our images using Microsoft storage Service uh in the form of blobs right so we're just basically storing all of our images there and then we're going to be able to pull those images down on the front end and visualize it okay and when we use uswr we can do lots of neat little tricks to actually make this happen in a really cool manner okay so next step I want you to do is go ahead and we're going to create new endpoints and we might actually just create all the end points now to make our life a little bit easier so I want you to open up your API and right now we already have the API suggestion route so make sure you click on API right so you're at that level click new folder so here we're going to say get images that's going to be one route and inside of that it's going to have root. TS and then we're going to have another one so I'm going to click on API again new for folder called generate image right and that's going to have a root. TS in front side of it as well so that way we' got three different routes right and we're going to build these out as we need to and so forth okay so they're fairly straightforward to be honest with you so inside the generate image one we're going to go ahead and do the following so I'm going to have the same thing that I had with suggestion right so here but now we're going to have generate image and generate image is going to be a post request we're not going to support get request it's going to be a post request okay and what we're actually going to do with a post request is you have to generate something called a next response instead so for the Post request we have to import next response and we're going to change the body of this a little bit more right so firstly we have to go ahead and get the request body so when we generate an image we're going to send a prompt alongside that request so the way we get the body of the request out is we basically say await request. Json from the an original request and then we get the prompt from it right so the if we do this it basically contains the body and then you can go ahead and get the prompt out of it okay so then what we need to do then afterwards is basically figure out the next bit so here we're going to create a request so we're going to say response equals await Fetch and this is going to be a post request now so await Fetch and this is going to be to/ API SL generate image okay and this one is going to be a post request and it's going to have content type application Json because we're sending it in the form of application Json and we're going to send the body we're going to stringify the prompt alongside it okay so basically we're sending a Rest Post request to our API mm point which is going to be an Aur function and then we're sending the body in the form of adjacent object and then we're telling it by put setting the header saying you should expect this data in application Json format okay now once that comes back you know we're assuming that we're going to get some response back from this uh we don't actually do much with this response to be honest we actually just the whole purpose is that we upload the image but we're going to pass the text and we're just going to say yep just carry on by saying next response Jason text a and then it just moves forward okay so that's how we do this now we need to create the endpoint on Azure right so you can do it a few ways you can actually use the the sort of you know um what I showed you previously to actually um uh what's it called uh you can do the you can use the command shift p to create new um sort of you know functions but I'll show you an easier way right I actually found a lot easier way than doing that right you can actually just create new files and it works right so in this case we're going to create a generate image file okay so uh generate image so we're going to go ahead and do a generate image. JS file and inside of here we need to do a few different things so when we generate images on uh um uh Azure you can't just go ahead and be a random user and just say hey I want to generate an image right what you have to do is you have to there's different types of authenticating your requests to make sure that they're valid requests so that way we don't just have people just you know destroying the the back end now one way of doing this is we can use something called a SAS token and I believe it's called a shared access um service to token I think um but it's SAS token and this will allow us to have uh sort of a limited time access to an uh an object or back in service right so we're going to be able to set this up right now and I'll show you how we can do it all um so we need to make sure that we've got a few different things installed so firstly inside of package Jason you can see I don't have any much dependencies installed here I need a few dependencies first the first one I'm going to show you um actually let's just do it now let's go ahead and say and I just want to check if I actually did end up using something here that I think I used uh I don't think I used it in the end but I just want to double check something yes I did use it okay so in that case that's fine okay so I'm going to go into my um I'm going to create another terminal so I've got three terminals now one running the front end one running the back end I'm going to CD into Azure to make sure I'm in the correct directory cuz that's got its own node modules and package Json and then what I want to do is mpm install and I need to install a few different dependencies so the ones I need to install are if I go to my package Json it's going to be uh storage blob from Azure so Azure storage blob mpmi Azure storage blob and I'm also going to install axios and I'm also going to install open AI on the back end so Azure storage blob axos and open AI so we install that now let's go ahead and add these to our dependency tree and you should see that this will update so we should have the new dependencies inside inside of here so there we go we've now got our dependencies inside we can go ahead and close that off go inside of here that's good and then what I need you to do is go into your lib folder so the lib folder we're going to create a helper here which is going to allow us to generate one of those tokens I was talking about because that's very important if we don't have the ability to generate the token then we could just set it to Anonymous access but I don't want to do that I want to make it quite a nice clean approach to this right so um inside of your local settings. Json I just want to showcase something so you have something called a account name and account key or we might have account name or account key I don't think I've set it up correctly yet um I'll show you how we can get that now so the account name and account key okay I remember this one so I don't I have not forgotten all right so in this case we're going to go to our um function so where is our storage account storage accounts and then we've got two here um which one was I using so I believe the one that we need is part of the resource tube that we were using earlier so this one res newbe a showing okay anyway let's just go to image generator storage AI image oh God's sake I set up two didn't I so don't do what I do and get yourself confused but here we can check it out by saying account name is AI image and then the key is there as well so we can use that actually to do it so I believe that is the key um yes so that is the key so you've actually got the key here so everything up to the colon pass equals that's the key so we have the sort of that plus blah blah blah blah blah but I'll show you from the back end how we can get it yeah so if you go into AI image generator which is my one and then you go into your where is it gone keys key access keys I believe it was here and then you've got your key here I just want to check if that is my actual key or not because I don't know if that was the one that I used so I'm just double checking something guys so what I want you to do is click on show copy this key right so that's the key that you're going to need and that key is also here right so you can then what I want to do is I going to make life a little bit easier and I'm going to create another variable called account key and I'm going to Simply pop in my key so here I'm going to pop in a key value so I'm going to just pop in screw let's do it now cycle monkey afterwards account name is going to be um my account name so this one here and then we pop that in okay so now I've got the same thing hit re close and then what we can do is we've got the key in place so we head back over to AER we head back over to our Live library library library and we say generate SAS token do JavaScript okay now with this we're going to go ahead and actually everyone's mad focused so we've got the token there so now with this I need to go ahead and get things out so firstly I'm going to need a bunch of dependencies from uh storage right so now we're inside of our lib folder I'm going to need these then I'm going to need a few different things so I'm going to need the account name I'm going to need the account key and I'm going to need the container name right and what we can do here I believe because we can say a storage a zero storage create container so you see create blob container create storage account so I want to create a blob container so I'm going to do command shift p I just went down there create blob container and then you can see we've got all of these so the one that I'm doing is AI image generator this middle one I'm going to hit enter then we have to give it a name so here I'm going to say images is the name of my blob container this will now create me a blob container with images name and that means I can store all of my images inside of this container and I actually have a really nice diagram to show you that visualizes this right so I want to kind of uh show you this so that way it kind of helps you guys out a little bit so this one is this will actually help you out a little bit so let me see if I can get this up so it's here right so you can see this is essentially how we visualize a container so you have your account which is basically like my account that I've logged into then you've got your container so in this case we're going to have images right so this one pictures we're going to call it images then you have the blobs the blobs are all the files so this is how you essentially are going to store all of your stuff right so this is how basically we use the Microsoft uh storage service right so that's actually going ahead and I believe done that um I think that has done it create storage account uh we can actually check ourselves by going into Azure go into our container apps storage account sorry and then inside of storage accounts you go your AI image generator you've got your blob containers and we should see images here images there we go nice awesome so in this case it's empty right that's that's exactly what we wanted to see it's empty and then now what we can do is we can set up our access keys right so the first one is you need something called a shared key credential and I'm just going to go ahead and explain these as we pop them in so you use this uh instance Creator here you pass in your account name and your account key this gives us a key credential to go ahead and log into the account then we need to go ahead and create a blob service client and this allows us to connect to that blob account and what we're doing here is we use our account name this is a special URL and it's very easy right it's just your account name blob core windows.net and then you use your key credential to access it so this is basically this object allows us to go into what we need to do and access it and do what we need right and then we're going to go ahead and create the generate the generate the SAS token so here I the async function generate SAS token and from here what I'm going to do is firstly I'm going to get the container right so here we have the blob service client which connects to the actual Microsoft storage blob service right with our credentials then I need to connect to the images container so I say get container client container name is already images so basically this is now connected to my images container okay now what I need to do is generate some permissions so what I say is I'm going to create some permissions for my SAS token I'm going to give it write create and read access to be true okay so fairly straightforward yeah then I'm going to set an expiration date and I'm going to say it's only going to be valid this token for 30 minutes so what I do is I set a new date which is now and then I set the minutes to the current minutes plus 30 so that's 30 minutes from now and then what we do is we create a token from that okay so this token command I'm just going to go ahead and pop it in and show you so this is basically we generate blob SAS right and you basically pass in some query param parameters so we Bas in the container name the permissions to string and the expiry date and then we pass in the key credential so that way it allows us to or like in a secure manner generate this SAS token then we can go ahead and say return SAS token like so and then this is going to be our utility function that's basically going to be really handy when we're trying to do any interaction with our storage container so then we export it so that way we can use this nice little handy function so all the complexity is kind of stored in here in this file we do it once done right so trust me it seems long but it's not once you've done that it's actually done it's it's really not passed that all right so at that point now we go over to our uh uh generate SS token so this is our nice handy function so now we can do our cool sort of backend magic so we're going to create a we're going to pause from the generate image and we're going to create another function called generate SAS token. JS and for now I'm actually going to just temporarily delete generate image right so that way I can actually go ahead and actually work on some stuff now I'm going to do the following so where we basically had the previous same layout exact same layout but I'm going to do it for the um generate SAS token so what I'm doing here is I'm importing the app right so from as your functions I am now generating the SAS token I'm pulling in that helper function that we just created I am naming the new uh aure function generate SS token it's going to be a get function it's only going to allow get request to it the off level is anonymous which means anyone can then go ahead and create a SRS token right and obviously you can you can restrict it as much as you want and so forth but that token will only be valid for 30 minutes so it's somewhat is creating these tokens that you can then access and so forth then we're going to go ahead and say a wait generate a wait generate SS token and then it Returns the token okay so let's see what all of this actually did right so in this case if I cut my server on the Azure um and I do mpm Run start or the same command y mpm Run start and then you can see now what we should find is this will hopefully not erl and it'll give us two URLs there we go we've got the first one which was for generating or the second one generating the chat GPT suggestion and the second one for generating the SAS token so if I go over here now and I basically paste in that command what we should see is that that is a perfectly valid SAS token that's perfect you should see SV equals and then a bunch of stuff and if we refresh it we get another token and so forth that's great now we've got our SCS token we can do certain things with it okay so you can use that function whenever you need it now what I'm going to do is I'm going to go into my generate image function and now we can begin to interact with the back end in the way that we need to okay so um you can either make a call to your own as your Cloud function so that's just a very handy way of having a cloud function that can do that if you if you I think we don't even actually properly use that separate endo but it's handy to have it if you want to do that okay but in this case I'm going to go ahead and do generate image again so generate image um oops no don't do that generate image. JS make sure it's a Javascript file okay and Pat pure yes this Tech combo is crazy I I know it's crazy yeah so at this point now I'm going to do a few in uh dependency pulls right so I'm going to pull a bunch of dependencies that I need so open AI axios generate SS token and then I'm going to have the same similar constraints I had previously so I've got my uh blob service client because I'm going to have to connect to the storage service my account name and a container name okay then I'm going to do a AP app. HTTP so HTTP request generate image is the name of the cloud function that we're going to do and then you've got the actual body of the function okay now for the methods it's only going to be a post request that we're accepting okay the orth levels are going to be anonymous and then we're going to have a Handler right so in this case you got your async Handler we don't need the context object right now that's fine so how do I get the body of the hand the request coming in from the so imagine we we send a post request to the azil function how do I get it well we basically just do a wait request Jason and we destructure it from the response that comes back because this will give us the body and then we just destructure to get the body. prompt right so this gives us the prompt back then what I'm going to do is just for debugging purposes I can do something very easily just say you know the prompt is prompt so it show on the the sort of server side right the logs right so once you've got that down now what I'm going to do is I'm going to communicate to Del so the way we do this is we use the open AI instance that we previously set up and all we just do is we open a do create image and this will actually communicate to Del and it will go ahead and uh we can pass in our prompt how many images we want to create and the size of the images and then it will return us an actual IM image URL now you can use that image URL but I'm going to show you a bunch of different ways as to how you can I'm going to download the image URL that it gives us and basically store the actual image in storage in um in Microsoft aure just to demonstrate how you can actually store the images or you could if you wanted just store the text URL it's completely up to you but I want to store the actual image right because imagine for whatever reason you know the open AI Ser has went down because they're under huge demand I want to know that I've got the image on my Azure server right so we've got that so I'm going to go and say con response equals await open AI so we do do uh create image and you've got all of them look how many you've got create image you got a variations all this kind of cool stuff as well and we got the prompt so the first thing we're going to say is the prompt is going to be the prompt that we destructured from the post request the second one is n now n tells them like how many results do you want so if you want 10 images you can do 10 I only want one which is fine and then we can say size and now the size only has three options so we're going to do the biggest size to get the highest resolution possible from this okay and then what we can do is we can get the image back from the response now the image comes back in a bit of a nested fashion so it comes back from response. dat. data and then you've got you know how many responses that came back in this case we only down n equal 1 so we only have one item left in there so we do get the URL of that image and then what I want to do is I want to down unload the image but I want to tell it that the response type that it comes back with is something known as an array buffer now an array buffer is basically a way of representing an image in like a blob fashion right so in this case it's just going to be a buffer of that it comes back and it's representing your image and it's basically a PNG representation of it right so here now what we do is we say conres equals axios you can do it with a fetch but I'm just doing axios I don't think fetch was supported that's why I done it so you did axos dogap we do image URL and then response type is an array buffer okay now we can go ahead and say const array buffer equals oops array buffer equals ar. dat and this basically gives us back an image right so this is literally giv us back an image encoded in a blob format and then we can basically need to upload this now so in the array buffer we have the image we actually have downloaded the image and we've going to we've returned it as an array buffer so here I'll just add a little comment so it helps you out right so we actually get the image aray buffer has the image inside of it now what I need to do is connect to my blob instance but I'm going to use the token that we basically generate so you can make a call to your own API service or you can just use a utility service that we made previously made to generate it so SS token equals a wait generate SS token from our U so this one or you can make a request to your own as your function if you want right if you're depending on it a lot but you can do con blob service client equals and we basically what we do is we we append it on as a query program so basically you say this https so account name blob cor windows.net and then you append it as a query program so it's SAS token is basically at the end of it so that SV equals blah blah blah that is where it goes ahead and gets attached to okay so at this point blob service client is down then we're going to go ahead and get a container client so remember we've got the access to the storage we now need to get access to the container so the image container and then we generate a Tim stamp okay and a file name so in this case I'm going to give it a file name and a time stamp so what I've done here is I've done the current time so in the Unix sort of timestamp and then I've created a name which is basically the prompt underscore the timestamp and the reason why I've done this is because just from the file name later on I want to know and be able to order it on the back end when I'm fetching the images which images came first and I can use that underscore to split the string and B basically figure out the time stamp so I don't need to store unnecessary information right so once I've got the file name I basically can go ahead and get the access to I can basically so now I've gone into the Container so images then what I do is I get a blob client which basically says a block blob client so if we imagine what I showed you previously was this diagram so the first layer of access was let me just show you again because I think it's very important you understand this portion very clearly so at this point you see the first element of access so uh at the top so when we did blob service client was this one so you got access to this level then when you get the container client you get access to this level and then when you do block blob level client you get access to this level right because basically you're saying at this file name right so I hope that makes sense right so now you got the file name now once you got that we're basically going to attempt to upload it and if something goes wrong we're going to error it out and we're going to use a TR catch block to do so right so very straightforward we have a TR catch block block bu Clan upload the CL upload data array buffer file will be uploaded successfully on the um output if it's all good otherwise it will say well you made an error there was an error there right so generate image okay now we've got uh this should be up and running at this point so now what we can do is we can go ahead and we can close our ter uh our terminal aure terminal rerun it and we should see a generate image request okay we should see a generate image request now what I want you to do at this point is download a app called Postman because we want to test out our API right we actually want to go ahead and send a post request not get request a post request to our endpoint so that way we can go ahead and say this is the prompt I want you to now go ahead and do what you said you'll do and upload an image to that image container okay so first things first I want to prepare the scene I want to make sure that you guys understand that this is actually working the way that we expected to so we go to Containers we go over to our images and as you can see here I have no results which is good okay so now what I want to do is I've got my post you see these ones are get you can run get requests in the browser you need a client like Postman to run a post request so if I open up Postman you can see Postman is a free app it's amazing it's really good for all developers to get used to using app so at this point if I dismiss this yeah so that's fine I going to create a new one so new requ Quest I simply paste in the URL to generate image and then what I do is can I make this a bit bigger yeah generate image let me make it a little bit bigger we change it to a post request and these are all the different options you can have post request and then what we do is we set the body right so body we're going to do raw and uh I'm just going to say it's Jason body there we go and then we pass in the um actual body itself so where's my example sorry I think it's um was it here I think I've done so prompt and then you can do the following just say um something like let's just do a Spaceman driving or a Spaceman riding a horse on Mars right so something like that click generate image and let's see what happens so you see it sends request it's sending a request right now and as you can see look on the back end it says a prompt is a Spaceman riding a horse on Mars then what he's doing is it's generating the image and then while it's doing it all afterwards it will say um if it all is all successful say file uploaded successfully so right now this is generating through di 2 API an image for us with by providing a prompt once that is done there you go guys look file upload this successfully amazing yes you can see here we should have back in the response now a um so did we return anything back from response I don't think we did much okay anyway so at that point we generate a response so let's see Microsoft is your so let's go to to our images container refresh look at that a Spaceman riding a horse on Mars so let's open it and it says blob and we can actually go ahead and download this image so let's go ahead and download the image and see the image that we actually got so I'm going to go oh wow guys look at this oh look at that a Spaceman riding uh a horse on Mars amazing right so it actually works so that generated uh the that that we created an AER function a post request and it works right so that used the SAS token it successfully was able to uh verify that the token was valid and then it got through so you can see the authentication meod access key is what we're using right the SAS token that's damn cool right so now you can see we've got an API that does it right so now we can go ahead and connect up the front end and continue the build so now what we want to do is basically have it so when I click on generate or I click on you suggestion you you suggestion should pass this prompt to that endpoint generates should suggest whatever I've typed in here so it could be a bcde e whatever click generate and then it should go ahead and make the make this call possible so let's do that right now right so heading over to my code oh my God I'm getting so mixed up with everything so let me go ahead and minimize Postman because we don't need that right now and I'll minimize our demo as well so because we don't need that let's go so at this point we are going to go to our cover that we need to go to our front end again so heading back into our components our prompt input okay so when we go ahead and click on the use suggestion or generate button this is where we need to go ahead and make the magic happen right so prompt input for new suggestion we're going to go ahead and I'm sorry use suggestion we're going to submit a prompt right so in this case so for this one or for this one so let's do generate first so that should just be very simple we should have onclick equal was submit prompt okay so we're going to create a function here called submit prompt now um let me just go ahead oh actually what you can do is because this is a type submit button you don't even need to do that here you can actually have the form on submit that's the submit button you can have a submit prompt right you can also do that right so very straightforward um and then oh sorry handle submit so okay so yeah so this will be handle submit yeah and now what I'm going to do is create a function above it so I'm going to say const handle submit and this one will have a so every sort of a click Handler has an event right so in this case if you don't know the type definition for it nice little trick you do a little arrow here and you hover over and you can see form event HTML form event is that so I copy that pop it in there and then I can remove my handle submit and there you go just like that import the dependency and Bam I have perfect type definitions every time right so e do prevent default there we go bam and then I'm going to say await submit prompt so this one will just basically call the other function and then you can do extra stuff here if you want to I'm just making it relatively simple now submit prompt is going to be a function I'm going to create above here so it's a con submit prompt equals um uh asynchronous so it's going to be an asynchronous function and this one is also going to have a parameter that we passed through and this is going to be a conditional so it's going to say use suggest and it's an optional so we don't need to pass it in and it's a Boolean value okay so if you pass in true it will use the suggestion that was generated if you don't pass in true it will use the input that you would actually put in okay so how do we do this now remember we're disabling the buttons as well if there is no input so it will prevent you from sort of making a mistake so first thing I want to do is create a copy of the input so I say input prompt uh input prompt equals input oopss input and then what I do is I can clear the input because basically I want the users's um experience to basically be the minute they hit generate it should just do that it should clear it right I don't want to load because then what they might do is they might click click click click click click click and it's just like a bad user experience right so you want to clear it out right and you can use um console log if you want I'm not going to do that so in this case that's good and then we can go ahead and say that the um if the person has typed in so the text that we're going to send I'm just going to say call it P so the P represents the prompt right so p is the prompt to send to API right so p is the prompt to send to API then here what I'm going to say is if you passed in use suggestion then what you should do is you should say you should go ahead and use the suggestion otherwise what I want you to do is I'm going to go ahead and check um that the input prompt exists or if that doesn't exist no sorry no one minute I've completely messed things up so if your suggestion yes that's fine um otherwise it'll be input prompt or why did I add that one in suggestion okay I think that's fine for now I think that's good yeah I don't think I need the other one oh no okay actually yeah so if it's because sometimes your input prompt might not be there so in this case okay let's leave it for now if if it errors out I can figure it out so then we're going to make a request to the back end so we're going to say res this is where we make the post request to the back end we say await fetch SL API SL generate image and this is going to be a post method the headers are going to be application Json and the body is going to be stringified prompt right so it's going to be the P right then when it comes back we're going to get the data we're going to get the data as uh Json and then we're just going to Simply say if if there was an error you know you're going to we we'll handle this with the notifications afterwards okay um cool yeah so this should do it now what this is doing is firstly it's generating the um the image here so this one is going to um make a call to our own API so we need to make sure that we've actually got an API endpoint for Generate image that is created which we have yeah so now what this will actually be doing is that this post request firstly is not correct this needs to go to the actual um generate image back end that we've created so we need this one to go to our local host for now so this one here generate image there'll be no see it's not that one you want if you open up your execution so remember this one so it'll be generate image so here it'll be generate image okay so now what happens is our client makes a a request to our API in our local API which then pings our Azure function our Azure function then does its thing and then it will come back and it should work okay so let's give this a try right now and let's just see if it works right so generate um let's go over to our let me close some of these things because I've got too many things open right now so let's close this close this close this close this close this let's make it very simple for you guys to follow me so I'm going to open up my prompt input there we go and and um this is good so far yeah so I'm just checking something um so uh we've got this we got the content Jason BL blah and then um okay submit prompt there we go so at this point when we do API generate image uh it will make a request to my backend so at this point we should be fine so I'm just going to log out here saying console log uh input prompt um yeah so we should be able to see it when I submit it that way I get some feedback when I inspect so I can just know what's going on so here so this so I'm going to you click on uh draw a dinosaur in the ocean right click generate see draw a dinosaur in the ocean and then what this would have done was on the network tab this would have actually called generate an image and you can see right now is the payload was a prompt and you can see it's pending so this is actually executing right now and you can see if we were to look at the back end you can see that it just came back successfully um so uh let's go down here so file upload prompt is draw a dinosaur in the ocean file uploaded successfully so let's go ahead and head over here refresh and we should have a dinosaur in the ocean so draw a dinosaur in the ocean. PNG amazing that's what I'm talking about guys that is so so sick so now we've got that pretty good so now we've got the ability to generate images okay and what's really awesome now is that it's very easy to go ahead and where we have our use suggestion button here we just simply say onclick um submit prompt U oops submit prompt true and true would basically represent that you're using the suggestion which means it would use that suggestion output okay which is perfect so in this case now if I was to go ahead and refresh and I go ahead and click on use suggestion now so let's go ahead and do that right now so click on new suggestion what we should see is that it should say it's prompt is a modern abstract oil painting of a tiger running through a forest so we've actually gone ahead and executed the API and then in a second we should see that file uploaded successfully we've got an error here which was unexpected oh cuz we're passing some Json which wasn't which wasn't correctly handled so I need to handle that a little bit better on the front end but for now at least the back end is still pulling in the correct thing so like I'm want an abstract o there we go nice so the reason why we're getting this error let's dive into it so we've got res. Json so this is uh y so if we go over to our um API so let me just go into our API generate image rout so here we are going ahead and saying prompt response. text text Data that's fine and then inside of prompt input prompt input so prompt input where we get things back data. res. Json um that's also fine so the error must be in Azure so when we're pulling let's have a look at aw so when we're returning our text from our generate image function I believe this is probably where we're making mistakes yeah it is here so we're not returning anything from generate image at the moment in there and that's the reason why we're getting an issue yeah so here we're not returning a body so I made a mistake here so we should be returning a body and here I don't really care I don't want to return the image is too big I want to do a fetching mechanism on the front end but here we successfully upload the image that's great okay so at this point now we should not get an error because we have something to pass when it comes back okay now the final sort of Step here is generating the images then we can go ahead and do the front end for getting our nice beautiful layout done so I'm going to go ahead and firstly create a Azure function for doing so and this is going to be called get images so let's create the get images function so get images. JS as your function and now what I'm going to do is do the appropriate Imports so again very similar to what we previously did and I will show you right now so very similar Imports right so we have all of the the app which we require for any and Cloud function our credentials uh the the dependencies for credentials our SAS token helper account name account key the container name which is images the credential which uses our account name and account key again you can refactor that actually into a separate file if you want to not have repeated code like this blob service client we need over here we simply pass our account name and the credential to allow us access then we go ahead and create the actual endpoint right so in this case we say app. HTTP get images this is going to be a get method the or level will be anonymous and then we have our Handler now we do need the actual context here CU I believe we do use it and then we have our function like so okay so this one right here is what am I messing up yeah there we go there we go yep so we got the Handler here so for the Handler now I need to basically create a container client connection so that way we've got access already to the service The Blob storage service then we want to get the images container like I've said previously once we have the images container is we're going to have two things we're going to have one which is the image URLs an Mt array and we're going to have a generate an sas token so we can access our backend so what I'm essentially trying to do now is I'm trying to pull all of these right so what I'm about to do is list all of the blobs in this container so each one is a blob so you see block blob right blobs are amazing data type for storing media files like images pictures that kind of thing right so at this point we're going to go ahead and um basically make a request to all of these things and uh get those um answers back and then we're basically going to generate a list from this so I'm going to have all these file names as an end result okay so let's go ahead and do that right now so first I say four I'll show you we do four await and then we say const blob uh of we're doing a nice little Loop here we're saying container client do list blobs flat right so this returns an async inter iterable iterator list all the blobs under specified account okay this will go ahead and give me all of the blobs back right and we are waiting for each one so now now what I do with this information is I go ahead and I basically create a URL for each image so basically see I've got the blob name and the SAS token so I can access that image if I don't have the SAS token at the end of the image it's basically going to say you don't have access or permission to view these images because you weren't permitted a SAS token right or if it was after half an hour would have to generate another token so now what we do is we create a URL now this URL is perfect because that exact URL can be rendered on the front end as a image URL so then what we do is we say image URLs do push and then basically want to push the URL and the name okay so I want to go ahead and push in the image URL so now at the end of it we have all list of all the URLs but we also have the name because I want to use the name on the front end for the keys okay now what I can then do is I want to sort it because basically what we'll find will happen remember I sawed the file name underscore a Time stamp.png PNG is for the image right the extension so what we're going to now do before we return the all the list of images to the front end I'm going to basically pass those strings so what I'm going to say is the first portion of the string is the file name so I need to basically do some string manipulation and I need to go ahead and say split that string up and give me everything after the underscore okay now after the underscore I have the timestamp but I then have the amp. PNG so then I say split everything thing based on the the dot so PNG and then give me the first part right so then what I do is I basically have the only the time stamp from the file name then I do something called a sort function which I teach in zero to for stacko feel free to check it out at papa.com course and basically what you're going to do is we're going to do a simple sort function which is just going to check the first time stamp against another one and sort the entire list before we return it to the uh front end okay so now what I'm I'm going to do is I'm going to go ahead and say const sorted image URLs equals image URLs so image URLs do sort and basically what you have here is you have your A and B so a is going to be the first item in that list or as you iterate through it will be the first element from when you're doing the comparison the second one will be the second element then the third the second cycle will be the second and third third cycle be third and four and so forth right and it keep swapping them until it it sorts everything um so we're going to say const a name equals and basically remember what I said we're going to split based on all those different things and we're going to pop right so the way to the Shand that I've done here is a nice bunch of it's pretty cool right so basically what we're doing is let's imagine we had a file name called um draw draw a dinosaur right so draw a g dinosaur say that's a let's imagine that's a time stamp right so what it's doing is it's splitting at the underscore so so then I have this section and this section in an array then I'm saying pop right so pop is giving me the end result so basically giving me this so at this point after that I basically gotten rid of this bit right so up until here and then I do two strings so up until here is basically getting me this then what I do is I have dot split so dot split gives me an array where this is the first element and this is the second element and shift Returns the first element of that array so then I get this so basically now after doing that like kind of you know um that that that combination here you're basically going ahead and getting that from the the the original uh title right so then what we do is do the same with Bame name and then all we do is we return B name minus a name and it will start sorting all of those uh time stamp values right so basically now you're sorting all those image URLs by doing that that's a lovely little es6 um uh sorting function if you didn't know how to do it okay so once you've done that we basically I'm just going to add in something to say like that function was actually processed for this one blah blah blah and then I'm going to return something so now here I'm not going to do a simple return that we were doing before I'm going to say return but in the Json body I'm going to say image URLs are going to be the the key and I'm going to return the sorted image URLs okay there we go so at this point we've got our return so that's great so now I should be able to go ahead and actually access this so let's go ahead and remove that that from previously so I'm going to close this uh asure function instance and then I'm going to go ahead and say mpm Run start and that's going to go ahead and hopefully if it all works give me a URL for get images there we go get images so now if I run this this is a get request so I can actually throw this in the browser and I should get all the images back there we go guys look at that that's sick I literally got these back look nice and they've even sorted it based on the order so these are all being sorted on the back end and returned to the front end so that's awesome now now we've created our Azure endpoint okay so now we've got the Azure endpoint I now go to my front end and I go over to my app API get images rout and you can see we don't have anything here so now what I'm going to do is I'm going to create an API endpoint here for our local side and this is fairly straightforward right so we've got the simple Syntax for uh nextjs 13.2 which is basically was going to be a get request that we're supporting here we're going to go ahead and make a get the response and this is going to be an await fetch okay okay and this is going to be using uh making a call to that Endo that we just went ahead and retrieved which was this one right here so it's get images so over here yes so we're going to go ahead and fetch from there and then we're going to go ahead and say as a second argument we're not caching right so you can optimize this more and you know have caching rules and that but for now I'm making every request be dynamic so it's basically a service I render each time right but you can feel free to optimize as you wish right now remember I returned it back as Json body right so what I'm going to actually do here is return it as a blob type so this will actually give me back the blob and then what I do is I return the text back from that blob by doing blob. text and then I pass that so basically I get it back in the form of a blob so it's a lot of like you know data that comes back then I pass it then I basically say cons data equals Json do pass the text data and this will give me back a list of URLs okay so then I return it back in a stringified fashion so then I basically go ahead and stringify the data and I return it back with 200 so now I can make a request to my forward slash um API get images and then that will go ahead and actually help me out right so now I can actually go ahead and do this from my front end so let's go to um I need to create a images component so where are we going to use that I'm going to use this inside of the so where we have our page. TSX right this is where I'm essentially going to be rendering a very simple page in itself it's going to be simply here I'm going to have the main tag and this is going to have a MX margin of zero but on a zero sorry uh but on the largest medium size screen it's going to have a margin of 10 so margin of 10 actually to be honest I think for now we're good let just zero and this will render our images right I'm to create this component now so this component is going to be inside of the components foldo so here we're going to have our images. TSX RFC bam go up here get rid of that and now here is where we do some magic right so I'm going to pull in my images folder from components and we're going to go ahead and do the following so inside of my images firstly it's going to be a client component because I'm going to have a few things like use S SWR making calls here so this is going to be a used client component so it's a client component as opposed to a server side component because remember in nextjs 13 everything is a service side component until you make it a client component so I'm going to import the following and you can see I need a uh special lib helper here to fetch the images so very simply I go into my f files go into app um sorry my lib folder where is it lib on the upper level and where we have this similar structure I'm going to do essentially the same thing but basic I'm doing it for um the uh where is it going fetching images right so basically I'm going to create a new file here called Fetch images. TS and it simply is the same following protocol it just makes a fetch to get images we're not storing the cach or caching data and then it returns me a helper function so we do that then we go back to our images folder and then we can basically go ahead and successfully import that as needed so that is freaking out why um let's just double check for/ Li for/ fretch images there we go okay so now that we have our images uh folder good I've got so many files open on my screen my eyes are a bit crazy right now um I am going to basically make a pull to those images so we need to go ahead and basically set up the same thing with usw so what we do is remember you can get your you get the following from it so we say you get the data which I'm renaming as images you get the is loading State the mutate State basically just calls this again but I'm renaming it to refresh images because that makes more sense and then we've got is validating right so in this case we got fetch images being called and then what we're doing is we're caching it as images you can really cach this however you want though you could say if you really wanted to API for/ get images as the URL endpoint right but honestly that doesn't matter too much right but in this case case this just okay we'll do the API end point doesn't make a sense that doesn't make a difference and then I'm going to have a type definition for remember we stored the images and we returned them back with a name and URL so I'm creating a type definition yeah and then inside of the images this is where we can actually go ahead and render them so first things first I need to see if I'm getting images back so let's go ahead and render out the images and see what happens so if we get these images back guys I swear to God I'm going to lose my mind cuz it works right so we go to console and we get images oh Let me refresh and we've got ignore that image y look that look at that oh my God beautiful look at that images the images are coming down so just like that we we've created a next JS API zero function it's connecting to it we're returning all that stuff it's just so powerful it's so cool that when you learn how to do this stuff so now what we do is we simply have some front end fun and we go ahead and render this out so let's go ahead and have some fun and render all this information out first things first we have the div and then this is going to do CSS grid so so we're going to have the div and then inside of here we're going to have another div and here we're going to go ahead and do we've got the images themselves so we're going to say images dot right and say and and and we're going to say optional chaining so if it's not yet ready then it's going to go ahead and not crash by by having optional chaining so we're going to say image URLs do map and then that could also be undefined and then we're going to save for every single image and each image I'm going to manually cast it to that image Type image type sometimes chat um copilot is too aggressive yeah and then I'm going to do implicit return so normal parentheses brackets okay and then here we have a div right and then the div has to have a key when you're mapping through things because otherwise your your rendering is crap so do not do that okay so there we go uh then we've got the image dot name is going to be the key here and inside of your div I'm going to have the image itself right so image for Slash and we need to import this image from next next image which we've already done as so you see and then we've got the source which is going to be the image URL the out is going to be um just image name we can do if that's fine the height is going to be 800 so I'm just going to use 800 our set value the width is going to be 800 and then the class name I'm going to style my image the width should be four round rounded small uh Corners Shadow should be of a 2XL a drop shadow should be here as well drop shadow large and I want to do a minus Z index of 10 because I want to layer this nice overhaul effect afterwards on it all right so I hit save and what you'll find now is I get a big error okay now this is happening because what remember we're using the next image component and when we use the next image component we need to whitelist the domain that the images are coming from and the reason why I left it to this point is because it I'll show you a little shortcut it actually helps us out so it says you need to add the host name this right here to your next config so it just saves you a bit hassle you just literally copy that go back over to your next config and simply add it to your list of Whit listed domains right so add it bam over there boom right and then because you change your next config you're going to have to restart your server on the next side right not your as your side you have to restart on the next side so then we go we reset that boom and then we go ahead and do our thing and there you go and now we should see images wait for it do we see images wait for it go oh oh there we go look at that look at that we got dinosaurs Tigers that's just it's so beautiful I love it right it's so cool when you see the the stuff you trying to do work it's just amazing right now you see this it's huge this is not ideal right so I'm going to show you how we can basically perfectly optimize that and get in the right way that we want and we're going to do this with the magic of CSS grid okay so here we're going to say it should be a grid and then a gap of four should be present right so gap of four and then basically on a small mobile device it should always be columns one and then what we do is we Step Up The Grid columns as we get to a bigger size so grid columns two uh on a medium size a large screen grid columns three yeah and then on a extra large screen grid columns 4 and so forth right so grid columns 4 and then I think I fin yeah I finished it off on a 2XL oops oh God 2 XL and this is going to be grid columns five there we go yeah and then I'm going to say padding X of zero and on the medium screen is a padding X of 10 right so padding X of 10 so on the mobile view there's no padding and then on the bigger screen it gets biger so now we hit save and look at this wait for it wait for oh my God look at that oh it's so beautiful look at that a it's just lovely when it works that's just silky smooth look at that it works perfect yeah and now what we can do is I actually want the first image to take up like a block over here so I wanted to take up two rows and two columns the first image only yeah and CSS grid is so good at that because we can actually use like you know span too or that kind of logic to get that down so now what I can do is I can say for the div here where we have the key that sort of thing we can have the class name uh and I can have some string interpolation here so I can goe and do Square cly brackets back ticks and this is going to be relative because we're going to have a little trick going on in a second I'm going to have a um cursa uh help when you hover over it yeah that makes sense cuz I'm going to do something cool and then I'm going to have this uh some JavaScript now here what I'm going to say I'm going say if the index so basically here where we get this back if we get get the second argument back which is actually a number and this tells you like is it the first item second item third item so it starts from 0 1 2 so forth so if I equals z I know it's the first element okay and if the first element is there then I'm going to say the first element should span two columns and still uh two rows okay and then I want to have some logic when I basically scroll over it so I want to have like a hover and all that kind of thing so basically what I'll do is I'm going to add that hover stuff here before and then there you go so now what we've done here is uh that looks horrible one second I've completely broken something um let's just go ahead and fix this quickly let's get rid of that let's get rid of relative cursor I think it's because I've got this and I need to figure something out one second okay so let's do relative there we go so now yeah so there you go firstly get rid of the relative for now I have an idea I'll show you something here so firstly that works yeah so that looks very nice on like it looks proper like an art gallery now yeah and then what we're going to do is after that is done is after this then we're going to add in Hover scale and and that kind of stuff right so now you can see if I hover over it you see we get this nice little effect right and same here and same on a small screen right now here it doesn't work correctly because of a medium screen right or a small screen and I'll show you how we can fix that in just a second so so um oh this should only take place sorry on a medium screen and above yeah it doesn't make sense to span rows on on screens like that so there you go that's why yeah so that's why I was working and then we do make it relative I'll show you a little trick so because this div is now relative yeah so there you go that now it's fixed that issue and then what we're going to do is when I hover over it I want to have this nice little effect so I want to create a white div that hovers uh when when I hover over it just suddenly appears right and the way that I do that is I have a div next to it all right but first the the parent container has to be uh White right so it has sorry uh has to be relative so in this case I say div and then I've got P tag and that P tag will have the text of the image right so basically what I'm going to do is I'm going to have a string here I'm going to strip the PNG and the time stamp out of it okay now for the P tag I'm going to say text should be oops last name we're going to say text should be in the center font should be light and the text should be large and padding of five and then for the div on the outside I'm going to say that this one is this is where the real kind of trick comes in right so as you can see now it's got the writing on the top but I want this to be absolutely positioned over it with a white background and it's an opacity only comes through when you hover over it so what we do is we because we're relative the parent contains relative we can do absolute positioning within that div so we can absolute Flex justify Center items should be centrally aligned and I'm going to say the width should be four the height should be four the background should be white the opacity by default is zero and then when you hover over it the opacity becomes 80% right and then I want to do a transition on the opacity so you get this nice little effect and then we're going to say the duration is 200 milliseconds and a zed index of 10 so that way it's layered above the image right because the image is minus 10 we're going to say this one is positive 10 that way now it's layer so now look we get a layering effect where it's sitting perfectly on top of the image and just like that oh my goodness it's like it's so clean like when you get this down like it's just it's icing on the cake all right so look at that looks so so clean and then now you get all this kind of coolness right now the thing is right so if we've got this working well but firstly when I actually come to this page it it doesn't tell me anything like it doesn't tell me when it's loading and so forth so firstly I want to increase I want to update this U UI so that way it does tell me some stuff right and the first thing I want to do is I'm going to say if it's loading then I'm going to add in a P tag which simply says um uh loading okay so I'm going to Simply add in get rid to this and I'll show you how we do it so we simply say on based on the is loading from the above we say A P tag and it just says loading AI generated art and I've simply done an animate post on it and centered the text so now if I refresh loading AI generated images until it's ready and then buam it pops in right so beautiful works really nicely works well yeah so the next step is I want to have a button on the bottom right which will refresh the images right so in that case if I added a new image it will refresh and I can actually go ahead and check what happened so I'm going to add in a button here saying refresh images but the way I check this is I basically say if it's not loading yeah so if you're not already loading and it's invalidating then you can say it's refreshing otherwise it would just say refreshing images right so now this button here simply if we click it it doesn't do anything but what we want to do is simply just call refreshing images so all it's going to do is fetch the images again when you click it and that causes is validating to become true but is loading you don't want it to come up when you first are loading the images because it doesn't make sense so you basically disable it for that so the text shows and is validating is triggered when you refresh so when you call this is validating gets called okay so here we say onclick and then I'm going to say refresh images right but I'll show you a little trick now so if you just did refresh images what you're going to find is it's just going to get rid of everything so if I do this that refresh images it doesn't like it's not an it's not an optimistic update right so I know it looks like it's working but it's a bit it's a bit sketchy right what you do is you pass in the old images and you get like a nice optimistic update and that means that it doesn't kind of get rid of everything cuz what can happen sometimes is this stuff just like disappears and comes back so we're going to do a nice optimistic update and then it'll use the images when we're refreshing it and then it will replace them once it comes back with a response right so that's pretty cool and then for this button I want it I want to have it floating down here so for the styles for that I'm going to show you in a short hand how we can do it I basically just done some absolute positioning or fixed positioning sorry so I'm just going to paste it in and it's layered at z20 to save a bit of time so fixed bottom right bottom 10 bottom right background 4 90% opacity so you can see through it a bit text white bit of padding rounding Corners when I hover the background changes a little bit darker Focus outline none Focus ring so when you click it you can see something and the F font boat and z20 so it's on top of all the other tiles now you can see look that's lovely look at that really really nice and when I click it refreshing and then refresh images comes back when it's done yeah so that works pretty nice and what we can actually see here to prove this is working if I go to this and I go down down here you can see if I click refresh images you see how it's calling it every time I do it so it's actually making that request to our back end which works right so really really nice so at this point we're looking pretty damn good right so this is looking good but we have a problem so let's imagine if I go ahead and create a black and white oil painting of a child playing in a park so let's use the suggestion which means that I'm creating a modern black and white oil of a child playing in the park now when this comes back this will not update right so I'll show you so look this will not update so let's go ahead and wait for this to come back so once it says file uploaded successfully it won't come back and I'll show you what how we're going to address this problem and this is because this image component is not connected to this uh image input prompt right so I'm going to show you how we can correct this now using uswr in a very very nice caching efficient strategy right so let's wait until that uploads so that should be done in a second sometimes it has a little delay maybe it takes longer to paint that picture or whatever it's doing I'm not sure but it's yeah it's it's doing it on the back end um we could always try and Trigger another one I always find if I do yeah there you go follow uploaded successfully and you can see it's not here right it's not here and we're not revalidating on Focus so it's not going to refresh so if I click refresh images now you can see it then pulls it in okay so the refreshing the images actually pulled in wow that's amazing right that's crazy so it pulled it in okay so now what I need to do is I need to make it so when it finishes this prompt it's going to Simply basically refresh this fetch images but how do we do this if we're in a separate file right so we don't have something like Redux here we don't have any of this stuff so how the hell do you do that Sunny well it's actually a lot easier than you think with us SWR so provided that your caching key is the same so in this case the caching key being API images or whatever you decide to call this if this is IM providing that this is the same right so if I Chang the images I'll show you we can then go into the other component The Prompt input and actually pull in what we need for the ability to do what we need so I'll show you so let's go into prompt input and then inside of the prompt input now what we can do is we can say const and we can just simply pull in the mutate function and we're going to Simply call this one uh update images or you can call it re refresh images really doesn't matter use S SWR yeah and what we're going to do here is we're going to go ahead and say remember the key was images that we decided the fetching function was fetch images which we're going to need to import from our library and then we're going to go ahead and say revalidate on Focus false okay so now I've got access to this and what happens here which is amazing is inside of submit prompt right what after we up load the picture we can cause a refresh to occur by simply pulling in the additional pictures now after all that is said and done simply put what it will do is it will cause a refresh to occur so I'm want to paint a spiral galaxy in 4K resolution use suggestion so now it's going to call make that request so I've actually uh generated that so prompt is a modern abstract painting and I'm not going to do anything and you're going to see it now pop in with that image after that's done we then have notifications to add and uh and then I think we're in the clear to deploy so you see that look it did it it literally did it by itself and that's incredible that means that you have a beautiful decoupled code which is clean good programming practices you're not passing you know your set a function from one place to another and then something can break now all you're doing is you're relying on the caching key which you should be probably putting in a constant file somewhere else so that way you don't mess this all up but then with that you get the you get exactly what you want which is incredible yeah so at this point now this is looking amazing so let's now add in the ability to Let's firstly test it ourselves with um let's just say a um a red balloon on a white background let's say generate and you see like a red balloon on a white background so while that's coming back we can go ahead and test out um the next thing so we now we're now going to add in react hot toast notifications so that way the user knows what's happening on the front end otherwise right now you're kind of waiting like did it work or did it not work and look wait for it look at that oh so clean a red blue on a white background clean all right so at this point that's pretty cool at this point now we're going to add in react hot toast notifications so the way we do this is It's react hot toast notifications so you simply go to the react hot toast notification uh website and we're going to add it in so I'm using mpm in this this instance so I'm going to grab this well I'm think I'm using mpm so so we're using mpm so so I'm going to go over to my um yeah I'm going to go up to the correct directory which is the main directory uh okay let's not do that let's just go ahead and create another one so there we go and then I'm going to go ahead and say mpm I react hot toast now because we can't actually so the way they would tell you to install it is you have to wrap your entire app with um the toaster provider now we oh you have to put this toaster element at the highest element in your highest point in your app now you can't do that in a next year 13 app because you're using server side components so the way you do it is you create a client wrapper or client provider and to do that is fairly straightforward all you got to do is go into your components create a client provider. TSX this will be a client component wrapper in some Essence then what we do is we in import the toaster inside of this file so we pop it in like so and then we're going to go ahead and do the following so where we had the the trick that I like to do is I go to my app I get the layout I basically copy the layout right and then I pop this in but I don't use a lot of this stuff so I get rid of all of this I don't use that obviously and then I still like this part right so what I do is I get rid of all of this and I just make this like an empty fragment a react fragment and I pop the Po in and now and then what you can do is you still have the children so I like to use the layout as a little shortcut for me so I don't I always forget sometimes what I actually need to do that so I get the children now and then I can basically position this so I can say position bottom center and now because this accepts children what you can do is you go to your layout component and obviously by the way you can use the new metadata in nextjs 13.2 so you can actually say AI Art Gallery um and then the description this will change the head of the page this is really good for SEO purposes you say generated by the pop fam let's go all right good and then um popi yeah we got to represent AI IM AI Art Gallery right so at this point we can get rid of that as well I'm going to go ahead and wrap my entire stuff so client provider client provider with what I was doing so I did export yep I did export so here what I can do is I go around the entire app and I get client provider and then I just need to Simply import it into my app so I go here and I import it so I go and say the following and I can just do at there to make the alas work and now your app should still be working it should still be fine but now you can have that ability to place it at the highest level and you don't break your server rendered component structure so if you ever need uh to use higher order components but you know in nexts 13 everything is a server component by default that's how you would do it so if you ever need to have like um any kind of context provider or theme provider you can do it that way and then that would be a client side component it doesn't mean everything underneath is a client side component either okay you can actually still do some clever stuff there I thought that was what it did but it didn't right so at this point we can now add in the toaster notification which is fairly easy we just go to our prompt input so we head over to our prompt input and when we have submit prompt I'm going to base it all off the promise of when we are generating an image so what we do here is we say notification prompt first I need to import my toast from react toast so let's go up here and then I'm going to go down to submit prompt and where we have the input prompt itself I'm going to have a notification prompt okay and then I'm going to slice it to make it a shorter prompt otherwise I don't you imagine I don't want this whole text to come up in the prompt you might want it but I didn't right so it's going to be either the input prompt or the suggestion okay if you have an input prompt um then it will be that otherwise it will be the suggestion um or you can actually just go ahead and say if it was the to be honest it would be the P The Prompt so to actually let's do this let's do underneath here and then let's just make it notification prompt will be P yeah there you go and then you have the correct one right and then you do notification problem slice 20 that means you basically go up to the last one and then we create a notification so the way we do this is we say con notification equals toast. loing and this is for the ID so we can dismiss the same one afterwards we say Del is creating the short version of your notification so it'll be like dot dot dot afterwards right and then after it's done what we can then say is here we can do the try data uh we can basically check the data to see if there was an error now if there was an error on the response what we can say is toast. error with the data. error else toast. success right now what you do is is you simply go ahead and um we actually pass in the ID notification there so what this will do is it will replace the existing notification that we assigned here to these ones so then it'll become toaster sucess your AI generate has been your AI has been generated so forth so let's try out now so chat GPT is thinking of a thing let's do a sunset in the desert use suggestion click it and boom look at that guys a modern abstract photo of uh Sunset and desert but I've cut it afterwards CU you don't want it too long right on a phone for example and now can now your user is not sitting there thinking is it working or is it not working and that kind of thing and you can still go ahead and use the app right so like you can Lally go ahead and say while it's doing it you can literally do something like imagine it look at that it looks lovely right so people celebrating aeal outdoor occasion use suggestion I'm say draw a iPad and then generate as well look and we can have two and they Stack Up draw an iPad uh generate a modern oil painting of a group of people oh that's not an iPad it's closed right I guess it's some sketchy apple pencil but you can see that that's lovely it works just as we expect it um let's do a Col yeah there we go let's just use that one so now you've got a nice UI everything's looking beautiful and I think we are now on to deployment right so first things first we're going to basically step this in the correct way first thing we're going to do is deploy the Azure functions then I'm going to swap the URLs out now as I mentioned you can do the little check to see if production then use your real Dynamic production URLs and then otherwise use Local Host but for today I'm just going to swap it out to be simple we're going to deploy our aureo functions so that they're live and up then we're going to go ahead and deploy a Vel app to uh to yeah to to where it needs to be so let's go ahead and do that right now I just want to check something as well Vel does it no okay so there we go I haven't got the extension yet so uh at this point now what we do is so inside of our Azure right what we have here is let me close everything first so inside of azure we have our local settings. Json now inside of local settings Jason I'm not going to show it because it's got all the keys and everything there but basically what we have here is a bunch of your your your config stuff right so all of your config stuff is in local settings. Jason now if I go over to remember don't forget you got the access to the code here on First Link in the description so if I go over to um my Azure functions so if we go back over here now to my Azure functions to the function app what you'll find is if I go to um configuration so you can just type in settings configuration you'll see we have the environment files here the environment variables here okay and then what you'll find is look you've got your different keys and stuff like that now it's working locally because we have the file but notice how some of my things such as my a sort of you know my my account key my account name that's not on the that's not here so how do I push my local settings up well it's very easy command shift p we type in a zero storage and then we type in uh settings no is it zero storage no a zero function sorry settings upload local settings so this one right here simply hit enter on that and then what you'll find is It'll ask you which app most likely so give it a second and then we find the app so in this case AI image generator YouTube app so we click it and now what this is doing is it's uploading my local settings Json file to the actual Azure functions so this means that when I deploy it so you see successfully uploaded so now when I deploy it if I click refresh now yep we click on continue you should see those new environment variables in Azure so now you can see look open AI key open AI organization and you can see that's correct and we even have the account key and account name so this is perfect right now right so we have the stuff that we need and now with that said so now we've basically set the environment variables in Azure so now what we can do is we can go ahead and say command shift p as your functions and then we can go ahead and do the following we can say deploy to function app and then what this will do is this will actually deploy all of my source um uh URLs to a real app so in this case we can select our app hit enter and what this will do is it will you have to be careful because it will override all of the previous deployments so we're going to click on deploy that's fine and what it's doing now is it's deploying these actual URLs over to um a zero and because it's got the correct your um the correct environment variables it's working so in this case it says deploying click here to review the output files so let's go ahead and see if we can get that why can't I see that um okay let me just see that one second let me yes check the output window there we go so you can see now it's going ahead and it's starting the deployment it's doing everything it needs added the following settings that's what happened before so if you want to find this you go to Output you click on this you see has zero functions you can see all the nice little output stuff syncing triggers deployment successful once it says querying triggers what you'll find is it will give us back the URL endpoints so you see like querying says deployment complete that's what I'm talking about so now what we can see there's two ways of checking this firstly it will give us a bunch of URLs right now and we're going to use those URLs in just a second so let's go ahead and see right now one second so let's pop this to the side let's move this over here and what we'll see is we should see all of our triggers live and deployed so give it a second give it a second it'll take a minute all right so while that's doing that I can go over to my um functions here and you should see yeah there you go look they're there they're literally here they're live yeah so app that's fine we can can do this uh and then so basically that is live so that will give us the thing and then if we click on aure we go here to uh function app AI image generator functions you'll literally get the uh the URLs here as well and I think we can actually copy the URLs here as well so this is this is why the extensions are very good so that's not giving me it right the moment that's still reading so just give it a second it's querying okay so takes a little bit of time sometimes that's finally there you go so we got the different things if we right click com copy function URL so if I was to click on for example get images you can see if I was to paste this in we actually get look that's a real API end point so if I click that look at this guys bam I actually get it that's awesome that's amazing it actually works there's a row end point and it's working so now what I can do is go through my code where where I had my um different files so in this case we've got the generate image and so forth so yeah so in this case now we go to our files let's go to our uh hide this for a second go to your app API and by the time this should have yeah there you go so it came back eventually but you see you got all the URLs here as well yeah so when it gets past HTTP trigger URLs so these are live now in Azure right so now it's actually deployed so we've got the Azure URLs we go to app end points and instead of these ones now I'm going to use them ones so instead of that we're going to go to our Azure and then here I'm going to say generate image copy uh oops no oh god I've actually oops actually executed it um so this one I'm going to go ahead and no don't do that cancel yeah oh but that's really cool actually you can actually generate it from here I did not know that enter request body wow so here you could do prompt Microsoft fair play you can say draw a d dinosaur in a Blue Lagoon I don't know I don't know what's up with me in dinosaur as well enter and that we oh wow that's cool yeah so you can actually test it that way as well now you know right and then in this case we can go ahead and paste it in so that's live um obviously you can use I would recommend that you actually did envir like proper environment variables for URLs here and constant FS but I'm just trying to show you the point right so we've got this get images oh look at the papa Fon come on let's go then we got to get images here so here we're going to do get images the same thing copy our function URL pop it in and again I would make it so when you're in uh your production environment oops sorry guys when you're in your production environment you're doing your local like basically you just do a check here which is if it's in production you do local otherwise you do your domain I just want to show you this it works and then the final one is chat GPT suggestions so here this song will never get old I swear to God I love it it reminds me so much of the the papa fam and the amazing community that we built and then let's go ahead and copy this one bam pop it in there and then you see so now you've got your chat GPT suggestions all that kind of stuff running off your actual endpoint so let's test the up and see if it works let's refresh Y and you see chat GPT is still thinking of suggestions it's still working a modern abstract painting of a house okay awesome look my my dinosaur in the blue came out so let's go ahead and use this suggestion and this is happening of real as your end points right now so this is happening of real as your end points right now can you have custom URLs I'm pretty sure you can yes so in this case look that's happened that's actually been uh that actually fetch from a row as your endpoint and that's perfect that's working look this is all working from real asure end points so the final step now guys is we need to go ahead and push to Vel all right so let's go ahead and deploy this to Vel right now so heading over to the cell what we need to do is remember we got two things now because we have over here our local environment file okay so the environment. local file um the environment local file here we actually need to uh upload these environment variables to Vel but I'll show you a nice quick way to do it right so what I like to do is very simply go to my uh let's actually make this a little bit neater let's go here let's pull this over here and we have or AI remember you're going to get confused at times cuz 1 minute you might be in Azure and then this means you're at your your Azure function your your aure project nested inside and then you got to come up to do your dependency management here as well now what we're going to do is we're going to go ahead and type in Vel and Vel if you haven't already installed the Vel CLI tools all you have to do is type in Vel CLI and it will have very simple instructions to install it you type in for cell if you're not logged in it will make you log in here I just say set up and deploy yes and then what scope do you want to do so I'm actually going to do it to Sunny s's team so I've got a pro account as well so I'm going to do a sunny Tangers team link to an existing project uh I'm going to say no for now what's your Project's name there you go what in which directory is your code located it's in this one right here and also guys if you haven't already signed up to Vel um so in this case which code is your which directory so you hit enter on that setting up the project now this will upload your code now this is going to fail right I I'll show you why so you first you click enter okay that's fine this is going to fail because we haven't uploaded our environment file uh variables yeah so what I'm going to do here is I'm going to go to my uh AI image generator build go here and right now I'm trying out the pro features we go to our settings go to our uh environment variables and you can see we don't have environment variables so the easiest way of doing this is you simply go into your environment variables I'm going to invalidate my key anyway so I don't care environment copy your environment variables and then you simply go here and paste and then you click production preview development whatever one you want to do it for click save and then what you can do is go to your deployments cancel this one right oh so it's actually already finished anyway but basically and now what I'm going to do is I'm going to type in Vel and this will work because now you're going to redeploy it to um production or no it's not going to deploy production but it's going to or it did do it here as well um but it's going to redeploy this now with your environment variables now remember if you haven't already signed up to Vel then I highly recommend you check out use this link links. rea.com Vel so make sure you go check it out if you haven't already and you're going to get a free bunch of stuff when you do this way so if you haven't already got a pro account or you haven't got an account with Vel then definitely go check it out at links. rea.com vasel okay okay so that is I'm just going to add it on the screen so it's super easy for you guys to read so it's links. rea.com again you're supporting the papa fam it helps us out a ton and it always you know it's always awesome to have you guys support us out so in this case we got the preview link uh you can deploy to production by simply running Vel d-r which is what I'm going to do here and this will deploy to production and then we can actually go ahead and see it so in this case let's see if it worked and we've got everything oh look chat you please think suggestion let's go this work yes let's go that's what I'm talking about amazing if yours if you're adding images in I need to refresh on my side because it's not a websocket connection but I'm going to check so feel free now to test that out for yourself and I want to see if images actually come in okay so I'm going to go ahead and keep on adding a few images as well so a new suggestion let's just type it in and then we should start seeing things oh someone did it look someone did it yeah that was someone else that wasn't me let's do it again so someone there we go look hey there we go guys look cat girl love cre see Skyline in 4K resolution let's go guys family of three create a modern abstract oh wow that's crazy this is so cool Jay said he did one as well oh look at this oh my god oh this is so cool so what do you guys think absolutely cool right amazing stuff destroy that like button if you're enjoying this build right now look at that everyone's loving it lion wearing a crown that's what I'm talking about I think the cat one by pach I don't know I had a feeling lion emoji and ice cream this is so cool but look at that wow look how good that that is that's incredible but yeah you guys have tried it for yourself you can see for yourself that it works that is really cool that was insane guys you just built a Del 2 image generator app with Microsoft Azure powering it up on the back end firstly that's a huge collaboration you're not only demonstrating your AI skills but you're using powerful backend tools such as Microsoft Azure to go ahead and power them this is a great addition to go ahead and add to your digital portfolio and you can impress your next interviewer at the next interview now remember if you got stuck at any point check out the code in the GitHub repo it will be linked in the description where you will find the code for the entire build located inside and if you want to go ahead and sharpen your skill sets with your coding skills or you want to go ahead and get support from others inside the community definitely check out our course and Community Zero to fullstack Hero it's the first Link in the description you will not regret it without further Ado guys it's time for build three of four in the AI crash course let's jump into this next up we have the AI Trello clone now this was one of my particular favorites because of one main feature Dragon drop I'm going to be showing you how to implement Dragon drop using the react dndd library inside of a nextjs 13 app so of course you're going to go ahead and level up your react skills in this build but most importantly when we're using next year's 13 I'm going to show you how you can go ahead and differentiate between client components and server components and where you put an a library such as react D andd inside as a lot of you seem to get stuck on this and it's for good reason because it's a little bit confusing to get used to but I've made it simple and it's going to be an awesome build on top of all of this you're going to make your app look beautiful with t and CSS we're going to make our code nice and robust by using typescript and all of the data in today's build will be stored and located on the app right cloud and of course to manage this data inside of our app we are going to leverage a global State Management Library known as zustan so if you've heard of this this is the ultimate video for you and in addition to all of the above I'm going to show you how to go ahead and create accessible components leveraging The Headless UI Library let's jump into the AI Trello clone enjoy check out the Trello 2.0 AI clone with gbt 4 get ready guys Popa F out we do it boom 2.0 Trello look at this thing it's so flipping beautiful I love it the design is awesome let's go ahead and drag and drop oh my goodness look at that oh hang on what's that 2bt is summarizing our our tasks that's that's awesome right and then we've even got a really nice model look at this and guys this is using headless UI so if you haven't already used headless UI this is how you do it guys let's go ahead and add a new to-do let's say I want to crush this stream right and then what you can even do is you can tab so now I'm literally tabbing through using the keys to go up and down and I can go and done I can upload a photo so I'm going to hide so that way you know I don't show anything I don't shouldn't show then we get the nice little preview here you see right now we got a nice little preview we go ahead and add the task that's going to go ahead and upload it inside of the upright cloud and then it's going to go ahead and pop in our done page so depending on which one you clicked on it will go ahead and preet that for us so you've already got that working look at that I want to cross this stream and you can go ahead and move it around this is persistent this is all on the database and we've even got search included so if I go ahead and type in podcast you can see we've gone ahead and released the podcast right you can go ahead and it's really fast really nice stuff welcome to the stream you can see how it filters everything out you're going to learn all of this today and yes you know how your boy does it it is responsive I wouldn't make something that's not responsive there you go look at that so this thing it works on a phone works on anything you can imagine and we've also got some nice cool tricks today like how you can get this gradient effect in the background so so much stuff happening right now right guys let's go ahead and break down this build so we can get started for you all today this build is actually powered by the guys over at ight Cloud so this entire thing is actually super simple behind the scenes and and it's actually thanks to the guys over aight so we're going to be building an incredibly fast scalable solution today but they've got everything from databases authenication storage functions they're basically Cloud functions security and privacy realtime database functionality all the the good stuff and they've got so many examples here so you guys can see they've actually released their beta which is perfectly working right now so you're going to see today how we can use it how we can integrate it and honestly a lot of the code is honestly it's like on line clicks so you can basically do a on line command to get something into the database we always like online stuff right so that's why we're going to be using this today it's definitely something that I would recommend and I definitely suggest that you follow along today get set up give it a play with and because there's so many features I haven't even covered in this so if you want to see more videos let me know also by the way I forgot to mention you can actually take the entire columns and look how they see-through oh look at that oh my goodness and even look how it turns green oh I just I love it it's so satisfying it's so so satisfying right now I just went a bit crazy that's why I I probably got an error I I think I I I I threw too too many things around all right so let's go ahead and uh break this stream down so first things first we have the react we have have nextjs 13 so we got nextjs 13.4 now I know there's so many changes lately in nextjs 13 uh. 3.4 all of these different releases changes there is even something called server actions now which is damn powerful but in next CH 13.4 we are going to be using the brand new app API directory to create some endpoints so you got some fun stuff to look forward to we then have GPT 4 in the mix as well we actually have uh a few things today so we've got Tailwind CSS Tailwind TSS I highly recommend you go ahead and get this sort of you know you get practicing with this that's how you're going to be able to build awesome responsive webites without the headache right honestly without the headache of media queries and all this crap but I hate this so in that case we've got headless UI now if you haven't use headless UI we're also going to be doing typescript so we got typescript in the mix as well so we're going to be building robust code that's going to be you know less error prone we've got some search sort of functionality so I'm going to show you how to integrate something like a search field and um we even have oh yeah and I've not actually done this in any other the builds so far we're going to be talking about the map object inside of JavaScript so if you've never used something like a map object I'm going to be showing you something like basically a map object today so I'm going to break it down we're actually going to do it uh in a really sort of cool use case and what I did here was you can call it over engineering I really don't care I'm trying to teach you a lot of different principles in these videos but I want you to come out of this knowing what maps are and how to use them and why they're a bit more efficient sometimes Okay so we've got the map object inside and obviously we cannot forget that we have the dragon drop Library okay so it's called Beautiful DND D so I'm just going to write d and d and that stands for Dragon drop now the crazy thing is the the library was actually um bought out by atasan and atasan actually bought trillo so we've got the cloud powered by aight so we've got aight powering our cloud and that's where we're going to be using today so everything that we've doing on the back end is essentially powered by the ight cloud and that is pretty much oh no of course I've missed out the biggest thing we have zand so if you haven't heard of zand this is essentially a very new bit of Technology now I am actually somebody who is quite skeptical when it comes to you know touching new bits of tech like I will tend to use them but I will run them through coaching course in my community 0 to4 stack hero the coaching Community you can definitely check it out second l in the description but I will go ahead and try these things out see if they're actually useful see what my students react to them see how useful they are in my production gigs and then I will actually go ahead and make a decision as to if I want to push it on YouTube now Z stand is absolutely incredible it's simple it's so easy to understand and Implement and that is why I'm going to show you how to use it in today's build as a replacement for something like Redux so it is actually honestly it's going to blow you away like I do so much cool stuff with this including handling the modal state so when you click on a modal it's going to handle that state so when we do this right here here and bear in mind you can actually click out so I'm going to show you how to do all of this even if I press Escape you can click out so all of this stuff's ready to happen right you've got all of this Z stand then we're going to keep the board State inside of that Global State as well and we've also got the users interaction so notice how when I click on a to-do column it already highlights to do if I click on a impr progress column it says in progress and if I click over here in the done column is already highlighting done so you're going to learn loads of things like that so a lot of people saying what do I use to r on the screen screen brush that's it right okay so let's go ahead and dive into today's build but before we do at any point if you get a little bit confused or you're not really sure on to you know if this is too advanced for you do not quit instead what I recommend is you check out all my free content and if you really enjoy the free content and how we do things then I highly recommend you check us out at zero to full stack hero this is our internal Community this is not only just a course it's a massive community of Papa fam members you can go ahead to papa.com click on INR now and you'll literally head over to our page tons of stuff here right if you want to see what people are saying about our course check out the reviews tab on papa.com and you see for yourself right there's liter we got so many members inside there but in this case yeah you can go ahead check it out we've got real members real people talking about the success and honestly it's just everything you need to go from absolute Basics to crushing it and Beyond right we've always got your back and this is a lifetime community so join it you'll be a lifetime member and that's how we work right we literally have a community where we help each other out we help each other level up we help each other do like professional gigs all that good stuff happens inside there and if you want daily emails with coding challenges then you can even feel free to check out the University of code on latest and greatest newsletter it's at the top over on pap.com basically coding challenges every day every single day to your inbox with the solution the following day so you can go ahead check it out yourself but all of that is available at papa.com so make sure you check it out that is how we essentially support everything that we do so honestly it's a win-win we go ahead and help you out and yeah this is this is what we do and this is how I'm able to constantly go deep into topics that I can't always do on a live stream right so I want you guys to learn the most so this is something that I can help you out with everything in today's build by the way that we are going to use is free so I want to make that very important everything that we are going to use in today's build that you see on the screen right now is free so make sure you do this make sure you go ahead and add this to your portfolio and keep this as a project because honestly it's a really nice project to have on your portfolio that's absolutely that's it we're going to get started with today's video so I'm going to go ahead and show you what I like to use now I'm going to show you as if I was doing it from absolutely scratch so that way you can go ahead and follow along because I know a lot of the times some people are like how the hell did you just do that right so I'm going to show you literally as if I'm Googling it right so the first thing I like to do is use create next app okay so create next app oops a right say AP and I like to do it with towi simple as right but this time we're actually going to use create next app the canary Edition right so I'm going to use the canary Edition you can use h honestly quite like quite frankly you can use any one you want but this is how I would typically find it right so you can do I would say so this is what we're going to do MPX create next app at latest inside your terminal if MPX does not run then all you have to do is install node so Google node and you'll be able to install it okay so we're going to open up a terminal to get started let's go ahead and pull this up let's get into a flow State now okay so remember all of these videos are time stamped afterwards this is live right now but if don't worry if you're busy and you have to go away and you want to come back you can do that it's all good okay this is all literally going to be straight up on the channel afterwards so we're going to go into I like to keep things organized I'm going to go into my documents my builds folder good stuff and if you're wondering yes all of this is going to be available on the GitHub repo afterwards so you can go ahead and download the code all the links that you're looking for are in the description okay let's go ahead and do this so builds right now let's go ahead and jump in we're going to say uh MPX create next app at latest you don't even have to put a title in right you can just go ahead and run that command and then it will go ahead and prompt you to ask you what you want to call it and everything you want to do after that so let's go ahead and see what that says and now it says is it okay to proceed we're going to say yes it's fine what is your project name we're going to go ahead and say Trello ight clone and I'm just going to say YouTube but you can call it whatever you want all right would you like to use a typescript with this project I'm going to say yes I would like to use typescript would you like to use es Lin yes would you like to use towin yes would you like to use the source directory no we don't really care about the source directory okay um would you want to use the app rout which is the new next year 13.3 I believe it came in r or you know whenever it came in next just 13 though they say yes would you like to use customize the default import Alias no and a lot of you're wondering or may have not seen that import Alias I'm going to show you today it's really nice this is like a little addition that they've added in the template you can see they're constantly updating this so if you're watching an old bir and you're not getting these options then don't worry about it you know they're going to change that command whatever the case just look at the migration the latest docs adapt your code and so forth okay so let's go into our directory so CD Trello aight clone YouTube and then I'm going to do code Dot and this will basically open up vs code with our project okay so then I can close this I can go ahead and I'm going to prepare myself by setting up my screens in the way that I expected okay so I'm going to push this over here make this go over there close this up and now what you can see is if I go into my app my page. TSX we have a bunch of stuff inside of here okay so command J opens up our terminal we're going to click on output and here I'm going to hide the first one and the last one so I just have my terminal that means we basically shifted over so we've got our project open the way we want it and we want to essentially just run this app now okay so first thing I want to do is I've actually taken screenshots of the old app so don't worry about it we have screenshots of all of this so you guys can actually you know we can run through it afterwards and I forgot to mention by the way this is actually using GPT 4 so that's actually using the open AI um uh API and it's actually going ahead and taking the to-dos that we're going to go ahead and format and pass to it and it's providing a summary of the things that we have to do today right and if I move things around it will go ahead and calculate another summary for the day right so it's pretty cool and this is an example of how you can use AI in a very simple fashion in this case it shows us what we have to do today so again I'm just giving you the tech the platform you can go ahead and run with it build some really cool apps right so let's go forward and do what we were doing so heading over I'm going to go ahead and um yeah so here we're going to go ahead and I'm going to cut my old app so let me cut that one off and we're going to say mpm cuz I've got package Lo uh package Jason package lock if you had yarn lock then you'd be using yarn I'm going to say mpm run Dev and this will basically start my app inside of a developer environment all right so now we've got this open I'm going to go to Local Host now so I'm going to refresh my page and what we should see is a nextjs starter template so we're going to go from the nextjs starter template to this so this is what you should see right now so this is your starting point okay now what we're going to do is eradicate all of this that way we've got a clean template to start building things command J to hide everything we're going to go into the main tag and we're going to delete everything inside of the page. TSX and I'm going to type in H1 and say hello let's just say Trello 2.0 clone right AI clone cuz we are using a bit of AI here and then I'm going to go ahead and get rid of that and I'm going to get rid of that okay now inside the app Direct it's worth mentioning that in next year 13 anything inside the app directory is actually naturally a server component server components mean by default they're rendering on the server so some things aren't available to us out of the box unless we convert it to a client component so don't get freaked out by all of this just know that if you get some random error when you're trying to use State that's what's going to happen but we'll explain a lot of that in a second let's go over to layout. TSX this is the layout file which is responsible for your presentational logic right so we're going to go ahead and get rid of the font stuff we don't care about that we don't really need to change that right now we're going to keep it very simple the children is essentially where our page is rendered into on the layout itself and we can go ahead and change the title with it like here we can say Trello 2.0 clone and we can say generated by the papa Farm there we go bam and then the final piece of the puzzle is globals now the top three right here are responsible for pulling in all the Tailwind utility classes all that means is it you know those little nice Tailwind classes where we basically write like text red 500 all that stuff is basically PED in here and they are called utility classes because they go ahead and actually translate to real CSS rules which can be read by the browser okay so we're going to go ahead head over back to Route delete all of this hit save close that now what you should see on your page is this and that means that we should have a very empty page and that is good because we want to have a blank sheet to start with okay so we're going to go ahead and pull this out and I'm going to go ahead and move this over here let's go ahead and pop that to the side and now we've got a perfect starting point okay so the first step there's a lot of different areas that we're going to have to build today right so I'm going to go ahead and just try and get a little bit of sense to this as to how we can go ahead and move forward with this in the most efficient way so what I've done is I've actually gone ahead and screenshot screenshotted a bunch of things and what I'm going to do right now is open those screenshots and then keep things up on the page that way we're going to refer to this as a design element and I'm doing this because a lot of you actually really like this approach okay so as you can see imagine we have a Okay so we've just started as a developer at the papa fam headquarters right this is our developer the designer documentation so our designer comes to us says I want to build this how the hell do I build that right so now we're going to break this down and build this entire app okay and it's got drag and drop functionality everything that you expect but we're doing it in exactly the way that it would be in a real life situation so hopefully this should give you some real world context okay so now we've got this screen so I say we break it up into sections we've got the header and then we've got the board right I think that sounds good I think in fact what we'll do is we'll consider all of this the header and then we'll consider the rest of it the board okay so let's go ahead and get started with that so the way I like to do it is I drop a comment simple as I say that this is going to be the header component and this is going to be the board component pretty simple it's going to be two components the header and the board that's it okay so just to get us warmed up we're going to start with the header comp component so I'm going to go ahead and create a header component now this is going to complain because there is no header component so what we're going to do is I'm actually going to close this go to my package Json level create a new folder and call this the components folder this is going to be responsible for all the components now it's worth mentioning that inside the components folder we also have server side rendered components so all of them are server CL server components by default okay we're going to go into the components and we're going to go ahead and create a new component called header. TSX and we're going to say RFC now if you're probably wondering I did RFC and my computer doesn't look like that well that's because you haven't got the extension that I'm about to show you right now so inside of your extensions tab I want you to go ahead and type in es I always forget it is it es6 es5 es6 Snippets yeah es7 so you want to type in es7 es7 um Snippets this one here okay I want you to type this in and install this extension that's how you do RFC and it pops up with everything all right so you want to install this one and while you're there I also want you to install the Tailwind CSS extension this is going to be really important for the Times where you see when you're adding in your utility classes it goes ahead and gives you all the options that you can go ahead and pop in like so it's really important honestly it makes your life so much easier I 100% recommend it okay and it's very good when you're learning how to do Tailwind stuff so now we've created our header component this header over back to page click on the end of header and the nice little trick is if you press control space bar you get this nice little import now I go ahead and hit enter and as you can see it auto imported it now something which is really cool here guys is that you can see we've got this at sign now this new ad sign is is something which is not really that new but we just haven't seen it much because I don't really tend to do it in the builds unless it was set up for me because we were in a rush but the reality is this is called an alias now what this does is is it says go to the top level or whatever we've assigned to that and I will show you how you can Define what that refers to in the path so rather than doing like dot dot dot dot dot dot so forth now instead you can simply say at to go to the top level then you can go into components then you can go into header that way no matter where you are you can just say at for slapp at/ components and the way you do this is you go into TS config head over to Puffs and as you can see the at path simply refers to the top level so this means that the top level and then it's got a wild card for anything that you want to put in so this will correlate to this wild card and that's essentially how you do it so it's actually really simple to get that working but it's a game changer okay so now we're going to go into our header and we should see the header popped in like so this is great okay so I want to okay can I can I not shut my grammarly off um I use grammarly lately it's pretty cool um can I just deactivate it when yeah there we go get off that's it we're good okay so at this point now uh there we go nice so I'm going to change this to a header syntax we want to be a little bit SEO friendly get rid of that we don't no longer need to say that it's um a header um import sorry and then the first thing we're going to do is we're going to go ahead and start styling out so let's go ahead and use this our reference we've got an image tag here then we've got a nice little Gap here so in fact this is going to be an image this is going to be a div which takes up all of this space and then we're going to have a search bar and a avatar on the right okay moic says uh um there we go do you think so we're actually using Zan today for State Management and trust me it's so easy to do okay let's go to the image component so I'm going to go ahead and pop in an image right now so first up we're going to use the nextjs image tag so nextjs image tag like so and I'm going to go over to control space bar and you can see next image okay now what I've done is I've made your life a little bit easier I've added a source tag um which I've shortened into an own my own URL okay simply the trailer logo and this is complaining because you also need to say something like the o tag right so you have to give that now it's not just going to work like this you have to give it either a fill or a width and height so in this case I've given it a width of 300 and I'm going to give it a height of 100 and this is basically how nexj determines how to optimize and render it before you've done anything right so we go to the class name now now here what I'm want to do is I'm going to say width is 44 on a mobile view but as we hit a medium screen so this is called Break points then it's going to be a width of 56 okay okay I'm using so many different plugins that is super annoying right now there we go all right and then we're going to go ahead and say padding bottom of 10 we're going to say and on the medium screen we're going to go to a padding bottom of zero and then we're going to say object should contain itself that means it doesn't stretch out and look strange now as soon as I hit save we should see an error this is because nextjs likes to optimize our images now we have to whitel list what image is we're actually allowing to come from and what domains they're coming from from if we don't everyone could misuse this because they could you know be pulling in images left right center from different domains and then there a bit of a problem so we have to basically say we trust this domain how do we do that it's very simple look at the error message it says host name and it will give you the host name copy that host name then head over to next config next config is simply inside of here notice how I don't even need to say using the app directory anymore so previously we had to say app directory now we don't actually have to do it anymore because it's now in uh it's working here we simply say images and then we're going to go ahead and type in domains okay and I'm going to pass in an array now I'm going to go ahead and pop it in like so links. rea.com now what actually happens now is it actually does restart the server for us but I'm you know I'm a little bit skeptical I like to play it safe I'm going to cancel the Ser with control+ c and then restart it again cuz I've had a few weird errors whenever I decid to do that right but they are upgrading it which is nice right so we go ahead and refresh and we should see that this disappears and we should see a logo at the top hey we've got the trailer logo okay so that's a good start next up what we want to do is we want to have a div which is going to include the search box okay so as I mentioned before we've got the left side and then we've got a div with the search box and the custom avatar okay so this is going to be the div next to it now inside of here we're going to have a search box and the Avatar which is the little circle with with somebody's name in it okay now for the search box we're going to make our own custom search box okay so I'm going to go ahead and pop in a form and inside the form I'm going to have a input field and I'm going to have a button okay the button is going to say search but I actually want to hide this button so we can create some funky nice UI to it okay now at the moment we can't really see anything because it's kind of white and we yeah it's bit hidden right so what I want to do now is Al I also want to have an icon next to it right so there's a few things that we need to change here firstly in order to get that icon I actually going to use something called hero icons so head over to Hero icons.com this is a you know a library that is supposed to be used with Tailwind let's go to documentation go to on here we go and then go down and it should show us how to install so for react we simply do an mpm install we head over to our code command J to pull up our terminal and as you can see we're already running something here okay so what I want you to do is basically you can either do two options if I'm working on a bigger screen I actually split the terminal but in this case I'm just going to open up a second terminal so my first is running the app the second is going to go ahead and be my install terminal I always like to have a few separate ones running so we've installed the stuff that we need and then it tells us how to go ahead and use it so in this case I need two different icons so I'm going to go ahead and import them like So eventually we're going to use the user Circle but the magnifying glass is what I need now if you're wondering how did he search for it though well all you need to do is type in for example user you can go ahead and see for yourself here it pops up right and then you can go ahead and use it like so so in this case we've done the heroon step so I'm going to go ahead and add in the magnifying glass icon now I'm going to go ahead and style this a little bit uh by saying it should have a height of six a width of six and I want it to have text Gray 400 oops my bad text Gray 400 okay and what we should see now is we get a nice little icon which is a lot lot better than nothing right now for the input type we should have a placeholder value that way the user can see where they're supposed to type in and it also allows me to show you the changes are happening as we do what we do right so for the form this looks horrible right now so let's go ahead and fix it up so I want to change this to make it look like a really nice form so firstly we're going to put flex by default naturally the children go into a row as you see the search is now next to the um the magnifying gloss then we're going to say the item should be centrally aligned on the y- axis we're going to give it a space between each other like each item of five that's why it spaced apart then we're also going to say the background should be white the rounded the corn that round the corners off padding of two give it a shadow of medium right and as you can see already it's looking pretty decent right it should be Flex one no so that's not going to be Flex one yet we'll handle that afterwards right I'll show you how we do that um yeah so actually it's true flex one because on a mobile screen I want that to take up the entire width and then afterwards I want it to be flexed initial on larger screens so that way yeah you it'll make sense once we actually complete that part so let's carry on we've got the magnifying glass here High we got that perfect the input field we're going to go ahead and give that a flex one rule and right now the flex rules here so if we do Flex one here it means that the input field is going to take up so you see right now it's not taking up the full width right if as soon as I hit save on Flex one watch how it takes up the full width that means because you're saying that child should take up the maximum space that it has yeah so that's how we essentially do it right and then also you see this ugly blue line I don't want that I'm going to say outline none right so outline none gets rid of that blue line makes it a lot cleaner and then it's too close together so padding of two little bit of breathing room now now that's looking much nicer hey good okay so we got a nice little search field the final bit is this button we give it the type of submit okay and what this does now is it access the enter key so when you're inside of a form and you have a button with type submit if I go ahead and type in a bunch of stuff and I hit enter notice how the page refreshed that symbolizes to me that we actually submitted that form okay so that's a good start yeah so let's carry on strong so now inside the div for the surrounding box we actually want to go ahead and you know before we carry on I want to just modify something here so we're going to go ahead and have a div that surrounds everything so inside the image and so forth so over this image over this div so let's have a div which surrounds everything yeah and this div is going to start having some rules so we're going to say it should be Flex there you go and then um so what we're going to do is we're going to do mobile first design which is how you should typically do it right so we can say Flex column on a mobile view this means it goes into a mobile view now when we go to a bigger screen it's going to become Flex row okay because basically as we're on a mobile view I want it to stack up like this but on a bigger screen you see I want it to go across like that right once that's done we can say items should be centrally aligned so as soon as we do that so now you can see it centers on the phone and over here it centers you can't actually see it because there's no padding but it trust me it does right P of five to go ahead and give it a bit of space from the corners and I'm going to give it a background gray of 500 now that's really strong so I want to give it for sl10 that is basically a short hand for make the background gray five the shade of 500 but 10% opacity right crazy stuff round the corners off so bottom 2XL now you can see I've got these nice little Corners rounded off it's very subtle difference but these things are what caused that nice change to happen so look at that already looking pretty sweet now you see here how the Trello is right next to this right this is because if we were to inspect this these are only using up the minimum space that they should be all right so if we now go to my image and we basically say I want you to use up the full width so it wasn't actually that one it was um I'm going to fix that afterwards actually so we'll do that after this one is yeah that's fine okay so let's do yeah that's it I got it right so this div yeah so the div surrounding the search field we're going to go ahead and say class name and I'm going to say this is a flex box and right now it's only got one child in there cuz we haven't got the Avatar in there so I tell you what before I do that I'm going to add the Avatar in so this Avatar new library so it's kind of fun right so this new library is called react Avatar right so it's pretty funky Library um I would I used it more out of convenience if I'm totally honest um but you can feel free to to use whatever you want so this is react Avatar we're going to install it and what I like the reason why I like it is because you can actually use a bunch of things like Skype ID GitHub Google Facebook ID and it will go ahead and grab your picture for you so I thought that was pretty cool so we're going to go ahead and just do that right now and I'm simply going to put a name in there so in this case mpm so as I mentioned this will be on your portfolio so really what's going to happen here is it's going to be one of those ones that you put on your portfolio I'm going to make it to a level where again it's just going to be statically for one user right you can go ahead and upgrade it and so forth as you wish I'm going to make it a little bit bigger for everyone so hopefully that helps you out so in this case we have Flex so we've got the Avatar so now I'm going to go ahead and use the Avatar so here I'm going to say Avatar Avatar and you see how it imported it automatically for me so Avatar space name equals in this case I'm just going to say Sunny sang right you again you can feel free to look at the library and customize it as you wish right I'm just giving you the tools to go ahead and get things started off so if I do that you'll notice that okay that was not a great one that that freaked out um Avatar name round okay let's refresh why is that freaking out let's have oh okay this is a client side component okay so actually we're going to do a lot of things here inside the header which is going to require State and a few things like that so what we're going to do in this case is we have to convert This Server component because in nextjs 13 everything by default is a server component so in this case I'm going to go ahead and convert this to a client side component this means that it is rendered on the client so basically the rest of the page which is a server component gets rendered on the server but this header component basically when the page loads then on the browser of the client it executes the code right so that's basically what's happening when I say use client so it doesn't on the server it does it over here now what you'll find is we should not get that arror anymore there you go that's why so that's a big sort of thing that you have to look out for now as we transition into this sort of server component realm yeah so now what we're going to do is use a nice little features of this Library we're going to make it round we're going to go ahead and say the color should be a value and I've got this nice Trello blue right I should really give it a name but in this case I'm just using it simply we're going to go ahead and pop it in like so it's got the Trello blue and then I'm going to go ahead and say a size of 50 right so 50 like so and again you can change this to whatever you want you can say Elon Musk and then you see it becomes em and so forth right but I'm going to go ahead and say Sunny s yeah nice so now we've got our you know a easy bit there right um so you can Liam you can definitely render what you can on the server so again you can optimize it at so many levels I'm just showing you the base and then you can feel free to elevate it I'm just trying to show you a mixture of the things but I'm not going to go so far in if you want to see me really optimized zero to four sa C in a coaching court is where I do that kind of stuff so again papa.com Link in the description and I will help you out with all of that right so I would recommend if you really want to elevate the Diamond package is honestly the one that we get Raves about yeah so definitely check it out so we go to the div class name and now I'm going to say Flex items Center and as you can see now now we get this like really nice effect going on right so this is what I wanted to show you I want to space this out so Space X of five so there you go Space X of five Flex one so what this will do now is if I make it a bit bigger here so what you're not seeing is that this is actually by doing Flex one so if I get rid of this I'm going to say BG red I just want to show I'll make a point to you BG red 500 okay so notice how it's only using up what it should be using right so if I do Flex one boom it uses up the full width now okay then what I can do is I can say justify it right over to the end so justify to the end and then what it does it froze it over to the side okay and then on a mobile device you'll notice how it's only small so what I can say is make the width four as well and as you can see now on the mobile device it's width four and on the bigger device it's going to be nice and snug in the corner and then obviously we can get rid of our red color that I was using for demonstrational purposes and and then we go look at that I hope that was a good explanation of how we did that but yeah you can see how clean that was right so look at that it's really clean you got a beautiful UI and just simply like that little tricks that you learn over time and yeah you can do that yeah I'm Dev that's perfect explanation yes use client is for things that can't be done in the server have to be done in the browser hence we convert it to a client set component and then we use it right but I wouldn't recommend making your entire page client side just do the components individually right okay so we got the Avatar done okay that's great now after the Avatar so after this div what I now going to do is have another div and this is going to be where the suggestion will be right so in this case you see this suggestion right here right so I kind of want to have this still as part of the header right you can really you know you can exclude this out and do it separately as a different component if you really want but it's completely your call here I'm going to have a user Circle icon user Circle icon and I'm going to say something like this I'm going to say the class name should be an inline block right it should be a height of 10 height of 10 width of 10 oops height of 10 width of 10 and you're going to mix the music up a little bit let's go to some of the new tracks that we've got on the popan playlist again pua.com right at the bottom sign up to that newsletter and you get access to the entire playlist if you like the music that you're hearing right now we're going to say um height of 10 width of 10 we're going to give the color of this um person to be the blue that I talked about earlier and we're going to give it a margin right of one so boom and I if you're wondering yeah I actually do listen to this um this music when I'm coding so this is literally my my playlist I listen to right just go ahead and hit save refresh so you can see now it's blue looking nice and then yeah that's pretty great okay and eventually we're going to have it if it's loading that's going to spin right so that's perfect for the P tag I'm going to Center that P tag by saying Flex items Center justify everything in the center a nice little trick was centering a div and then we say MD padding y so only on uh medium screens are above I want to add padding y so in this case you see there's no padding here but if I'm on a medium screen it adds the padding right so I want to do that just in this case okay now for this P tag I'm going to say that it should be text should be actually know before I do any Flex here inside of here I want to have a suggestion as well so this is a P tag so we've I'm actually reading the icon as part of the text and then I'll have a suggestion So eventually we'll hook this up to GPT but for now I'm just going to say GPT is summarizing your day okay so that way you guys can see so now you can see that this is slightly off character right this is not like perfectly aligned and the trick that you can do is as we have two inner children technically here we can actually do flex and we can do items Center and notice how it's now it's perfectly aligned nice little tricks right text small font should be light I'm going to do padding right of five and I'm going to say shadow XL so that way he's got a nice little Shadow to it round the corners off with extra large rounding I'm going to make it fit only where it needs to fit the background should be white it should be italic and it should be a maximum width ever of 3XL and I want the text to be on fancy ass blue right that just there you go fancy boom there we go nice right there you go look at that looking clean right something's off though the padding the padding is off right so I forgot to add padding in the P tag yeah of course so here so padding of five bam that's much better right so now you can see GPT is summarizing your task for the day right now obviously it's not we're going to go ahead and add that in afterwards so at this point now things are looking pretty good I think so I'm happy with that that looks pretty nice now I'm going to show you the trick for the color gradient okay so you see this color gradient in the back now something that you might have not noticed slight designers will notice this right only the designers will notice this but that is not white that is gray right so and what I'm going to do is I'm actually going to change the background color to a gray so we're going to go to page. TSX and we're going to start modifying the color I think I did it in yeah I did it in the layout so T typically you should be doing that kind of change in your layout so for the overall body I'm going to say that the background color is a custom color now I've actually grabbed this from a uh a design sheet that I was working on so I've got a background color and as you'll see now it very slightly changed it but the nice thing is it makes the white pop that's why I like it right the only thing that's bothering me here is in the header on that P tag I simply don't have a little bit of I just need a tiny bit of padding on the phone there you go that's nice yeah it's tiny bit of padding and then it goes to a bigger padding on a desktop that's beautiful okay so how do we get that really nice gradient effect that you see here because it changes up everything right so what we can do is we can go over to our header component so I'm in the header component and what we're going to do is we're simply going to add in a basically a hidden div right so we go inside the div that's responsible for outputting everything and here I'm going to add in a like a hidden div right right so they're going to go and say div and this is basically an invisible div that will act as a gradient now here's a trick we're going to say class name and I want this to be absolutely positioned ac across the ENT High screen that's what I want right I want it to be top of zero and what I'm going to actually do here is drop it down like this so you guys can actually really see what the rules are I'm doing right so top of zero left of zero that means it basically goes to the top left and then I'm going to expand it out right so the width should be four so if you think about it now it's expanding the entire page starting from the top left right the height should be 96 96 it basically goes down to around this length which is perfect that's all I want right I don't want it to go across the entire screen then I'm going to say it should have a background gradient which is to the bottom right right so as you can see I save nothing happens because I haven't specified what the colors are for the background gradient okay so I'm going to say from Pink 400 two um and I've got the nice that blue right that really nice blue uh let's go ahead and grab it and again I want you guys to customize it and what I love is if you customize yours and then do a little screenshot send it to me on Instagram I'd love to see what you guys build out of this right so let's go ah a and hit save and now you can see boom we get that now as you can see everything's hidden it doesn't look that does not look like that how do we get it there right well very subtle changes what we have to do it's simple we have to round the corners yeah and as you can see now we've got a nice little Roundy Corner that's that's definitely not going to do it though right we have to say filter cuz we're going to add a filter to this right and this basically prepares the browser for what we're about to do then we say blur 3 XL now you can see o we get this nice effect going on then what we can do is we can say the opacity 3XL you say opacity is going to be 50 right now you can see it goes behind as in like well it's a lot harder to see but we still have a problem here right it's it's like in front of everything so what we do here is we use something called Zed indexes so I'm simply going to use a minus Z index of 50 everything else basically so Zed indexes think of them as layering so by setting a minus Zed index so minus Z of 50 it's basically going to the back right and then what I can do is if I really want to control things I can say minus Z 40 will go in front of that one and then it can go all the way up to Z 10 20 30 40 50 or whatever right but the point is that you can then stack the layers As You Wish cuz sometimes you might have an issue where just like now you want something to go behind another element okay so um yeah hopefully that helps you out right I'm very happy with this so now we are going to proceed to the next part so we've got that looking pretty nice so let's go ahead and do the start with the board right we're going to be coming back and forth moving around loads but this is where we basically get you our hands dirty right so let's go to the page and here we're going to go ahead and remove this and we're simply going to go ahead and put a board in play right so I'm going to get rid of this like so now the board let's go ahead and create this component so I'm going to go ahead and create a component here board. TSX and then I'm going to say RFC right you can go ahead and get rid of this and then we have our board go back to the page simply import it like so so go ahead and do control space bar bam we have our beautiful board right looks great right so this is looking pretty good right so this is going to literally be our top level page so you see your page by the way should always be a highlevel functional sort of element right it shouldn't be every bit of logic is it your page level should break things down into a way that is concise and it's just clear to see that is my header and my board that's my page and then everything goes goes deeper than that okay that's how you should be building your apps yeah so now let's go ahead and start with the board okay so the board lots of different elements here right we've got this nice to-dos we've got the different columns and so forth the library in fact that we're going to be using which I think we should begin with is actually going to be called react beautiful DND so in this case let's go ahead and search for it right now so react beautiful DND and in this case you can see if I go to the actual Library itself with atlason which is actually the owners who bought out um they own jira they own Trello so yeah you might have heard of them right so here you go react beautiful DND D scroll down and you can see a nice demonstration of how we're going to use it so this is their demo I think ours looks way better though so we're going to build this instead right so why are you not using JavaScript instead of typescript so a lot of people get confused about this JavaScript is your language typescript is a super set on top of typescript on top of JavaScript so typescript is basically adding strongly typed power to your your JavaScript coding right so it's not you can't do one you can't do typescript without JavaScript so yeah so in this case we're going to build this so how do we do it let's go ahead and install that's the first step okay so we're going to go to installation and I'm going to show you like I said I want to show you all of the steps so we're going to go ahead and install this into our project right so command J head down to zsh boom and we install react beautiful DND now as you can see they've got prob don't get confused you know sometimes you're going to see different examples different tutorials all this kind of craziness but the main thing is you need to import drag and drop context into your app that's the first step right um so we're going to go ahead and pull that in so we've installed that command J to hide the terminal we're going to pull in the drag and drop context from R beautiful dndd now you can see it's complaining some libraries will do this when they do this I want you to go ahead and hover over it and a lot of the time it will give you this little command here where it says you can install the types cuz what's happening is it hasn't automatically connected the type definitions or the types the types from uh the typ script definitions um automatically when we did it so what you have to do is you copy that command and what this will do is it will save the developer dependencies and all the types of this now most cases it will find it just like so and in just a second that will disappear okay so that's how you go ahead and get rid of that then what you want to do is you can go ahead and check out how you can use it so in this case this part honestly was a little bit sort of Hit and Miss I had to check out the get side the s all this kind of stuff but I'm going to try and make it a lot more easier for you okay so you don't need to do any of this I'll show you how we do it so this is basically uh a nice little demonstration you have your drag and drop context then you have your droppable parent and then you have draggable elements within okay so you have to have your drag drop context at the highest level your droppable area and then dragable stuff within but remember we actually have two nested layers now what we have is the ability to drag each of the individual columns so I can get my D column move it over there I can get my progress column move it over there and so forth and then inside of that I can move the to-dos across each of the columns right so we've got a bit more complexity here so I'm going to go ahead and showcase how the hell we do all of that right I would love to see a markup being done live and then making it in reality personally strg fig designs oh sure dude do something like that okay so you can go ahead and read this out if you want and check out the examples I'm just going to go ahead and start jumping into how how the hell we build it all right so let's start breaking this down step by step right first thing we're going to do is the parent the overall outside we're going to go ahead and say drag drop context right so this is our parent then as I mentioned we're going to have a droppable okay so we're going to go ahead and put in a droppable cool all right so this is going to be inside of here so we're going to say droppable uh droppable yeah now this droppable you have to give it an ID right so in this case it's got the dropable let's close it out there we go you have to give it an ID so we're going to give it an ID a board okay then we're going to give it a Direction so in this case I want this is going to be a horizontal board okay so horizontal the reason why is because these this first dropable is basically I'm going to be able to grab all of these different things right so you see this right here I should be able to pull this entire to-do list this section and move it over there right so we're not addressing each card yet we're addressing the entire columns so that's the first level we can move this column over here and so forth right so that's the first step so the first one is going to be a direction horizontal not vertical the type is going to be something called a column cool right now what we're going to do is this gives you something called render props so basically a child of this is given to us so we can go ahead and get something called provided so you can see I've got provided here right now as you can see I'm doing parentheses this means that in my jsx block these curly brackets I returning something here so it's like an inner function really right so we're going to render out a div and inside of this div we're basically going to render out all of the columns okay so I'm going to show you how we're going to do it so this is basically going to be rendering all the columns right cool so at this point I'm going to do a little pause because what we really need to do here is actually go ahead and prepare ourself for what's to come right we don't have any anything that we can actually map through yet right so what we're going to do is we're actually going to pause here we're going to implement the upright section of the build and then we're going to go ahead and um and then we're going to pull from upright get our columns our board columns and then we're going to proceed okay so it's going to be a bit of a step but we're going to do it um so let's go ahead and do that right now so we're going to go over to Upright so you want to head over to upright and simply type in upright Cloud you should see the cloud. upright. so first things first you see I have a first app over here I'm going to go ahead and create a new project so we're going to create a new project project I'm going to call this one let's just call it the Trello YouTube clone bam hit create and as you can see we created our project now you can go ahead and they made it extremely easy over app right to go ahead and get set up with our projects we're going to go ahead and add a platform in this case we're going to add a web app so I'm going to click on web app you have to give it a name so naturally I'm going to say something like Trello YouTube clone and the host name now in this situation once we employee this will be the host name of the deployment domain yeah ight is free yes yeah the host name here we're going to say Local Host and we're just going to start off with this right then you can see we're going to click on next now you can see we can install so they make it really easy for us to carry on and get this set up so I'm going to go ahead and install at this point so instead I'm going to pull up my terminal install app so mpm install appp wait till that's done now in our true fashion the way I use usually do things on all my streams I'm going to go ahead and hide this out and simply go to the bottom I'm going to close everything out and at the package Json level I'm going to create a file called appts right and this is going to be where we essentially set everything up so I'm going to do an import of all of the things I'm going to need all right so in this case I'm going to end up using all of this stuff the account the ID database storage and so forth we're actually not using the account today we're using all of these instead right I'll show you how you can initialize even the account right so that way kind of in case you decide to use it you can use it so I need to go ahead and initialize my client so in this case const new client now how do we actually go ahead and get set up with it so you see if we click on next it will tell us how to set the project up in this case I've got a project ID you know is open so I'm going to go ahead and copy this ideally I might have to you know create a new project cuz that's that's already shown but anyway it's mine now so we're going to go ahead and do this right now so cons client equals this and so you want to go ahead and copy this and do it right here so in this case I've already done it was a set endpoint and then right here we're going to do https Cloud upright V1 okay so this is actually the the thing that we're going to use right now okay then we're going to say set project and instead of doing a default value I'm going to say process. environment. next public ight project ID okay this is a is actually going to be a public variable so next public symbolizes that this is going to be um this is actually going to be available on the client right if we don't have this it's only available on server render components and the backend stuff so we're going to go ahead and add this in and this is going to be something I'm going to say is absolutely there okay once we go ahead and set that up in just a second then what we can do is we can go we can initialize everything off of that client so we can have the account the database access the storage or by setting it up like the following and then we can simply just export it like so okay ID gives us unique identifiers that's going to be pretty handy right right so now we go ahead and hit save this is great right we've got everything looking pretty nice right now so what I need to do is set this up so I'm going to go into here I'm going to create a new environment variable so EMV do local and inside I'm going to go ahead and pop in my project ID now my project ID in this case will be this one so I need my project ID so I'm going to go ahead and pop that in like so hit save and as you can see in my terminal if I go back to the first one it will say found a change in your config it's going to oh no sorry it will say your environment variable ignore that we've fixed that one so that will be gone in a second but yeah we've done that there we go that's our project ID then we can go ahead and click okay and you're ready to go take me to my dashboard so they have a really great dashboard at upright that shows you all of your reads your wrs your usage your storage your functions that you're running your authentication all of it is available here and you even have access to your API keys so a lot of this stuff is pretty much self-explanatory once you're set up right so next up we're going to go to the databases tab and this is where we start setting things up the way that we need to okay so what I'm actually going to do just for my own reference is open up my other Cloud ight windows so that way I can remember exactly how I set up the structure of the database cuz I don't want to mess it up and I want it to be fairly smooth tutorial for you all so first things first we're going to create a database so let's create our database now this is going to be called our app database so I mean this could be really anything we're just going to call it the app database right so this is where everything is going to live right so let's just call it um yeah just call it app database right app database doesn't really matter let's go ahead and create create so inside of our app database we have our collections right now the difference between this and something like Firebase is you can predefine what the attributes are so that you protect what is added into your database which is something that I actually really like okay so at this point now what I want you to do is I want you to click on the um Collections and I want you to create a collection called to-do okay so we created a collection called to-dos and inside of to-dos now we are going to go to the attributes Tab and here we basically set up how our you know our attributes for each entry will look okay all right so we're going to go to the title here so we're going to call this first attribute the key title the attribute type so let's go ahead and we're going to say this is string okay then you can give it a value so the size sorry in this case the title of each one I mean you can really play with this yourself we're going to say 512 okay and we're going to say that the title is actually a required fi so you see we've got some control here it's kind of a mix of no SQL but yet we have the SQL constraints right then we go ahead and add a few more we're going to add the status this will be like in progress and done that kind of thing and in fact you can even make this an enum if you really want to so in that case what we're going to do here is go ahead and do enum and this is going to be this is going to say the following it's going to say too it's going to say in progress and it's going to say done these are going to be the three states of our app right so now we're going to go to the and we're going to accept that so that's pretty happy right we're going to click create to H you can say required for that but I'm only yeah we'll see I'm going to leave it as I'm required for now and then we even going to have an image now the image is going to be essentially something which is not required but it will be something like a past value and that's basically going to be the storage location once we upload the image to app right cloud storage right so in this case going be IM it's going to be a string as well in this case I'm just going to give it a 512 and we're going to leave it for that for now so now we've got our initial setup okay so what I want to do to get set up with this is I want to go ahead and just add a few test things right something which allows me to go ahead and get started with things in a nice way so I'm going to go for firstly start off with create document right so sorry um I've completely gone blank yes so I'm going to go ahead and say create a document and the first one is going to be something along the lines of let's just say take take the dogs out for a walk select the enum see to do in progress done I like that right very simple okay so let's go ahead and do that right now to do and then remember all of these by the way we can go ahead and protect it in typescript in our code as well all right so let's go ahead and do the image image we're actually going to leave blank for now and we're going to click on next create and that's fine now for this tutorial I am not enabling you know security rights right so in this case I'm going to say update permission I'm going to say we're actually going to allow anyone to create read update and delete but you can add authentication and then protect based on the user who is logged in similar to how we do it like Firebase rules other platforms and such forth so you can have that functionality here as well right so now we've got an example of a document take the dogs out for a walk it's a to-do great okay so that's the to-dos set up for us right so now the next step is that's our basically our our structure of our our to do are going to be stored okay the storage bucket so let's go ahead and prepare our storage bucket so our images that we're going to store inside of the app you see the images here for example these are going to be stored in an image bucket so in this case just create a bucket called images right so this going to be images create the bucket and inside of here we're going to go ahead and you see we're going to basically have let's go ahead and show you if we go the settings we're going to have permissions and any and in this case again as I mentioned I'm just going to allow anyone to be able to create read right update and so forth but eventually you can go ahead and feel free to extend this build add authentication and protect it so that only when you're logged in you can modify yourself all right so in this case we got the images right here so we've got the images and database set up okay so let's get started with how we can actually go ahead and integrate this now so the first things first is I need to go ahead and take reference of the database and collection IDs okay so in this case I'm going to go ahead and actually I'm going to hide something here I'm going to show you how how you can prepare it and then I'm going to hide me actually adding the values because I don't want to show certain values in case we get spammed and so forth okay so in this case I'm just going to go ahead and pop it in here so the first value I want you to know about is the next public database ID okay then we're going to have the next public to-dos collection ID so where you get these from is very simple inside of appy at the top of the app database you simply copy the database ID and you can simply paste that in so that one is fine I can sh that inside of the to-dos we can click to copy or you can go ahead and click in and you can copy it here so what I'm going to do is I'm going to copy this in and pay I'm going to paste this here and then I'm going to go ahead and hide this uh save and hide the environment for our screen okay so I'm going to go ahead and actually show my face for a second paste it in hit save I'm closing that file so now I've got all of my environment variables in the right set right so we've got access to all of the variables that we need to basically make a connect connection to when we fetch our information okay so next up is we need to go ahead and handle the board logic right so I just need to figure out where I'm fetching again in my in my flow so in this case okay I understand so this is where we start using some form of State Management so what I want to do is when this board loads right so when this loads I need to go ahead and essentially so first this is going to be a client component so this is a client side component because we're going to have an element of client side stuff happening here okay so we're going to use a use effect and if you didn't make it a client side component you will not be able to use something like a use effect any hook you won't be able to use okay so at this point we've got the use effect and this is where I'll essentially be calling something like get board okay now this get board now this okay so let's let's describe our problem that we're about to face right firstly smash that like button we're nearly at 700 likes so the problem we're we about to face is I need to fetch the board data then I'm going to need access to this all around my app so I need to basically access this board information you know all around different places of my application okay now by the way if you do get stuck on the use effect part we have a huge tutorial on this on the channel just type in Sunny use effect on YouTube You'll see a great tutorial which explains the rules of hook how you can do use effect and so forth right it's going to help you change your life right I promise you when you understand use fact is great okay so at this point we need something which is going to fix the problem of allowing us to fetch the board here but use the board in any point of our app okay so this is where you introduce something like State Management right so State Management libraries typically include things like react context API or something like Redux but there's a game changer now and The Game Changer is called zand right Z stand is is sick I actually I was told about it from a friend of mine but now oh my God it's it's it's really good right it's so good so zand you if you head over to zand Google it you'll find Z stand you'll find this now it's literally this is the amount of code you need to write a store like what it's crazy it's so good it's so good like I'm not joking it it's so so clean right and it's I like I couldn't believe it when I first saw it I was like no it's not going to be that good then surely nothing's that easy to sell up that good but yeah it really is so we say mpm installs the stand okay now let's create our first store so I'm going to go ahead open my folder up and I'm going to go here I'm going to create a folder at the top level called store now the first bit of information I'm going to store now typically what I always say is when you have something like State Management Library you should have different slices of your store so that way you can contain different bits of information at different areas so first thing we're going to have is containing most of the information about our app we're going to have something called a board store then we're going to have a model store for keeping track of if the user opened or closed a modal so at this point we're going to go open that up and we're going to Simply say board store. TS okay now inside of our board store we can basically go ahead and start reverse engineering what that demo tutorial tells us so I'm going to go ahead and show you right here first create a store so I would I want you to Simply copy an example like this simply like put like that right then what you're going to have is you're going to have a bit of a complaining issue with oh no you need to set up and blah blah blah and do that kind of stuff right so I'm going to show you how we can correct this because we're using something called typescript now they have got an example down here I believe where it's typescript and it shows you how to do it so here you go so when you use typescript you actually can go ahead and pass in the state but I will go ahead and make this a lot easier for you to understand so you don't have to worry about all of that right so first things first right let's go ahead and create our source we're going to say use model store oh use Board Store sorry we're doing the board store first okay then I'm going to create an interface which is basically like a type definition we're going to say board State and this is going to be everything that we basically contain inside of the board right the yeah board so in this case we're going to have a few things inside of this we're going to have the board itself the board is going to consist of you know all of the information you see here the different columns with the to-dos inside all that good stuff so that's going to be the first thing this is going to be board and this is going to be of type board which we haven't got yet right I'm going to create that afterwards right so this is going to be of type board then we're going to have the get board function okay so we're going to start off with these and this is going to be a function which is not going to return anything okay so let's go ahead and just simplify this now so we've got a board and initially this is going to be a uh let's just start with a no value and I will fix this afterwards okay we're going to say the get board function is going to be a function that does something okay so now you can see the arrrow have disappeared except for this so we need to Define what a board is right so in this case we need to go ahead and do command B and I'm going to go ahead and create something called a typings dod. TS file inside of here we can create some type typescript definitions right so inside here I'm going to say typing. D.S now here I'm going to say interface now welcome to the world of map objects so I'm about to blow your mind if you've never used that map object I thought it' be cool to do that you can actually do this build probably simpler with an array like the the library is built for an array but I want to show you how you can manipulate things and change things and change an array and map through it map through an object and in so many ways and yeah I I want to make your life a little bit difficult at time so you learn okay so in this case let's go ahead and show you the harder rout right I could have done this with it ra easily but I want to show you the harder rout so you understand how to do this because honestly you're going to come to a point in your career where you going need to know how to use a map right so we're going to say the a board will simply have a map inside of it and a map you can basically specify what the key value pairs are so I'll explain this in just a second right now inside of here you can have something like a string string right now if we were to do this all this means right is a map is very simple right a map consider it like a bunch of entries right so you've got basically a list so think of a list right a really easy list each item in that list has a key and a value so the key could be like you know sunny and inside the value could be like all the details about Sunny then it could be J and then it could have all the details about J you know you could have whatever key you want and the best thing about map is which is kind of cool is the key can actually be anything it could be an object it could be a hash it could be a string it can be a number it can be anything you want right so it can even be an object the key right and the value can be anything as well and it's really cool because once you interact with these it's quite efficient because you can just say get this exact key see if we've got something in there and that way you're doing a direct index check right so now what I want to do is I want to customize the two types so the first thing is I'm only going to have three types of keys right the types of keys I'm going to call them typed columns okay and this is going to resemble the to-do the in progress and the done so in this case the type column is going to be basically an enum so it's going to be a to-do it's going to be either to-do in progress or done and this is not going to have a space it's going to be very simple so it's either to-do in progress or done and the key is going to be a typed column so the key will only be to do in progress or done ever done okay and then we're going to have a column inside each value right so this is the powerful part about typescript so let's go ahead and type out that definition so in this case I'm going to say interface column and now this will have an ID and the ID of that will be a typed column oops sorry typed column so the ID of our columns will either be one of these it'll be a to-do an in progress or done and then inside of there we're going to have an array of to-dos okay so we're going to specify an array of to-dos which we haven't specified what a to-do really is yet so we're going to say the interface have a to-do and I've defined this structure based on the response that you will get back from aight that's why we've got a few dollar signs and all that kind of stuff here right so in this case we can say dollar sign ID string and we're also going to get back something called the created app time stamp and this is going to be a string we're going to get back there and then we're going to have a few of our own values so we're going to have the title the status do you remember we set this up we had the title we had the status and we had the image and the image is actually you know it could be an image or it might not have an image right so in this case some have images some do not have images okay and so forth so in this case we've got our our interface then we can go ahead and do interface image some people asking yo when should you have an interface or type interfaces can extend pretty easily so you can say like a column extends a to-do for example and that's when you typically that's very simply put that's how you can do it right so if you want to extend something just use that but yeah you can use either or I like to say in these situations use a type in this case for main objects I'm using interfaces right so interface image for the image each of the images are going to have a bucket ID which is basically going to be the ID of the bucket so remember that images storage container that we set up just to second ago and then each of them has got its own file ID that's how we locate the image okay and this image is actually going to be referenced here sorry I messed up the status as well should be a typed column I went into autopilot right so the status of each to-do is going to be either to-do in progress done the image itself is going to be one of these types so now you can see we've got a really nice set of type definitions and this will protect us from making a lot of Errors okay cuz it will scream at us if we screw something up so now we've got the board right so so let's go to our board store now now what I want you to do is inside the board store yeah what we do is we can initialize the board when we set up the used board store so this is basically the type definition and all we do here is we say create and we pass in our board state right and then it will know if you're setting things up correctly so now I'm giving it a value of no to begin with and it's saying whoa whoa whoa you cannot do that because that's not a board state so all I'm going to do here is Define something which satisfies what board is so in this case we have the columns filled and it needs to be a new map and remember what I said guys a map is a typed column and a column type right so the key is a typed column the value is of column type okay and then we're just going to invoke it so this will basically go ahead and create a new map for us with type column and column inside okay good stuff now then we're going to go ahead and create a function for get board this is going to be an asynchronous function inside of it I want to go ahead and get the board so I'm going to say get constant board equals a wait yeah and this is where I basically perform a fetch function okay so in this case I need to do two things I need to fetch it fetch the information but I actually want to fetch all of the to-dos and I want to group them so I want to actually group them by the different types okay so in this case I'm going to create a helper function called get todos group by column and what will this look like right what what the hell will this look like well the goal here is that eventually we will have something like this we'll have something like a map so it look something like this okay that's horrible what am I doing um here so we have this okay ignore me okay that's not working I'm going to just hack this away but okay so say we've got this so one of our keys for example will be to-do and then we're going to have each of the to-dos inside of this this uh field right so we're going to have all of our to-dos inside of here right and then it's going to be grouped accordingly so you've got your to-do you've got your in progress and so forth so this one will be in progress and so forth and they should all be grouped accordingly okay and then that way we can do the information that we want to do and we're basically going to pull from our database to handle that information right so get Todo is Group by column let's go ahead and do so and what I like to do is create a lib folder which is for utilities so in this I'm going to create a folder in the top level sorry so top level folder lib lib is like U folder same thing right and we're going to say get to-dos grouped grouped by columns bam done okay and now what I want you to do is go back to board store eventually this will give us back of value and then we're going to use something called set board and what set will do is it basically sets the global State here like so okay so it sets the Global state for that value so in this case it sets that that piece of information then you can pull it wherever you want okay so let's create this function so I'm going to go ahead and go to my get um to-dos grouped by column and now we're going to go ahead and set things up so the first thing I need is to basically create a function so we're going to say export const get Tod do by column right and then we're going to go ahead and this is going to be an asynchronous function which takes no arguments okay cool stuff easy as yeah fairly straightforward so far now I need to pull from the database so you see the database that we set up earlier so this database right here I need to pull the information from here guys right so I need to pull all of that information in so how the hell do we do it well we made our life a bit easier earlier we can simply say const p and p is basically a promise so we're going to basically return all the data let's call it and we're going to say await right and all I do here is I type in databases and we previously set up our data databases through our appts file so I'm importing that like so then I say list documents now here it's really straightforward all I do is I pass in the database ID and the collection ID you can even pass in queries and so forth afterwards and you can fetch the information just like that so now what I can do is I can go ahead and say process. environment process. environment. view no way we using view right so I'm going to go ahead and do this so I say process. environment next public database ID then we go ahead and hit color and then I'm going to do the same thing for the collection ID and we set these environment variables up earlier okay next thing I want to do is I simply want to console log the data so that way you can see what the hell is going to be on the screen well actually you're not actually going to see this right now because this won't actually be on the screen so what we can do to test this is we can go to page we can go to board we can actually go ahead and just um just put in hello uh we can sort of just comment this out for a second and then we can call our get board function so I will show you how we can actually set that up right now so we can actually test out what we're doing right so in order to get access to our board functions like get board all we have to do very simple hook right we just say const get board equals use board store right and have I explored it I think I have no I haven't okay um I believe we just got to do a simple export here which is why I've messed things up yep so we should do export my bad export con use Board Store there we go and we're actually going to even go a step first so yeah we can import that there we go and then what that does is it gives us the state and then we can go ahead and say state DOT and then you see we get the board or get board so now I'm mapping this to a available function so in this case we can go ahead and pass it now because we are using get board we actually have to include that as dependency but in this case we do that now what we should see is we get this right now you can see we're actually getting an error right now because we're not we haven't defined the get to do group by column so let's go back into our Board Store like so and I want to go ahead and import our helper function okay and this is obviously going to complain because we haven't got the right value so we're just testing right now okay so at this point now inside of my get todos I should see some data here logged out on so somebody says is this going to get executed on the server well actually uh we're instead going to go ahead and I'll I'll drop it a little bit yep no worries the background music so in this point you can see the um we have the get to do group by column right so this we go here and we simply are logging out so this is actually going to get executed um on the client so you see here we've got the object and by the way this eror that you're seeing I've got um oh no that's actually fine to be honest for now that's cuz we've got that error that we just had set up so yeah there you go so total and you you can see this is what came back guys look at this take the dogs out for hey that's what I'm talking about sick right that's exactly what we wanted and you see what I mentioned before there was there was actually more properties so you can feel free to add that in but I wanted to you know I just kept it very simple but you can even add in like permissions updated app collection ID and so forth into your type definition that way you can be sure that you get it back right and I reckon you can even go as far as to add get those exact definitions from um the guys over app as as well so I just didn't go that extra step right but you can right so I want to show you a bit of manual stuff as well so at this point we've got the documents flowing in which is great right so at this point we've got the data now we need to do some cool manipulation to you know mess with the data that we need it so what I'm going to do is p. documents so the data here that comes back what I'm going to do is I'm going to say const to-dos equals data dot documents okay so that's all my to-dos now so inside of here this list will be all my to-dos easy as now what we can do is if you actually go ahead and highlight over this models. doent so you can actually extend models. doent um and then if you really wanted to you could do your typings that way so you could actually go ahead and do something like this so interface Todo extends uh model document and now your to-do class actually has model document inside of it as well so if I was to do something like const a um to-do equals something this then you can go ahead and see for yourself that to-do we actually have a DOT um the stuff that we wanted inside of oh actually it didn't end do it properly but yeah anyway I need to import it and do that stuff properly I just kind of Rush that step so in this case models. document you would have to pull in correctly but anyway you could do that right so heading back over to our yeah yeah let's carry on so first step I want to basically map through and get the all of the so right now now we just have this list right and there's no coordination here so I want to basically rearrange this this so it'll become a key value pair where all the statuses are grouped together so all the to-dos all the impr progresses all that good stuff so I'm going to show you a nice little map function and again if you find this confusing then be sure to join Z zakuro or just check out some tutorials online but the point is we have loads of tutorials in the course that will explain how to use things like the map reduce functions and so forth so at this point we're going to say const columns right cons columns equals to do reduce and reduce is basically an accumulator function so what it means is you basically take you know your array and you're you're going to reduce it down into another form so if like let's just say a very simple example you got an array of numbers you reduce it down into a number for the total but we're going to do a bit more of a complex object right so in this case we're going to do a reduce down to a map okay so you probably wonder oh I don't know how that works how don't I do that right so in this case what you do is every single single time you iterate over you get a bunch of things so the first thing is you get something called an accumulator value this is going to be the value or the previous value basically that's going to that's going to rack up and build up so this is going to be the map object right that's going to slowly grow and then each time we map through we get the to-do itself okay so now inside of this function we can do a few things so basically oops at that so after all of this we do a comma we can give an initial value and this is the initial value that we want to start is is with a map okay so this map is going to have again a typed column and you can you guess you could just say you know you could actually use the the board column the board uh definition if you wanted but in this case I'm just going to say yeah new map with type column and column right so in this case now the accumulat value starts off as a new map right so what we can do now is we can access it we can say if there is no so we're going to access the um the map and we're going to say get Todo status so basically what this is doing is this is an empty map right now so it wouldn't have anything in there so this would actually be satisfied basically it would find this first to-do and it'll say is there a to-do and right now it be like no there is no to-do right so in this case what we're going to do is we're basically going to create a key inside of that map so we're going to say account do set Todo do status so what I'm doing here is I'm basically setting the first key inside of that right so ID to-do say and then we give it the the to-dos itself so in this case to-dos is an empty array so what we're doing is now the end goal would be you have something like this so you would have something like a object which is going to have um no sorry a key value pair so every single one is going to have like for example to-do and then inside of to-do you would have key value pairs so loads of key value pairs here and then for example this would be all of your like I'll show you Afters I'll map it out right it'll be very easy to understand right but this will basically grab all the to-dos together and it creates an empty to-do and then once you've done that step once the next time it comes across a status with to-do we're simply going to push it inside and I'll show you how to do that right so here we say a account or like the accumulator get too do status right uh to do do status too do status I'm going to say that it is there because it should it will be there because we literally would have created it here and then we're going to say to do todos so it's going to access this Mt array todos do push and then what we're simply going to do is push in we're not going to push the entire to-do in but instead I'm going to create an object out of it right so we're going to say that the ID is pushed in so to do ID the created and if I do control space you can actually see we've got already got our perfect functions here as well as in our perfect attributes so we're going to go ahead and add in the title as well so the to-do title we're going to add in the status which is going to be the to-do status this again is being pulled in from the back end right now the final one is actually interesting so what I'm going to do here is as I'm pulling it in I'm going to do a nice little spread trick okay and what we're going to do is we're only going to fetch the image here in this object if it exists from the response okay so the way you do this is simple you basically say spread right and then you have a condition so now this is exactly this is actually perfect yeah we say too image and and image too image so basically what we're doing is we're saying if the response that we're mapping through has an image cuz remember some things may not have an image inside right then we're going to go ahead and append this inside so basically imagine it's doing this and then it's spreading it so it basically pops it so you're basically taking this if there's an image you're taking it and adding it there like that that's exactly what's happening if there's an image okay so in this case this is how it works now when we push the information into the database I will be storing as adjacent string of vied value for the image stuff I'll get to that later but for now when we do eventually pull it we're going to need to pass that information back into its full object okay so at that point we simply go ahead and close things off right and then what we do is we return the accumulator function okay so now with all that done what we can do is we can save and I will show you if I simply log out The Columns now what you'll see is we go from this horrible looking thing right the response to a map and you can see look the map has a to-do entry and you can see the to-do entry has one value inside of it which is the record and it has a value with the to-dos inside and then it has everything in so what we've done is we've transformed data so we've taken an array response and we transformed it into a map and I'm going to blow your mind now by adding another to-do I'm going to add a few to-dos here and show you just how powerful this really is so crush the live stream I'm going to say this is in progress because that's exactly what we're doing and then we're going to go ahead and do next create and we're going to do another one so we're going to say uh create document and I'm going to do another thing here just like so I'm going to say um let's just do Finish the build finish the build and this one will be in progress right so we got two in progress is one toss so that way we can test this out so create Okay cool so now we've got a bunch of stuff in this so if I refresh now you will see that we have a map of two right but I'm going to show you what we actually ended up transforming here so as you can see this is the the the app and then what I'm going to do is I'm going to first conso log the response so if you see now this is the entire response that we get back so I'm going to go ahead and refresh so the first one is the entire response we get back you see look this is literally what we got back right it was just a bunch of like to-dos from the database right and there's no you know there's no actual mapping here really like what status is this and what status is that now what I've done is I've grouped them all together and I've got this nice map so you see my first entry the key is to do the second is in progress and then what we're doing is we're grouping them so now you see the value here is an array of two and in this one there's one array for the to-do and the in program we have two to-dos so if I go inside now you can see I can see all of the to-dos inside so this is called transform transforming data it's really important when people ask about data structure and algorithms and stuff like that this is basically how you you should be you should have an understanding of how to transform data and don't worry if you don't again this is why I have a lot of this stuff inside the course that's where I can teach you at a like in-depth level so Zer to four. Career we do this we teach you and inside of coaching course and module content we have a mixture of ways to get you to understand this in a really Crystal Clear way so all of this is fairly straightforward okay so absolutely killing it let's carry on so at this point now we have our columns okay now I need to do one more thing right I need to basically say okay now we always want to have all three columns shown but what if for example now I've got too and I've got in progress but I don't have anything in done okay so what I need to do now is I basically I'm going to create a little function here which is going to ensure that we always have you know each of the The Columns with a empty to-do array inside of it so it's always going to have a populated empty to do array so what we can do is I'm going to go ahead and get rid of this now we don't need our comments here and I will show you how we do it so if the columns doesn't have an impr progress to-do or done add them with empty to-dos right because what happen is what might happen is you delete everything and then you need to go ahead and do it so let's go ahead and do this now so I'm going to go ahead and create an array of all of the different typed columns so in this case to do in progress done okay and then I'm going to go ahead and loop through them okay so I'm going to save for each so I'm going to do an old school map here you can do either or I'm going to say for each column type column type of all of the column types we're going to map through you can do a for each you can do whatever you want so we're going to say if that there was if there was no that's perfect actually that's exactly what we wanted so that's exactly what I've got written as well so if there is no column so basically in this case remember we had it to do we had an in progress but it wouldn't have found a done so it would have basically satisfied here when it hit done when it Loop through then it will basically set the column so there is now a done and then it will show the uh a to-do it will set a to-dos that way when you map through it won't it won't break it will be we'll be able to render out that column all the time okay so now that we have this in place what we can do is the final step is I always want to show them and this is this is kind of up to you now right in in my tutorial I always want to show to do in progress done then you can rearrange it but when you whenever you come on the page I always want it to be into do in progress done I always want it in that order okay so I'm going to go ahead and sort them in that order right so in this case this would have manipulated that array previously so now we've got all of them so if I was to even console log The Columns now you'll find that we have a always no matter what we will have a map of three right so let me refresh you will always have a map of three yeah so now even if you've got done you see inside of done we still have it to do array of zero so now we've always got all three perfectly like so okay so this is exactly what we wanted now after the columns we're now going to sort the columns right so I'm going to sort them based on the initial order that you see here all right so sort columns by the column type so I'm going to say const sorted columns equals a new map and what I'm going to do is I'm basically going to generate it's this going to be a sorting function again we cover all of this inside Z to4 St because it can be a little bit scary right the first step I want to do is I want to convert my column entries into a um so there's two ways to do this but if you want to convert your um your your map you can do something called dot entries which will give you all the key value pairs in an array so what we can do is we can create an array like so yeah or you can say array from there's two ways you can do you can say array from or the real es6 way is you basically create an array like this then what we do is we spread out the columns which basically means get all the key value Pairs and create an array from it right so now what it's done is is it's go all the key value Pairs and then it spread them out and tell you what that's why I didn't do it last time yeah so array do from columns. entries right this actually is a bit easier to understand I guess as well right so you've got we created an array from all the column entries this will give you again all the key value pairs uh in an array format right then what we can do is we can use all we can use array sort of mapping functions to go ahead and do all of our stuff these are all array functions now so now we can say sort now with a sort what what you do is you get AB so AB is basically the comparison part now AB refers to every it will Loop through two items at a time and every single time it does the first item is a the second item is B and you can do a comparison where you basically say if this is that and blah blah blah and then basically you can move around you can sort the objects in whatever way you want then what I'm going to do here is make life very simple I'm not going to do the curly brackets I'm going to do something called implicit return so basically I'm doing parentheses and then because it's a one liner it'll get rid of the parentheses and what we do is we simply say index of so column types so this one right here if the index of this right so the first value this is the key of the first value is like basically this is doing a um like a string check so it's basically checking if this value is less than this value and so forth and basically what it's going to do now is it's going to sort them in this order so if they're not in this order it's going to rearrange them to hit this order okay so now for example if it fetched all of them in different random orders now or you move them around it will always fix the order when it refreshes okay and then what we simply do is we say const board so we get the entire board as a board object we go ahead and a board object simply has columns inside of it and then we give it the sorted columns okay just like so and then we return the board so this has been our helper function this is our helper function which gets us all of our stuff that we want so now this will always get us all of the data and make sure that we always have those key value Fields populated with the to-dos empty if there is nothing inside of the to-do so we hit save now go back to board s and you'll see it no longer complains because it is getting a board back that's great now what we can do is we can go back to our board. TSX and over here what we can do is we can console log the board and you can see now oh we don't have the board how do I get the board now right how do I get the board from the orinal original Board Store well I need to do you could do the same line again and do you know something like this and board stateboard I guess you could do that but that's you know who wants to do that when there's probably an easier way right so in this case you can actually combine so every time you want to get something more than one thing from the same board store or same store in in zand you can make an array and you can basically say I want the board I want the state and so forth so in this case I want the board and I want the get board and then all you do is on the return you simply make that an array and you simply say state. board and now you can basically have this beautiful set of uh oh got to just save the HTML now you can basically pull in multiple things get it back and then we consol log the board just to see if we're actually getting something back simply hit a refresh and just like that guys now we have our columns in so initial arrenda was Zero because it has to fetch then we do the columns and as you can see we've got our columns we've got our arrays being pulled through so now we have the column to map through the objects that will be shown on the screen okay so let's do it yes you can um you can do it loads of different ways again right you can really mess around and do it however you want I'm just showing you a way to do it right so now we can uncomment this out and we can carry on from the dragon drop perspective so let's carry on with this so we've got the div inside right remember we are now we're going back to the beautiful Dragon drop example that we were talking about earlier so let's head back over to this example and as you can see we've got this situations we've got the drag drop context then we've got the droppable Zone which is this then we've got the dragable elements inside Okay so we've got this thing called a render prop so in this case we're going to render out uh every time we run through it you also get something called snapshot so here you can use something called snapshot and that's basically if you're dragging you can change color and so all that kind of stuff I'm not going to go too far into it but now what we can do is that map so that column that board sorry what we can do is we can actually say array from right because remember we can't actually simply map through uh a map as in like literally you can't Loop through a map easily you have to change it to uh a board so in this case you say board board columns uh entries so we go through all the entries and now we can map right so now I can say map and then what we can do is inside of there remember you get key value pairs so it's not going to just be like this it'll be like it won't be like something like that it'll be your key value Pairs and what we can do is we can do something in es6 called destructuring so we can destructure the ID and the column and then the second argument will always be the index okay so in this case it's always going to be a second argument there and what you can do is you can wrap the entire thing in parentheses like so and then you have an arrow function and then you can return something that you want to Loop through okay so again just take your time with this step and understand what's happening we're converting the board columns into an array we're creating an array from that we're then mapping through all of the key value pairs I am destructuring so that way I've got the ID which is a typed column and the column which is a column remember that map it was always type column column let me get the index which is basically it'll start off with 0 1 2 3 4 as it Loops through then we're going to map through and basically output a column so in this case if I was just to do an example here and do uh let's just let's just start into it let's just do a column okay okay so this is where our column is going to go now the column itself we're going to build right but it takes a few arguments it's going to take the ID and then we're going to pass through a couple of variables ourself so we're going to have an ID that we actually need to set it's going to have the to-dos itself which is column. toos and then it's also going to have the index itself okay so in this case that way we basically we need to go ahead and create that right now before we hit save and continue on we need to ensure something something happens so this div here whenever we have a dropable right the first child of that dropable when we when we actually put out something we have to go ahead and spread certain props so what I can do is I can say dot dot dot provided droppable props and then we also have to do dot dot dot Prov um sorry we have to do reference equals provided in a ref okay and this is basically how the dragon drop is knowing what the hell is going on okay so for this column now this will eventually have a arrangement of grid right so we're going to have it on a mobile view will be one grid so literally be all of these will be stacked up on each other like going down and then on anything past a um I guess a medium screen it will be a grid of three okay so this is where we Define that so here we'll say class name grid grid columns one on the medium screen it'll say grid columns 2 uh three sorry and then between all of them we're going to have a gap of five the max width will forever be 7xo and we want to center it right so MX Auto there you go hit save cool this is complaining because you need a special function here called handle on on drag in right so here let's just go ahead and satisfy this quickly we're going to say UND drag end and we're simply going to create a function called handle UND drag end so over here underneath the use effect I'm going to say const uh handle on drag end right and this this one is basically going to have something called a drop result so this one right here if you in case you're confused if you hover over this you'll see UND drag and responder but if you do a little trick here and do e Dash you'll notice you get the type definition you can paste that type definition simply import it like so and then you can get rid of the E so that's a nice little types script trick if you didn't know so that'll get rid of that so I'm not going to show you we're going to build out this afterwards now that's basically what happens when you let go of a drag and drop operation okay so right now our app is in this weird State because we haven't built the column we've got a lot of things overhanging so let's build out each of the columns now right and this is going to be the droppable and draggable elements and so forth right so I'm going to go ahead and get that done so again we've got a lot to build so we're going to move fairly fast RFC okay so now the column so inside the column now we're going to start off by saying that this is a dragable right remember if we look again a beautiful D and D this is going to be one of the columns is going to be draggable right so we were previously in the droppable which is makes sense and then the column itself is going to be a dragable which makes sense okay dragable like so okay now inside of here we have the same logic we have a provided and this will have a render prop right so this is going to render out a div and inside of here we basically do a bit more stuff so this is basically inside of here we're going to render out droppable render droppable um this is going to be the internal droppable um section so another nested droppable section for the to-dos in the column okay so that's basically what's going to happen so the drag ball now we passed in a bunch of props right when we did this you see these props key ID and so forth so let's go ahead and firstly set up our props like so it's in the correct way so those props were as follows it was the IDE it was the to-dos and it was the index right so we're going to Define these type definitions like this we're going to say type is props and then we're going to go ahead and say the ID is a typed column so you see now how types script starting to protect us right got lots of protection happening here so we're not you know messing up on in in any shape for it's going to help us correct errors beforehand and then we're going to say this is going to be a type of to-do and then we're going to say the index is a number cool right now we pass in our values so this is really really nice and then what we do is remember your first child of your drag ball element should be passing through all of the required props so this one will be dot dot dot provided dragable props and then we've also got something called drag handle props we have to pass through as well okay and then we've got the reference so in this case it'll be reference um there we go right so we have the provided NRF so that allows us to that basically tells the dragon drop Library what the hell is happening okay then we basically have to render the droppable to-dos so that section okay so now we're going to do the same essential nesting as we did here but this is going to now be for the next section which is going to be the internal bit so what we did just there before we set up a droppable zone for the entire thing and then each of the columns were a dragable element right and then what we done is we set up a droppable zone for the entire internal column and each of the to-do cards are going to be dragable elements inside right so you see how we're working with this now okay so inside the column let's go this is going to have a few things it's going to have a dragable ID we're going to use the ID that we passed through to do so it's going to have an index as well and we going to pass in the index these are the two required props now let's start rendering out the to-do's droppable zone right so here we're going to say droppable and this droppable ID is going to be the index so the index do to string okay so it needs to be a string value so we're going to say index and this is going to be type of card like so let's render that out there we go and then we basically do the exact same thing we have a provided oops say there going to be a jsx block provided and then we basically wrap this up God damn it yep and remember I said you also get snapshot oops snapshot so remember when I was dragging one of the cards over to another one notice how it went green every time it went like went over it went green what we were doing is we were using a snapshot object to go ahead and tell when you're dragging over a certain element and I'll show you how we do it we basically create a div inside anytime that you have this provided you have to pass down and connect that div so what we do here is we say provided. droppable props we again connect the reference trust me once this setup is actually really good and it's it's honestly so cool especially on your project to have and then we're going to use a bunch of class names now what I'm going to do is I'm going to give each of the card or the background of the card a bit of styling right so I'm going to do first I want to have some Dynamic values here so I'm going to do back ticks so notice I'm using back TS I'm going to say padding bottom of two I'm going to say that it should have a few things like padding of two all around um rounded 2XL so that's kind of overwritten that I guess rounded 2XL then we're going to say shadow small now I'm going to have a dynamic value now here what I'm going to do is if the user is dragging right so now what I can do is dollar sign Open brackets oh sorry we've already done that so I can say snapshot do is dragging over okay and if it's dragging over the background will turn green yeah so this is really nice how this is going to work and then we're going to say if it's not dragging over it's going to be a background of white with a 50% opacity so now it's the background is normally a 50% see-through kind of glass View and as you drag over it's going to turn green on the field that you're dropping it over okay so then we've got that set up okay the next step is we're basically going to Define The Styling for the to-do and so forth okay so now what we can do is we can say we have a H2 and inside of this H2 I'm actually going to have the ID itself so in this case I'll show you how we do it we say the ID now what you'll start to see inside of our app is if we go inside and we refresh we should okay so the column is not defined we haven't saved this file let's save this one let's go over here now you can see look we already have some stuff happening so it's not working yet but it's almost there right you see how things are happening but it's not it's not saving and things like that right but we're actually getting to a point where something's happening okay which is good it's very good right so now what we're going to do is we've got the ID so forth this looks ugly I wanted to say to do in progress the correct way so what I'm going to do is I'm going to create a mapping function up at the top simply go ahead and say const id2 column text okay and this is basically going to have a set mapping of the key it's going to be typed column and it's going to Output a string and what I mean by this is it's simply going to be an object of mappings if it's Sease to do it should write to do if it sees in progress it should see if it says in progress it should say in progress if it says done it should be a capital D done now what I can do is I can simply pass this through and say just like that and now this will change to to-do in progress done that's a lot nicer I prefer that right so now this is this was already getting there it's pretty pretty nice right so we got the ID to column text and then I want to have the length right so I want to have you know two 4 three however many to-dos are in there I want to see how many to-dos are in there so now what I can do is I can say to-dos oops let's just have it um let's do it in a way where I basically say I'm going to span an element here so I'm span and I'm going to say uh to-dos do length Okay so in this case like we got one to-do in uh one to-do in the to-do column two to-dos in the in progress column great right so then we're going to go ahead and start this out we say textt should be gray 500 background should be gray of 200 then we're going to say round it off so rounded full font should be normal we don't really need that padding X of two padding y of one and the text should be small there we go text should be small hit save and now we got these nice little circles okay and I'm simply going to make the two children inside it be flexed justify the space between them um I'm going to make it font should be bold the text should be extra large and the P2 there you go and the reason why I did yeah that's why so here I did font normal cuz I don't want that to be B font normal and just like that look at that already getting there right looking pretty decent so far and you can obviously customize that however you wish change it up you padding y should be to one that's it I wanted a bit more circular that's it looking good hey nice right and you see how look it's in this is exactly how we wanted it to look right right So eventually it'll be like really sort of clean now notice how they're sort of swiping all over the place is horrible right this is because we haven't set things up correctly yet right once it's done trust me I'll look really good okay so now what I want to do is I want to go to the um so underneath my H2 let's change your music up getting tired that music all right so the H2 T all right so we got the div here we're going to say space class name space uh y of two so this is going to be um basically all of the to-dos are going to come through here okay so what I'm going to do here is I'm basically going to check no so I'm not going to do the search string we'll do that afterwards here I'm going to say oops that should be space space X2 Okay cool so now what I want to do is I'm going to say uh return inside of here um well I'm not actually doing that yet uh I'm actually going to be doing just the dragable elements so I need to map through them yeah so that's right so I'm say to-dos do map for every single to-do I want to return the following right and then here I'm going to create a component called to do card and I'll show you how we do it but before we do that it's going to be wrapped in a dragable element so this this one's going to be dragable okay these going to be dragable elements again we go back to this same logic we were nested in another droppable element so now we have dragable Okay so we've got dragable and then here is going to be the key the key is going to be the to-do ID um the dragable ID is going to be the to-do ID and the index is simply going to be the index okay inside of it we're going to do our traditional provided render prop which we are we again we have to use and then we're going to render out a to-do card which we are yet to build okay now this to-do card will have a bunch of things inside of it it will have the dragable props the inner reference all that good stuff so in this case I'm going to just save us a bit of time and pass in those values from that provided down into cuz eventually the div inside of there will need that so we're going to pass that in as well okay now this is freaking out why exactly because we have this this is here and then we need another one there we go yeah so what we need to do now is go ahead and um yeah we need to basically create a to-do card but before we do that the final step here before we carry on is after all of this what we have to do is something called a provided placeholder now what this does is is when I drag something across to another column it creates space for it otherwise what will happen is you're dragging it over the column and then it's just like there's no space for you to put it in the placeholder basically says if I'm dragging over it it makes space for me so it looks like I'm dragging in it creates space it's really nice really nice effect yeah so we got the provided placeholder and then at the end of all of that we're going to have a button which allows you to basically go ahead and click to add a Todo and that's going to be the modal portion of this build afterwards so inside we're going to have a did with a button inside and this one is going to have a plus Circle icon right so in this case let's just hit save so plus Circle icon this will be class name of height and width of 10 so height and width of 10 and in this case the text Gray I'm don't want it that's fine right so the button itself will will have a few colors to it so let's go ahead and start this out so class name bam uh like so and then the div itself will be a centered button I just want it to be very easily it's going to be no sorry towards the end so items end it's going to be justified towards the end as well of its section right now before you're going to see that that's basically responsible for this so you see how that's got a little Gap and then we justify it to the end right so let's go ahead and create the to-do card and then trust me it's all going to come together real quick all right we're going to go ahead and create the new component let's go ahead and drop it in so we go ahead and create file to-do do to-do card. TSX RFC bam we'll pop that in like so and just like that now inside we're going to expect a bunch of props so here we're going to get a bunch of different props come in so I've saved us a bit of time I've already wrote the definitions for them and I've saved you a bit of hassle as well so in this case we've got custom type so you got dragable provable dragable props and then this one drag handle props can either be no or undefined so I've already saved you the hard work of figuring out what's what right so these are going to be all the different types that we need and then you simply pull your props through okay so this will be all the props that come through right now this is going to be a client side component so we're we're going to Simply say use client right now for this to do card we're actually going to have a div now remember when we have a provided parent you have to go ahead and pass down the props now U like the dragable props in this case we passed it over as a prop through right so in that case we can do it like this then I'm going to have a class name and here I'm going to say background should be white rounded MD so these are all the cards now by the way I'm styling these cards yeah just so you're very sure uh oh thank you Ashan I appreciate that randd then we say space between all of the cards or all the items inside the card and we'll give it a drop shadow of medium cool right hit save and now what I can do is I can go back and obviously this isn't going to say I'm just going to say H1 hello I just want to show you for a second let's go back here and fix this up and boom import that at the top what we should see now oh look at that guys now obviously right now you can see look at that look oh that is clean so right now obviously the the logic for it to stick is not done but right now look at that it automatically gets it over there oh man that's so cool look at that oh clean and look how smooth it is as well guys look this is how you do like a crossover drag Drop Zone sort of situation so at this point looking really really beautiful right so let's go ahead and oh I've actually okay that was fine yeah I guess I played it on the other thing I done something out muscle memory all right so in this case to-do card now what we're going to do is head over to the H1 hello we're going to replace that with the actual to-do so this is the fun part right now we're getting now we're getting somewhere guys let's go ahead and put this in so let's go ahead and now we're going to pick up some speed so we got the div inside of here we got a P tag and we've got the to-do title so to-do do title and look at typescript it's just so nice nice like this is why we do it because it honestly helps you prevent so many problems X Circle icon is basically going to be resemblance of this cross that allows us to delete a to-do from the screen right so that way we can actually delete it from the database so this is going to have a margin left of five a height of eight oh this song gets me dark right height of eight and then we're going to have a width of eight as well right and then there you go you can see like a a little nice little thing and that button is going to be text threed of let's just say 600 or 500 when you hover over it I want it to be text red 600 and this gives us this nice hover effect yeah and then the P tag itself so the entire div surrounding it all we're going to say Flex justify between items should be centrally aligned with a padding of five H save and boom look let's getting there guys let's getting there good right I love it when it comes together every time right and then what we'll say is if there is an image URL right so we're going to basically prepare for when we set up images if there is an image URL um which we haven't yet set um so right now we don't actually have this and I'll show you how we do that afterwards actually we'll do the image Ur afterwards I'll show you why right um the reason being is we have to do a use effect and a bunch of stuff to handle the fetching Okay so we need to add image here afterwards that's for us afterwards okay so that's good right so now just to this point we've got this down pretty good so we've got different steps that we have to approach now the first one is we need to handle what happens when we drag and drop something on here so let's do that logic first then we'll do the plus Logic for the model then we'll do the delete logic then we'll do the image thing and then we'll do the search so you see there's a lot of work right there's actually a lot more work than I expected why wouldn't you to do now head over to board and at the handle on drag in function this is where we go ahead and set things up right so handle on drag end so first things first um whenever you drop so this is basically going to be resemblant of all of the drop interaction so if I drop here if I drop here for example it's going to handle everything so the result contains a bunch of information like the source the destination and the type of drag and drop that I did so in this case what we're going to do is we're going to destructure the result okay and if I console log this I will show you very quickly what is happening Destination type right so now if you see for yourself when I refresh let's go ahead and right now yeah I've messed something up there but we'll fix it afterwards right so now if you see when I drag and drop it shows the The Source the destination and the card The Source will say the index of where you dragged and dropped it from so in this case let's have a a look again so let's drag too over so from 0 to one so in this case you see how the index was Zero from the start and we dragged it to an index of one and the board was dragged right if we drag this one it will be a card so you see the card was the type of drag and we're saying which point we dropped it from so in this case if I drag from here to to to done it went from droppable ID zero so this column to two over here and the index resembles which which place it was in that list right so it can get a little bit confusing but trust me just take time with this I'm going to move through it fairly quickly but take your time afterwards rewatch it and just really log out things and understand how it works okay but I promise you I can't spend too long on this section but I'm going to show you how it works and explain it the best I can in the time we have right so the first step I want to do is I want to check if the user dragged outside the box like over here if they do that we don't want to do anything period right so if the user drags the C outside the board all we have to do is say if the Destin if there's no destination return that means if you didn't drag it to any of these destinations forget about it all right so in that case we can basically now it won't do anything period okay so that's the first easy step then what we want to do is handle a column drag so a column drag is basically when I drag the column to the entire column when I drag this entire column like so I want to handle that and then basically do what I need to do from it so the way we do this is we simply say if the type of drag is equivalent to a column okay so if this is the case then what I do is I say const entries equals and I make an array from the board columns entries so basically we did what we Ste we did before we're converting the key value pairs to an array now what we do is we splice so this is basically what I need you to pay very close attention so I already have the source index so where you took it from okay so I need to take from that in uh that column so now what I can do is I can say const oops okay what the hell is that const removed entries do splice Source index uh one okay so trust me the logic I've worked a long time to figure this out but basically what we're doing here is we're taking away from this so so if I drag it out of here I'm basically taking this so this is the removed element I have in my hand okay so now we have that stored in removed okay then what I want to do is I need to splice it into the destination so splicing means I'm basically pushing it in to the destination so the correct destination and then it's going to be in the position the correct position so I don't want it to be like over here like and then it randomly shows here it has to be in the correct position right so I'm talking about the column by the way sorry yeah I completely messed up it should be the column like the exact column that you've Dr drag and dropped into so the way we do this is we basically say entries do splice and we say destination do index right we do zero which basically means we're not going to delete anything we're simply going to push the removed item into that column right so now we're basically taking its place right then what we do is we create a new map of the rearranged columns so now we say we've got the rearranged columns from the more modified so what we done here is we copied the columns entries into a new variable we modified it because splice is a direct modifying uh function then we stored it into a new rearranged column and now what we're going to do is we're going to set the board state to that new state and what we need to do here is go over to our board store right so now we need to create a very special function called set board state right so this is going to be a very important function we're going to use a lot right so what this will do is this will take a board object and it will basically set the state for it okay so we're going to set the state so I'm going to go to my set board state so down here for example I need to create the function for that so set board State and what I'll do is I try and space these out so you can see so step board State and this is going to be a um basically the following it's going to take a board and it's going to set the variable in a global State okay so then what we do is we basically get that function now in our array so we say set board State and then we basically get it over here so we say set board state state DOT oops sorry guys state DOT get set board State okay so now we have this variable and we can pass in the re rearranged columns which is in the correct state so we can say set State um and basically what I'm doing now is I'm only Chang The Columns right now remember boards have columns inside of them so what we can do is a nice little es6 trick here we can say keep all the current keep all keep everything basically and and then change the columns field which is the only thing that really inside to become the rearranged columns okay so now what we're doing is we're modifying the state and with that done we can now actually persist so look at this look at that oh look at that nice look it works and it holds its value and then I remember when we set things up we actually had it in a way there when we refreshed it set it back to its original state that's clean so nice right so so clean and now we've done the column part now we've got the more tricky part which is the nested part which is basically how do I move a to-do into the correct one this take this took a little bit of calculation but I'm going to show you how it works okay all right so this one I need you to to just pay attention with me stick with me trust me I promise you the pain will be worth it okay so right now remember the source and destination it was only numbers it only said like you went from index zero to index one and so forth so what I'm going to do now is I'm going to basically create a copy and I'm basically i' I've slowly like left comments all around the place to help you guys are okay so what we're going to do is this step is needed as the indexes are stored as numbers instead of IDs with the DND library and because we're now using the um as I mentioned because we're now using the um the map right we need to basically convert it over to the array format so now what I'm going to do is I'm going to create a copy of my columns right so what I'm going to do is I'm going to basically create a copy of the columns and then what I'm going to do is I'm going to say the starting column index is the foll and the finished column index is the following so what watch what I do here so what I've done here is the source droppable ID will go into the columns and get me the correct column right and this one will get me the correct column for the finish and that means when you dragged and dropped in the correct way you're basically going ahead and and rebuilding from a zero to the object in your store and I'll show you what I'm mean by this right so from those values what I'm doing is I'm rebuilding the start column and finish column okay so now if I was to console log the start column and the Finish column what you're going to find is um so now you'll see if I was to go ahead and drag this over here for example you see now how we've got we went from impr progress we went from the impr progress column to the dun column so you see how we've we went from the just previously what I told you before showed you before the source and destination is 0 1 2 3 now it's actually found the columns rebuilt it with the correct arrays and so forth now I have the objects that I need to modify right so I have the start column I have the Finish column so now what we can do is if for whatever reason you didn't get the start column or finish column we basically return we're protecting and then if for whatever reason you basically drag and dropped in the same location exactly so not the same position but the same exact location we should then do nothing as well okay so um no Muhammad period right so Source Des destination that start colum finish colum basically what this is saying is yeah if I drag and drop into the exact same position it was in do nothing okay so if the source index is the same as destination and the start column is the same as the Finish column don't do anything okay so now what we do is we create a oops sorry guys uh we create a a copy right so we say new to-dos equals um start column to-dos right so we say start column. todos okay so again this is a lot of data manipulation then what I'm going to do is I'm going to splice the to-do to move so basically what I've done here is whatever to-do I take I am not splicing it from and the reason why we're doing an array destructuring here is because it returns an array the splice function and then we basically destructure to get the individual thing out so whenever I grab this now I've got the to-do moved okay now we've got two cases where we need to manage how and what happens the first case is going to be if we are dragging and dropping in the same column okay so if we do this and you can actually eradicate this but it's more efficient if we do it this way so the start column and and finish column ID right so if this is if this happens you're basically doing a same column task drag and you're not doing it in the same position because we already eliminated that here okay so same column task track else you are dragging to a different column dragging to another column okay so the first one let's handle it so first thing we want to do is we simply splice into the new location in the same start column right so in the same new to-dos the same column because we're not changing column we basically splice it then what we do is we create a new column right so in this case we splice it we create a new column object and then we basically create a copy right so what we're doing this is basically an immutable pattern right so we don't want to always manipulate the initial object so we create a copy of board columns I'm then going to modify so new columns do set I'm basically now modifying the start column ID so the ID basically of where I um and basically so I've spliced out the to-dos create a new column based on that value and then I'm setting I'm created a copy of the map and I'm re I'm setting that ID to become the new column and then what we do is we simply set that as the board State the new board state so we basically say set board State and this in here will basically be the exact same procedure I did before so board and then we say columns is now the new columns so columns is now the new columns like so okay so with that said what we've now done is we've handled the same drag so you see that now it works inside the same column so now it's working inside the same column it doesn't work yet for another column you see it just disappears right so we need to fix fix that right so right now it doesn't work if we go outside the column so we've done it for the same column so let's get it done for another column now so what we're going to do now is the First Column was fine it was very simple cuz we just had the start column right we didn't we never went to the Finish column but in this second case we have the finished column and we need to modify the start column and the Finish column okay so I'll show you how we do it because technically what you're doing here is you're taking something from this column and you're adding something to this column so you have to make the correct changes in each of the columns to reflect that interaction okay so let's do that right now so what I'm going to do is I'm simp simply going to say make a copy of the finished column and I'm going to splice from the finished column the destination right so in this case now I'm saying that we're going to basically in this one we we done it to the destination but the destination was still the same place right but in this case we're going to do to the finished column so the finished to-do sorry and then what we do is we create a copy so a very same like simple step here same step exactly as what we did previously yeah so this is essentially the same here here and here okay and then what we do is we just do two slight changes here so what we do is we say new column new columns do set the start column ID as new column so this is going to be the new modified value and then the um prev the finished column we set to the uh the new modified finish to-dos okay so you see the Finish ID so now what we've done is we've modified the first thing that you took it from and then the second argument here the second one is basically changing this this area so it's changing this and adding the to-do there so you see how it removed from there but it didn't add there this is what this is going to do okay then is very simple we just simply go ahead and um we set the board state to the new columns done save okay and I've also got a function here I'm just checking what I did for that one cuz I can't even remember what I did for that what the hell is that that is oh yeah okay gotad so in the database that's changing the value yeah so here we need to update in DB I'll show you right so I'll explain that so now first let's check the logic so we save and we should have everything working if we have I want you to destroy that like button so ready for this yes look at that and it changes the done as well look at that guys absolutely beautiful and look it works just as we expected great stuff as I mentioned before that can be a little bit confusing what we just did but what I want you to do is when you watch your back and code this along I want you to stop at certain points and console log it and really listen to what I was saying and then see for yourself the exact changes that are happening again all of this stuff is really about getting dialed in with the fundamentals of different data structures arrays Maps objects all that good stuff again if you want to go ahead and really learn and master all these things I Do cover it inside of zero to full stack hero so make sure you check it out over at papa.com and then you can see for yourself why it's basically the place to be for learning all of this kind of really intense stuff right so I want to go ahead and it's a Shameless bug but I want you to go ahead and you know if you do get stuck and you really want to dial in then that's the place where you're going to go ahead and cover the gap of maybe feeling really lost in what I just said versus feeling really comfortable and confident in what I just said okay so let's carry on strong we just finished off really nice with that okay that's really great so now what we're going to do is we are going to um we've got this done so now we've done all the dragon and drop stuff hey great stuff right so now you can see you can drag over here oh that's actually because I've got the horizontal that's fine we'll fix that later so there you go boom that works really nice uh I got a little error here because of the start column index of zero I believe I messed up up here where is that start column index board 43 was here so stock index sub [Music] 43 okay so I think I got an edge case there to be honest with you 0 01 01 yeah that's fine okay it's okay okay so at this point now what we can do is I want to go ahead and do one more step there which is updating the database so if you notice when I refresh it's not remembering where I put it right so what we need to do is simply make a function that will basically update the database so let's do it right now very simply all we got to do is go to our board store and this is what I like about the board storage you can actually have more than just State Management you can do other stuff inside there so here I'm going to create a function called update to do in DB update to do in DB okay and this is going to be a function which takes the following it's going to be a function which takes the to-do and the column ID and then it's basically going to set the to-do to that column ID when when you pass to that function so we going say update to-do in DB and that will take a to-do and column so where am I at right now I'm getting so lost okay yeah so update o oh I'm going make it an arrow keep it consistent okay and this will be an asynchronous function and then here what I'm going to do is I'm going to say await databases so I'm going to pull in my databases object from app right the one that we initialized earlier and this is why I do something called update document okay so what this will now do is it will update the document and all I need to do here is pass in a few things so the first thing is if you look at this is the database ID The Collection ID I already have them and the final thing is the document ID so what I can do is so here I'm going to go ahead and pop this in so to-do ID and then you pass in what the updated information is so here I'll say title is going to be the to-do title that I want to change and the status will be the uh status that we passed in so it's going to be the column ID okay so now we've got the correct function done so that's basically the update set then we go up to our board and we basically pull that function in so now what we do is we simply pass that in so update Tod do and we say State update to do in DB and then at the point where I had my comment all I want to do is if you were to go ahead and drag to another column that's also why I split it up because if you drag in the same column I don't really right now I haven't persisted the order but you can you can extend it if you want to but I'm only basically updating the DB or making a request to DB if you cross to a different status right so let's go ahead and you could honestly just set it based on updated at you can move it based on that if you really want to do that so now what I do is I simply say update to-do in DB to-do moved to the Finish column ID done and now a quick check to see if you've done it correct when you get to this point what I want you to do is refresh and to make sure that you've actually changed the state in the database you see this is loaded from the database so if I grab this and take it to done what we should see now if I refresh this should be in the done column and just like that it's done perfect so if we move everything over here now you'll see everything is in the to colum perfect so that's actually changing on appar right's database yeah amazing stuff and also remember what I said about the placeholder you see how it's it's creating a placeholder for me that's really nice right so it shows you what it's doing nice good stuff guys this is awesome now what I want to do next I want to actually go ahead and maybe implement the search functionality before we then do the model and then we focus on deployment and I think we're golden at that point right so let's go so the next step is let's do search so right now inside of the header. TSX I want to go ahead and cuz now we we can really like Elevate the speed and what we're doing so at this point inside of the header I want to go ahead and set up something called a search string and again this is going to be something which we're going to set up in in our board store so let's head over to the board store and we're going to have two new pieces of data the first one is going to be called a search string so in this case let's go ahead and add that in this is going to be a search string okay and the second one is going to be set search string which is the function to modify the search string okay now the search string is simply going to be like uh we're going to initialize it with a blank value so over here we just simply going to say initialize with a blank value and then the search string itself is just going to be a very straightforward Sear string that we pass in and then we set it as straightforward very easy to do okay now what we can do is we can go over to our header and as we type in here just like we would do with something like State we can do the exact same thing with zand except now we're modifying at the global layer okay so over here now what I can do is I can say const and I can say something like the search string and set search string set search string equals use board store and I basically get the state like so I will go ahead and get my parentheses like so and then here I can say search state. search string and state. set search string I can then go to my input field and I can set the value here to that and I can say onchange so every time the user types in we can simply set the E target. value two set that Global State instead of something like Ed state to test that this is all working all you need to do is simply start typing in and if you're still typing in you've done it correctly right otherwise it would freeze there and it wouldn't work so now we're setting up every time I type in I've got access to this at the global level now so if I need it somewhere else I can actually go ahead and change that accordingly right and we also got to do API GPT stuff so it's crazy so now what I want to do is implement the logic to filter out okay so where I do this is the board I believe it's the board or actually I think it's a column uh I do at I think I do at the column yeah I do at the column level so each at the column level so what I would you to do now is it the column level or don't oh my God okay oh yeah I do it at the to-do yeah column level I thought so makes sense all right so at the column level now I am going to go to my column and what I want to do is I need to basically first get those values right so I need to get the search string itself so let's go ahead and do that right now so I'm going say const search string I've done an array here because I'm going to need that afterwards use board store and I'm going to get the state. search string there we go oh I like this song right this one the OG songs and then we've got the search string here and then what I can do is when I actually render out the to-dos there's a in the end of the day there's loads of ways you can do this I'm just showing you one way okay so here we're doing an implicit return all I do is I simply add parentheses around the entire thing and all that was doing is basically that right so that that fix is it if you want to do that but then what I'm going to do is I'm not going to render it if how can you not notification V I'm not sure what you're talking about um here I'm going to say if the search string exists and if the to-do but title includes the search string okay and what I can do is I can actually do title do to lowercase to lowercase uh to lower case there we go includes the search string to lower case that way you never get some annoying Edge case then I want to return no okay so if I if that comes across then I simply return no so this is basically not showing it if it's there right so now what I can do is if you see live look at that oh dogs and build nice but you can see how each one is still saying one one one so I'll show you how we can get rid of that so already we've got that bit done so that walk there we go stream done right because this is local dat are it's fine to do it this way really not that bad right so now for the count again I'm going to do it inline I'm going to show you a relatively cheeky way of doing it I'm going to say here where we show the length I'm going going expand this and say if there is no search string okay then you should show the to-dos do length so it's very simple if there's no search string show the to-dos do length else I want to show um the F on to say to-dos do filter and then I basically I'm going to map through all the to-dos so to-do to-do and I'm simply checking if to-do do um let's see to-do do title so basically the same thing that I just did before yeah to lowercase there we go so uh why have I got this issue now so to do do length yeah that's right okay one second let me just write this out so we got the two. tile do includes search string L there we go and I don't need this part and here I'm going to do the same to lowercase check to prevent it from happening and yes you can honestly go ahead and you know make this all like refracted and really clean so now you can see we've got the so if you pay attention to these ones if I go ahead and say live right so you see that it shows only the the number only counts up for the one where it's in so build and so forth you see now it's a zero Z but one right so now it's perfect so this is looking good so far so we've done the search so just like that we've got the search right so yes um Ashan it's a very good point and I was literally thinking it as I was building um but it came to the point where it came in my head today so yes ideally what you would want to do here is do something called a debunk right debounce sorry a debounce um where basically as soon as the user stops typing like after like 500 milliseconds or something or 200 milliseconds then it executes search right now it's on every letter which can be very intensive but you're just not seeing it but yes you would want to do something called a debounce here on the search that way it doesn't always happen or you can do it on search where you hit enter yeah but I just wanted to show you now I'm doing it per render which probably isn't the most but very good for noticing that okay cool so next up let's move swiftly on let's do GPT and then let's do the model okay so GPT is up next and then we're going to go ahead and do this model for adding a new task and then we're going to add the images and so forth all right so we've got quite a lot to do so I want to move fairly quick okay so GPT let's go ahead and do it so first things first I want to prepare my end points so that way we can work in a fast fashion fashionable way so at this point inside of the app folder I can create the new API folder right so this is a new nicer API that we can use right and don't worry if you're confused it'll take time you know you can watch this back in the replay and everything right so in this case we're going to say right now we're going to create this bit where it says hello Mr Sunny welcome to the to-do app here's your summary you have four to-dos two in progress three done and so forth right Suki sing says I'm a full St developer in Australia you're doing amazing stuff thank you so much dude I appreciate you guys to the moon and back so thank you so much for that all right so inside of here I'm going to create an API endpoint called generate summary and then inside of there I'm going to have a root. TSR this is the new syntax for um the new rout in next year 13.2 or three I believe right it came in right but that's how we're basically doing it now so we've got this really nice and you can basically choose if you want to have a post or a get or whatever the case right in this case we're only accepting a post at this mpoint so this will be/ API SL generate summary okay so 13.3 there you go so what we're going to do is we're going to basically pass in in this request the to-dos in the post right so this is going to come through here then what we can do is you can log it out for you know if you're debugging it you can log it out there for example and then what we're going to do is we're going to basically communicate with open AI communicate with open AI right so GPT so in this case I'm going to show you how you can do it now you can use gpt3 4 Turbo all that good stuff um and in this case so we're going to actually go ahead and install open AI right now so what I want you to do is basically go here go to open AI API and then go to the API reference okay so what I want you to do is you have to create an account right with open AI I'm going to do mpm install open AI into our project so let's do this command J go to the second terminal mpm install open AI I've now installed it into the project then we have the authentication and all this good stuff so you can ignore this for now what I'm going to do is we simply have now we have to add in a process. environment. open AI key so I'm going to show you this one all right so what we need to do is go to our environment. loc file and I'm actually going to add in something here so let's go to want environment local file and I'm not going to show you the screen because I have all my keys here right but what I want you to do cuz I don't trust everyone on stream that's the truth I'll be honest I've learned my lesson in the past so I've hidden all my keys for a second so now in the open AI this is so stupid I have to do this but the keys are down there right they're all down there but the open AI API key so I need an environment variable here so what I want to do is I'm going to go to our personal view API Keys now I've already I've actually set a billing account here so I'm actually using this for a few things P you go I believe you can use a free amount on the turbo 3.5 GPT 4 is paid um but I believe you can use a free one but in this case I've added a billing account you can do it for yourself it's very simple uh and honestly I think I was I was like going to town on this thing and I think I spent like what was it yeah 49 cents so honestly is really not a problem right so I was going crazy on this thing and then I did that so yeah 49 cents is is honestly after going crazy at the thing so I'm going to create a new secret key here so I'm going to click this and I'm going to name it so in this case I'm going to say this just call it Trello YouTube Key YouTube key and I'm going to create a secret key right so I'm going to basically go ahead and do that right now and I'm not going to use this key but I'm going to show you what what we'll do right so you can create a secret key here and copy it right so you can copy that key now I'm going to delete this key because you guys just saw it but that's basically once you've copied that key I need need you to go back to your code and paste it in now okay so I've already got a key that I'm using so I'm going to go ahead and paste it in right now and then I'm going to pull oh and I'm going to pull up my my environment my my variables and then did so forth so I'm pulling pulling that in off I just had it on the screen it gets tricky guys trying to hide all this stuff right so now I've added in my API key so you should do the exact same thing so you should have four open AI key open AI API key and so forth okay save and close okay now I have my key like everything set up cool so now what I need you to do is go over here and create a new file called open ai. TS at the top level at this level I'm basically going to create a config for our environment right so in this case this is how we're going to go ahead and configure our API so we do a very simple import we do uh configuration equals new configuration passing the API key like so then we basically create an instance of open Ai and we we export it so now we're using the same instance every single time yeah PADI says oops Yeah EXA that's exactly how I felt and then here we're inside of the generate summary now what we do is we say const response const response equals await open AI okay so we do the import from our open AI dot create chat completion right create chat completion and then here what I want you to do is you can pass in the following information right so the first few things are I'm going to use GPT 3.5 but you can so I can right now I've got access to gp4 so you could do that the reason why I recommend you don't is because it costs a lot more to run gp4 and that's my honest truth and if you're doing this as a portfolio piece I'd highly recommend you don't unnecessarily add yourself that spend there's no point really unless you're really demoing this to like a bespoke user or something and then you have the messages array okay so these are the messages that you want to go ahead and send to GPT so the first one is going to be a system message Indonesia in house what is up so the first one is a system message and this is basically telling gpta I want you to always do this so when responding welcome the user as Mr Sunny so you can say welcome the user as Mr Jimmy Mr Jay Mr Noodle Mr sta all that good stuff yeah and GPT is also slower yes and say welcome to the pap F to do limit the response to 200 characters okay so that's fine and then your second one is basically I'm pretending to be the user okay so it's like hey provide that a summary for the following to-dos count how many to-dos are in each category such as to-do in progress and done then tell the user to have a productive day here's the data and then we do basically Json stringify it like so okay now once this comes back you get a response from chat GPT right and what we're going to do is we're going to destructure the data from the response so from the response okay oops from the response so that's great right so once you've done that step what I then want you to do is you can actually go ahead and log it out so I'm going to show you what I would do for debugging purposes is you basically want to go ahead and pop it in like so right so I'm basically say data is there and this this is what I would recommend when you're getting started because it can allow you to debug see what the hell's going on and basically the first response that comes back from GPT remember I'm only doing n equal 1 so it's only giving me one response back data. choices zero message and in this case it will return the message back to us okay so now we have the API endpoint done so the API endpoint is down we have our API key right so this entire route is pretty much set so now all we need to do is make a call right so I actually forgot how we did where I did that so it was in the header believe yeah so the header is where we're going to do this so inside the header what we're going to do is we basically going to have a fetch suggestion right so you can use us sub as well you can use anything here I'm just going to show you how you would do it in a typical user effect fashion okay so here we're going to go ahead and say I firstly need access to the board right so I need the board here so I'm going to go ahead and get the board so I'm going say state. board and again you see how nice like Z stand is right it's really easy once you get the hang of it so we're going to go and say use effect right I've imported it from react and then we've got the dependency array and inside of it I'm going to going to be using the board so I need the board now I'm going to protect so I don't want to fetch a suggestion from chat GPT if the board columns are zero so if board do columns do size is equal to zero you're probably wondering size what when since one was that in there already well no this is a map remember right this is a map so it tells us the size as a function so if it the size is zero then we're simply going to return yeah and then what we're going to do is we're going to set loading to true so um in this case I'm going to have a local piece of State here for the loading okay now because I don't necessarily need to have Global State for the suggestion in my instance I'm going to have a loading piece of state which is going to be a Boolean so this is basically just preparing it I'm also going to have a local suggestion now if you want to you can lift this into you know a used AI state or a AI store or something but in this case I'm just doing this it's local it's fine yeah so I'm going to set the loading to true and this is again a reason why you can use use S use SWR would eradicate this for you so yes you can use it um and we'll say const fetch suggestion Funk right so if you want to do anything asynchronous you have to wrap it in a sort of asynchronous wrapper function so then what we do here is we say const suggestion equals a wait and we're going to create a helper function called Fetch suggestion which would take oops no that's a recursive we're going to take the board right so we're going to make this function which accepts the board as an argument and then when we get the suggestion back we'll set the suggestion and we'll set loading to false and then what we do is we simply execute that function okay so let's go ahead and create this function now so inside of our lib folder I'm going to go ahead and create a file called Fetch suggestion. TS um I'm going to go ahead and create a function yeah we've done it so here what I need to do now is I'm going to go and do the F const fetch suggestion equals an asynchronous function like so and it takes a board object sorry so it takes a board like so okay now what we're going to do here is I'm basically going to do the following so I'm going to get the to-dos from the board but in a way like so so I haven't created this function yet but right now we have a map object now I want to make gpt's life easier I want to format it before I send it to the API whereby I literally strip it down to the amount of to-dos in each so it basically very easy for GPT to figure out you can go ahead and ask GPT to figure out yourself but it sometimes messes it up and I'm just going to show you a lot of transformation in this in this video okay so what I want to do here is I basically will create this now this will do an a API um call afterwards and we're basically going to pass the Tod do that we have formatted after in the body right once we get that back we're going to go ahead and do the following we're going to pass the response with res. Json that's the GPT data we're going to get the content from it which is the response that GPT shout to us and then we're going to go ahead and Export default um fetch suggestion now we need to create this helper function format Todo is for AI so inside of here format too is for AI do um TS and this one is basically going to be a function that looks something like this right we also have um so we say con to-dos what I'm going to do here guys is very straightforward I'm basically creating a copy like we done previously from the board column entries right so I've got an array now version I can go ahead and do it now remember what I said right what we want to do is so I you can do it two ways right this first function will reduce it down into a flat array so it will basically this first one will reduce it down I'm going to keep it very short to kind of keep it simple but this one will go ahead and make it a flat array which will basically have the key so it'll be like to-do in progress or done with the to-do array attached to it or array of to-dos attached to it that's good and you can send that that uh itself to um to uh chat GPT right you can do that I would recommend you make it even easier for chat GPT and you basically do the following where you basically reduce it to Key and length right so in this case what I've done here is I've taken the flat array and you can probably do it even simpler than this right you can do it simpler than this sorry you don't have to have this intermediate step but what I've now done is I've just made it so you've got your key so this will either be to-do in progress done and then it will literally just be so imagine you've got an array of three here and it will say to-do two in progress one done zero that's going to be the array now so it's a flat array right so it's a very easy array for chat GPT to figure out what the hell's going on right so that way it's less likely to make errors because I did trust it initially to be like oh yeah you know figure it out and it kept making mistakes I was like it right so screw it okay so in that case um I'm going to go ahead it slips out sometimes my bad all right so let's go ahead and import this and now we've got the to-dos like so if I console log the to-dos what we will see when we do this I'll say formatted to-dos to send I'm just going to go ahead and do something like that for now and just as a debug message okay now after that's done we go back to our header and we simply import the fetch suggestion okay and now we have suggestion here so what I can do is actually inside of my header where we previously had summarizing your tasks for the day I am now going to basically extend this and modify this so I'm going to basically firstly make this class name um back tis and then all I need to do here is basically say if it's loading I'm going say if loading if loading and animate Jay's laughing yeah I know clips yeah so if loading then I'm say animate spin okay and this is freaking out why exactly um oh yeah yeah yeah so in this case loading animate spin so while it's loading it'll spin the little head right and then what I'll do is I'll say if it's now got a suggestion it it will show the suggestion otherwise it will simply say summarizing your task for the day so now what we should see is it all come together nicely right so let's GPT is summarizing your task for the day oh there we go and then wait for it let's see if it comes back with a summary is it going to work first time is it going to work if it does smash that like button guys one did it is it even done aord to the back end let's see uh let's go to this one you can see hello welcome Sunny oh it is but it's not setting yet so let's debug what the hell is going on so let's go ahead and refresh and let's see for ourselves formatt it to do is to send you can see look this is what I was talking about it makes it very easy so it sends back that that object and then we can debug it I'll show you how I debug so look so now oh yeah look at that hey welcome Mr Sunny welcome to you're currently have one task to do one task in progress and one task is already done thank you for keeping track of your task have a productive day and if I go ahead and do this because this is attached to board it will go ahead and regenerate the query so GPT is summarizing your task it's an example guys right so now it says there is one task to be complet zero tasks in progress and two tasks already done nice if I go ahead and put everything over there so in this case we've got this one let's see if I dup it up it's basically going to make several requests by F right you got two in uh two to-dos in progress zero and d one keep up the good work and have a productive day ahead and if I go ahead and do this we should see three in to-dos and none in in progress and done look at that guys pretty cool right pretty cool right so let's go ahead and see obviously you can make it whatever load you want I've just done it very simply for now uh while I'm live I guess it's always being a bit of a headache but in this case is it going to see it where is it so you see where we're logging it out right you can actually see for yourself where it's happening honestly the demo gods are just against me right now but it does work I promise you uh okay so that actually was a weird failure let's try again there you go okay so it's it's a few edge cases but for the grand scheme of it it works right so in this case there you go so now what I want you to do is go ahead and obviously you can handle negative cases if that was to ever happen sometimes GPT can you know it can error out for some reasons right so um fetch function has an auto duping function built in it does you're correct yes so um yeah you're right actually but I'm saying if I was to do this like drive it crazy now it's making several requests all over the place and what you'll find is it will it will pop in like in a second so you see that look it pops in so look it pops in Pops in Pops in so it actually I mean it came to the right right end point but that's what I mean in this case look we're making good progress guys right so I guess the next thing that we have to naturally do is the delete let's do the delete first then let's do the model and then we are literally at the end and we're going to deploy this thing so this point now for the delete function right so we're going to go over to the to-do card boom like so and then here so the to-do card let's go ahead and do the X Circle icon so I want to make it so that way when I do the X Circle when I click on it it should delete the task right so I'm going to create a delete task function inside of the board store and as I hope you can see that you can do a lot more in the board store than just simple manipulation in your day right you can actually have like fully functional things happening here so what I'm going to do is oops is I'm going to go ahead and have the delete task I'm going to create a function for it so here delete task right so this one here it's going to take a task index a task to do and the ID itself and then what we're going to do is we're going to manipulate the the database in such a way so in this case I'll show you how we do it so we'll create a delete task function and this will be an asynchronous function so I've got the signature here to save a bit of time the delete task is going to be this like so oops like so and then inside of here I'm going to make a copy of the current um uh current map and this basically get geta will give me access to the current state and the way we get that value is you actually go up up to the point where we had set and you actually get a second argument here called get simple as right so here we have two columns yeah and then once you have the two columns we're going to say we're going to delete from The Columns right so it's very simple actually all you do is you've already got the ID of the the the task that you want to delete so it's fairly straightforward so we go into the column itself the ID of the column then we go to the to-dos and we splice the task index the current to- do out it so what we're doing here is we're changing the existing state we're then going to modify it so it seems like an optimistic update if that makes sense right so basically what we're doing here this is all on the front end so we're basically just splicing it and then we're replacing the board with the new columns so this will basically show on the front end that it's a media okay and then what I will do is I will basically have the following involved so I'm going to have a delete for uh for the image as well right so if there is an image so I'm going to import this from sto uh storage that we set up earlier from atro if there was an image inside the to-do it will delete it from the storage bucket so this is how you delete from Storage bucket so if there's an image on that to-do it will delete that image as well and then I'm deleting the actual document itself so this is how we do it okay all right so we got the delete task function done so now we go to our to-do card let's go over to the button here and here we'll say onclick right so onclick equals and this will be delete task right so what I can do to make this actually a lot smoother is I'm going to have a uh the following so I'll have par parentheses like this Arrow function delete task and then this will take in the index the to-do and the ID okay and the delete task we have to pull in from our board store so this is going to come in from we only need one thing so I'm basically just going to make it a simple straightforward pull in like this so we import the board store and we don't need the array because we're only ever going to use a delete task inside the to-do card at least okay so now with that said what we're doing is we should see so I don't have to go to ight to show you how this is going to work basically if I delete this you should see a UI change so that UI change was the local state now if I go ahead and refresh you'll see that it's no longer there from the GetGo which means it actually deleted it from ight right and I can promise you it did it because if I go to ight and I refresh we should see two to-dos here instead of three and they should only be in progress there you go perfect right so as you see everything is working really nicely the way we want it uh this is an old Local Host window that's why it's there right cool so now the next up what we're going to do is the Headless UI integration so headless UI is this beautiful popup and this beautiful popup is going to have a bunch of things involved in it so headless uui is actually a really great Library it's basically built by the guys from tailwind and they're fully accessible UI components which means when you're on this screen if I click outside it closes it if I while I'm typing in here if I hit tab I go to this part if I hit down and up on the Arrow key it goes through and then if I tab through it goes to the image if I hit enter it opens up the image picker then it will go ahead and show this I can tap hit enter it adds it to-do so you see the point if I hit Escape at any point it closes the model so this is what we call accessible right so this is what we're going to basically be building so what I want you to look at is the dialogue the model that's what we're going to be doing so this is exactly what we're essentially doing here right so we're going to go ahead and mpm install headless UI react okay so we're going to go ahead and install this command J bring this in go like this and do the following and while that's happening I'm going to go to my API generate summary and I'm just going to stop logging everything out because we don't we know it works now I'm going to keep our code a bit neat there we go that was more of a debugging step okay and then what I want you to do is you can see the example here now I don't need to basically dive so far into this because their documentation is actually fairly pretty like it's pretty good right so what I want to do instead is I want you to look at this example and as you can see they've got this dialogue and then you've got dialogue panel title description and then you can basically build it out accordingly now I want to go ahead and use something called a transition so there's actually a transition here so this one right here so you've got Transitions and then you got dialogue panel and so forth right so we're actually going to be using the transition and we have the transition child as well so it's this example right here so if you scroll down to Transitions you'll see this block of code again the reason why I'm showing you this is because it saves you time because you don't have to do it all yourself right so what I'm going to do is as a step one I need to make a new function called a model what I'm going to do here just to make life easier is pop this onto a new screen like so so we can kind of scroll between it so I'm going to create a new component called model. TSX RFC to pop open our model right so now we've got the model so what I want you to do is I want you to basically grab this block okay so grab the entire block right so we're going to be basically using it so I want you to pop that in and um Al so at this point you can really yeah so okay I'll you pop it in go to here my dialogue will become modal okay and as you can see that this is going to be a client side component so this is going to be use a client okay so to save us a lot of time right CU that is honestly we're basically doing the exact same thing that they're going to be doing except we're going to refactor it so the state of the model is stored in the uh use model store which we haven't yet set up okay so right now we can't determine when this is open or not right right now it's just a random bit of stuff that's going to be there so I want to basically refract this a little bit so we can do something cool with it so right now I need to export default model so we can access this object that's cool and then I'm going to create a new store now which is basically going to keep track of the modal stuff so in this case we've got board store but we can do another step and we can have something called the model store so here I'm going to say model store. TSX Tso and then I'll show you in short what we are going to do this is the entire store we've got the state there's three things inside of it is open and then we've got like uh open model close mod and then we've got the used model store here create the mod state so it basically pops open here and then we initialize is open by default with false because we don't want the bloody modal open straight away then we've got is open model which basically sets it to open and we got closed model which sets it to false right so basically in a nutshell that's how we're doing it now I can use this the exact same way as we were doing it previously right so now here we're going to refactor this from that is open to we're going to say um con and yeah we're going to say const I'm going to say is no sorry uh I'm going so blank here one second yeah here we go cons is open is open and we also have close model inside of here close model uh from use model store State and then we basically need to get the two things it will be state do is open and state do close mod model parentheses close we can then get rid of this and as you can see is open is already working the way we want it but on close all we need to do is simply say close model and that simple refactoring allows us now to basically use Global State instead of the state that they've used right you can feel free to take a look at all their Transitions and stuff but right now we're just going to get this set up right quickly yeah so on the Todo on the column now we have the plus the green plus which was here plus Circle icon so on that column I want to be able to open the uh the column when you click it okay so what we're going to do is we're going to go up to the top where we have our Imports and I'm simply going to go ahead and pull in the open model from our use model store now simply put all I have to do is go over to my plus Circle icon and on click I simply pop in open model so what this does is when I click the green button now it will open up the model now as you can see I think I need to just change one more thing I believe I think we're good actually yeah so let's go ahead and try it out okay so let's go back over so now when I press my green button so let's go ahead and make this full screen green button let's refresh I don't think I'm rendering my Modo anywhere though that's the thing yeah so I'm not rendering the Modo anywhere so I think I have to put yep yep there we go so my bad uh don't do that uh of course the model is not actually rendered anywhere yet so what we got to do is where we render the children at the top top level I want my model to appear right so model like so you can have nested models whatever you want to do in this case I'm doing it like this so you've got model okay and then now what we can see is if I click on plus oh we get a deactivate account right and obviously that's not looking very pretty so I haven't got the styling here so I'm going to show you but as you can see it's almost some it's something it's almost something right but you can see like I've got if I press Escape my model is opening and closing so if I click I can click out I can press escape and it's there so let's get the styling done now as well right so let's get the The Styling sort of nailed in so we can make this look beautiful okay so I'm going to go ahead and show you how we can change this entire thing now so the transition we're going to say appear oops sorry um so a few changes need to happen so transition should be appear okay the dialogue is going to be um on close sorry that's my bad and then we're going to have a uh this is going to render as a form okay so this will be a form that we're going to basically pull up right and then we've got a class name this is going to be relative relative and this one's going to be Z of 10 because it should come in front of everything okay we've got all of our Styles accordingly we've got the fixed insert and I'm going to change the div style here right so this div I'm going to change it to be the following so I want to have that one instead fixed inser black background black with the opacity 25 so it basically dims out the background a little bit Yeah the background and then where we've got transition child so here so this is where mine's different to theirs yeah so I I can't remember where I got my example from but I modified it heavily um I believe it was styling the dialogue yeah it there was a mixture of this so if you go to styling the dialogue you can actually get the Styles right so yeah I actually had this in there as well so what you can do is on styling the dialogues I kind of want to show you so you can just copy this as well so right here so I want you to grab this one with text a P4 I'll tell you what I'll tell you what I I'll do it this way so let's have I'll show you what I've done and you can just pause the video and just add it in yourself that's that way you can you won't mess it up okay so on the transition child fragment I want you to go ahead and just pop in the following so see this div so we've got a fixed inser and then I need to go to the surrounding transition child so when I mean surrounding transition child I'm talking about here we've got two why have we got this we going to need this one we getet that one get rid of that we're going to have a div after this one so after this transition child we're going to close out the div we're going to close out this div hit save okay and then inside of the transition child we have the following so yeah that's correct no dialog form yes okay that's correct okay I now know what we're doing yes I got so mixed up for a second so you want to have a transition child for the back backdrop yes that's right so you want to f one transition child with that background opacity and then your second one is for your container which makes perfect sense now because this one will be the one where you basically have the panel and everything displayed that's right so then we have the dialogue panel okay so the dialogue panel now is going to be so what I what I would suggest you do is I'm trying to to find the best way to explain this to you so let's have the dialogue panel first okay so this is the dialogue panel and I've applied a bunch of styling here you can feel free to just take your time and copy out then we've got the dialogue title and I've started this out for you A lot of it is all around making it centered all of that good stuff okay so here added task so I just want to show you we've got the addas button and so forth and then I'm going to have a div with the ability to add some information insid I I'll add that one afterwards but right now let's just test this out so let's go to Traer 2.0 clone let's go ahead and refresh and let's add add in so you can see there we go there we are there spell so one of the transition chart was for the backdrop the other one is for the center that's exactly what I wanted yeah and now we are basically going to go ahead and add in the input field and all that good stuff so what we're going to do is we're going to have a input type of um set task so new task input so this one is going to be the task input and this is going to be in the global store because we need to know that beforehand we need to have access to that so I'm going to add that in Here and Now new task input we're going to create a piece of State inside of the board store so let's go into board store and let's do it here so set task input so new task input is going to be here like so and initially this will be a blank value and then we have set new task input and um set new task input there's no reason why I'm putting it wherever I am you can honestly mix and match them so I'm going to put this one down here just separate some of it so you can see y set new task input and then go down here and this one is basically going to be a function like so so it'll be just pop it in yeah so this one basically takes input sets the new input done okay then we go here and we need to import them in from the board store so that's the model store so now we need to go ahead and grab it from the um board store so uh I need to get a bunch of stuff actually from this so let's go ahead and just add it in one by one so we do con new task input new task input set new task input and we basically map it accordingly like so uh it says it's not there that's interesting what have I not done so oh okay use Board Store see typ script saves the day and then that will know right so this is looking great guys right so now you can see it say enter a task so that's great if I go ahead and do add oh look at that nice if I type that now you'll see it's part of the global store so it's still there right so this is looking great Marcus says goat that's what I'm talking about dude all right so now we've got that that's looking perfect so the next thing is we need to create this radio group right so this radio group being here I need to have this really nice group yeah so we're going to create a component to handle all of that right and that's going to be in global State as well so it's going to be a radio group radio group I'm going to call it the task type radio group okay and again these are all coming from headless UI so I've got example and all that good stuff so again if you're wondering how did he get this code blah blah blah one it will be in the papa Breo and two the documentation in headless UI literally has these examples so you can take them okay so I'm going to go ahead and make a new component here called task type radio group TSX sorry my bad TSX right RFC and then what we want to do is basically go ahead and create this so uh I've actually got an example let me see if I can show you the example so if we go to headless UI and we go to Radio group here so you see this right this is an example very similar to what I've done right so here you've got your example and so forth so I want to actually go ahead and change it to what we have so uh you know Screw I'll show you my one instead let's do my one um so [Music] uh so what we have is I need to create a type of all the different options that are going to be available to us right so the first thing is we've got three types we've got types is an array and it's going to be ID to to do name description and the color the color will represent the color then you got the title description and then the ID and that's ID is going to correlate to what we go ahead and map okay yeah Ashen you can you can go ahead and do that yeah so the UI looks seamless yeah it's really nice honestly yeah so now we've got this looking pretty like solid and then this will actually be a used client component because it's already rendered but by default it will know that because it's being rendered in yeah the first the rafc does a rat functional component okay then what I'm going to do is pull in the Ed board store so the task type but now what we're going to do is we're going to store the use a selection so this we're going to refer to in the board store as task type right so new task type so what I'm going to do is I'm going to set it up for us so we're going to do use board store so I need to create a set new task type and new task type inside of our board store so let's go over to board store go to the top board new task type will basically be I believe it is a typed column yep so it is going to be a typed column and then we've got this set new task type which is going to take a column ID like so okay now for the set new task type we're going to have a very similar approach to what we previously did was the other one just put under there okay and now you can see we're good so what's freaking out here new task type oh yeah I need to give it initial value so if we go to the top here boom like so new task type sorry there you go and now this one freaking out because we do not have a new task oh that's because it needs to be my bad it need to be one of these so to-do so we'll start off with the to-do Top Value so that's great now we've got the values working over here so now we can cook it up in the way that we expected to so what I would recommend is you can honestly go ahead and take this and like basically change it up as you need it but what I've done is made your life always easier so we've got a I'm gonna have two divs so let's just take this out the equation and I'm going to have two surrounding divs and then I'm going to have another div here okay and then in that middle div is going to be where we basically Nest all of these options right now inside that middle div what we do is we have something called a radio group right so in that radio group we're just going to keep listing out so radio group we have like so we import radio group from let's go here from headless UI and as you can see we've simply on the change of the radio group selection it will modify it okay and then headless UI handles all the complex stuff that you know the really kind of cool quirky stuff so inside of there we're going to have a div yeah and this div will have space so class space y of two now here we're going to map through all the types okay so all of the different types here we're going to map through so this is quite a big chunk to be honest um what I will do is I will show you the entire I have two options here I want to show you I kind of want to just dump it in and show you cuz a lot of it is just styling yeah I think we're going to do that I'm going to show you all right I'm going to CH chop it in because honestly it's just a bunch of styling and I can explain the whole thing so between these two divs I'm just going to add a bunch of card I'm literally just mapping through with a bunch of styling okay so I'll show you exactly what we've done here so we're mapping through all of the types we're mapping through all of these three types this one this one and this one each one is a radio group option the key is type ID the value is type ID and then it's got a class name and you get these render props called active or checked which allow us to know if that group or that selection is active or if it's been checked or not okay so what we've done is we've dynamically styled accordingly if it's active it will have like a ring around it a bit just a bunch of styling and then we've got a relative bit of styling around it okay and then what I've done is I've rendered a inner thing so this is that's the actual option itself then inside of the option I've rendered the actual label so this is going to be the name the description all that good stuff and then the circle icon I'm actually going to go ahead and pull this in as well so now if you basically gone ahead and checked it it will have a circle next to it okay so now we can go ahead and enter that so in a nutshell you can pause it take your time over that but I'll be honest with you that's just styling and a bunch of other stuff and it renders out as a P tag as a span and so forth okay so I really want to spend too much time on that but you can get the access to the code and the proba get a Breo and we literally show you all of it okay now what I'm going to do is I'm going to go to my um model and I'm going to basically pop it in right so this one right here import from our thing and now if we go over to our trailer 2.0 CL oh look at that oh my God it just surprised me with Beauty look at this wait for it so we go ahead and press this oh lovely yeah and look if I tab and I press down look at that guys so beautiful and if I hit enter right now nothing's happening cuz I haven't got to submit yeah but we can type in this value saved and just to show you you see that it's actually saving that value we want to we eventually we're going to do it so if you click to-do it will automatically be on to-do if you click done it'll automatically be undone and so forth so I'll show you how we do that as well right so uh yeah that's cool now that's that bit done which is sick um we can go into the model and we're simply going to have the file input now as well so the file input so here this is where you're going to have a file picker option okay so here this crazy it makes me think how much code do I write sometimes damn okay so here we've going to Simply have an upload button for the file so this is basically going to be this upload image button okay so what we're doing here is we're actually going to go ahead and hide a um an upload button so like an input field right so there's a special input field like a special trick to going ahead and hiding something so what you do is simply pop an input field in like so and we need to create a reference to it we make it hidden but we make the type file right and then what you do is you say onchange and then you can basically do a bunch of stuff with it so I'll show you exactly what we're going to do here firstly we need to have an image that we store in the global State and we need image pick a ref locally that we can attach to but basically the goal is that this is essentially a UI element when you click it I'm tricking it by using the same ref to click the input so it thinks it's clicking so basically you're clicking something else but it's it's reference is clicking the input the hidden input right and then it basically opens the file prompt it's very nice little trick inside of this right so what we can do is just firstly handle the the reference picker so we go ahead and do the following we import use ref like so go over here handle image pick ref done and then set image is we need to go ahead and do so in this case we're going to go to the board store and we're going to add our image we're going to say image and this one I believe we do have an IM no so it's a file or no is there not a cleaner way to do that to do what part sorry or to do the hidden the hidden image thing uh the input no I mean that's the way I would say do it but you can do it in many I'm sure there's another way but like I've I've seen that in production builds a lot like people do that because then it's also web scrapers are seeing that as an input which you can select right so that's why sometimes it's kind of good to do that um set inut we also need set image where's my image at set image at so let's go ahead and pop this in here and then for the set image I'm going to go ahead and make it very simple that does make sense no no problem dude good question so in this case I'm going to pop it in here and uh set image and then the image needs to have a default value the image can be no to begin with this is a file so it's fine with no value so in this case we've got add a task right in this case we're going to go ahead and do uh I've lost track now what I was doing set image yeah so set image we're going to go ahead and do uh use Board Store we're going to say image set image state do image so now we basically set the input so this is a hidden input now so now we can do some magic around it so if we go to the model and we do the following um UT where is it yeah so now I'm going to basically say where we have the button all right so this we got a DI so I'm going to pop this in there and then I've got my sorry I'm going to put it inside the input here we go so this div right here we are this is where I basically check I say if I've got an image then I want to show like a preview of it right so I'm going to use the nextjs image tag to do that so I'm going to say nextjs image tag source and I'm going to basically use a URL create object URL from the image now this is going to be important because we're going to basically we are going to use the image that we set later I'm going to still set fix that step up but um yeah this is going to be something that we need to do in a second but I'll show you that in a sec right so we've got the image here and I need to go ahead and do this hit save so curs allow okay what's happening here why is why is this freaking out what is missing right just because I have a prop property is this okay there you go bam I didn't import the right thing so that will obviously break because it will be asking me um you haven't whitelisted you know the domain so I'm going to do on click here and then I'll say this one should set so basically what I want to do is if you have an image here selected it's going to when you hover over it it's going to become grayscale with like a no cursor not allowed icon but I've basically done it in a UI sense so if you click it and then it gets rid of it right so that's how we're doing it so set image of No and then um yeah that's it yeah cool that's good yeah so basically when you click that image it's gone yeah that makes sense we're done then I think I haven't got the current fancy looking upload image button that's what I was missing so my div here above my yeah here there we go this this bit was a bit of a tongue twister in my head to get around so there we got so upload image upload image I'm also going to have a photo icon next to it so photo icon and this one can have a class name of height of six width of six and margin on the right of two so it's not touching inline block now you're probably wondering is it touching because this I'm going to make a flex so this one's going to be uh I tell you I'm save myself a bit of time here cuz we got a lot left so this a bit of styling for the button to get it to look like you see here so that right there yeah so uh that's good now when you click this fake input button basically what I'm going to do is I'm going to say onclick right and this one is basically going to say the image picker ref so image picker F do current do doclick right so basically what this will do is you can basically protect yourself with optional chaining but now what this does is it essentially clicks that hidden one that hidden file picker so that way you don't get the ugly file picker you get this one right all right so in this case there you go so now if I click the upload image we should see a file pick I'm not going to show too much there we go I'm just going to hide it a bit um I don't want to show something I shouldn't show okay but the point is is it works okay so if I was to go ahead and show you that so if I click into this trust me that works I just did it right so I'm going to do it and I and you show you'll see it that it okay I don't anyway the point is is that look it's it's there it's it's there right we have it right so you can see a file picker I just don't want to show my my my stuff and it keeps going to the same photo which is a bit annoying so in that case that works right the far picker so let's go ahead and I'm just going to pick a image right now say screw it I'll show you something one second um so I'm pick the trell Clone which is a thumbnail and you see it closed right the reason why it closed is because it was submitting because that's the only button there so what it does is it by default thinks that that's the submit button so you say type of button and it does it that way right right so close guys so close so let's go ahead and check out so in this case now if I was to upload so in this case if I upload trell clone you can see now look I have this and if I click it it goes away so that way you've got this um they're all the thumbnails anyway so it's fine yeah so in this case it pops up and as you can see now we've got that so my decision now is if I've typed in a title I want it to go ahead and show ad task right um thank you Ed appreciate it so in this case we've got the underneath the div I'm going to have another div with a button inside of it and in here I'm going to say add task Okay add task now this one I've got a load of styling on it because it's got different states and focuses and everything so I'm just going to show you what I end up putting in but it's fairly straightforward like as in if you actually just take your time and read it it's inline Flex just for a with a bunch of basic styling here but when you hover over it it's got outline and when you focus means when I basically have like when I highlight it so now if I show you this you see like if I tab tab tab you see when I tab it's got the focus ring that's what the focus visible ring part is okay now for this part this button should be the submit button so if I want to submit it should be that one right and then we want to say disabled if I do not have any task input okay now you can see if I don't have any task input it disables that button okay so what's awesome about this now guys is not only is this looking pretty good right so if I go to the top div something's bothering me one second you get you know you get OCD about things when there's things like this like the that you can spot from a mile off so class name margin top uh two and it's also so in this case now so you can see if I was to type in like sun take dogs for a walk and then if I do tab up and down arrows tab upload image Enter key click on something something tab Enter key bam you see what it did it submitted which is wrong I'm going to change that logic but the point was is that it's fully accessible I'm using keyboard shortcuts to navigate that so this is why headless Yu is really good um just as a heads up okay heads up okay so at that point people are like Sunny you've been coding too long that's what happens when you code too long you get weird all right so at this point we've got the dialogue and then I'm going to have the onsubmit that's the final part here so we got the onsubmit so as form here I'm going to say onsubmit handle submit now this one handle submit I'm going to go ahead and make a function at the top we say con handle submit equals e and then basically I've got a nice trick here yeah so and this my coaching students love this in zero to full stack hero where basically if you don't know the type definition here's a here's a trick that I promise you will change your life yeah so look go to here type in E like is in make an arrow function hover over it and now that's the perfect onsubmit is in like every time you don't have to do the manual work and headache of it and all that stuff you just grab the form event and now uncomment this out and boom do the relative like the appropriate Imports and now you have the perfect type definition e do prevent default to make sure it doesn't you know do anything like that we're going to do some defensive coding so if there's no input a do anything anyway and then we're going to have a add task button set image to no and we're going to close the model so uh I'm going to go ahead and pop in the final part there set image to no and close model but here we're going to do an ad task um now I need to create the ad task which is fairly straightforward we just don't have it yet so what I'm going to do is I'm going to create eventually it'll be something like this it'll say add task and then this one will be something like add um let's do it here so state do add task oops add task okay why is that freaking out now um yeah there it go okay so state. add task use Board Store uh go into my okay no that one board store and here where we have delete task I'll add it here so add task is going to be uh containing the following so it needs a bunch of data and this is basically going to push it into the database so you can see we've got the ad task function here that's the signature I want to use and then we're going to have a bunch of data to basically push this so this is probably the bigger the bigger chunk yeah this is definitely a bigger chunk of what we need to do so let's go into the the bottom I'll put it right at the bottom so here I'm going to say add task now inside of here is basically going to be responsible for quite a lot right so this is going to be responsible now for the image uploading because basically if you've selected an image now we need to upload it to the correct storage bucket and then we need to get the uh URL um and put put that inside the image and then we need to upload that and then we need to update all the UI in the on your Global state so I'm going to show you how to do all of that it sounds really complicated but I promise you it's not actually that bad right so at this point we've got um let file equals image or undefined so we we've got a file here and then basically I'm going to say if there is an image we need to do an image upload so I'll show you this and I'll explain each chunk okay so if there's an image f file uploaded equals up await upload image now this upload image we need to go ahead and actually create this function right so I've I've created this helper function for us so we're going to pause here going to go into our lib we're going to create a uh upload image TS um upload upload image let's do it here so upload image you're right actually yeah you're right um that was in um where was I just at I've completely lost it if you can tell tell me it'll it'll help me out all right so at this point I'm going to pop in the function and explain it so this all this is doing this file uploaded is actually the I forgot to make this a environment variable but in this case I'll show you I don't mind showing this one so I mean you would set this as an environment variable to be honest so let's just rather than do that I'm just going to set this one manually to save us a bit of time to be honest but here to do storage what you do is you go to your storage and all we need is so you copy the bucket ID okay so this one if you hover over it you'll notice it says bucket ID so this bucket ID in this case was that then what I'll do is ID unique and then we pass in the file so I want it to have a unique ID which is passed in from aight and then it will return us the file after it's been uploaded so it's fairly straightforward inside of here this is where it was so it was he there you go so in this case upload image and now you can see what happens is is if there an image cons file uploaded this will basically go ahead and upload the image now what will happen is if a file was uploaded successfully we're going to basically take our variable which was either an image or undefined and we're going to uh set it up in this way remember bucket ID file ID that's what we want ahead and set up right so that's basically handling the image uploading section and now what we do is we can handle the next part so that would have uploaded an image then what you want to do is you want to create a okay so creating a document is fairly straightforward right so the next part is we to add it to a to-do what we do is we pop it in like so away databases create document we can import the ID from ight and we've got the database ID collection ID this is the to-do's collection we're saying add a new document with a unique ID this is going to be a title status and remember what we did before the same trick with the file we're saying if it exists then I want you to add in the file the file being the image right so this is actually the image here okay the image is the one that we passed in but I didn't want to mix it up so I said file so then that way you basically will get an image attached to you and we're stringifying the image remember so this will be like if there's an image we're stringifying the bucket ID the file ID or that kind of stuff because it's just text right so it's easy to do now what I'm going to do is I'm going to destructure the response to this with the following so we should get the ID back so I need the ID right so once we've added that now what I can do guys is I can goad and set the new task input as blank firstly so that way uh when you open up another model it's set in the right way then what I want to do is basically have the um the front end react accordingly okay so what I'm going to do is I'm going to set the state to be the correct um the correct yeah the correct thing that I need so basically I'm going to do a big set statement here so we'll do set like so boom and then inside of here what I want to do is I'm basically going to make a copy of the columns remember IM mutable pattern we don't like to modify existing objects we should always do it you know that like a better way then we're going to grab the to-do that we would have added so this is basically making our own optimistic update so this is where the front end is going to go ahead and update and so forth right um so what we're going to do is we're going to get the column that the person is entered the to-do into so in that case if it was in progress or so forth and then if there was no no column then it's going to set the column ID and add the to-do otherwise it will get the current column and push in okay so in this case we actually already do this to be honest with the first set but it's like a it's like a a backup if that first step failed right so when we fetch the to-dos we actually were fixing this so once we've got the new columns all set up we're simply going to return the board itself there we go it's coming in there nice and then we will pop in the new columns themselves okay so now what we should see is the ability to upload an image is successful okay now before I test this out I want to make sure that we um cuz I want to do something like I want to be very ambitious here and make sure that it kind of all works M go basically we've got the ability to add the new task so first things first I need to actually go into the model and I need to enable as then I need to connect it up so add new task is basically here so now it's going to add the task like so so we're basically passing the new task type the new task input and the new task type the new task type I can get from the following here so task type and here we can say state. new task type and now let's go ahead and test it out yeah so let's do our test oh wait no so we add it so this will successfully add it and it should um update the the UI it was what we did in um in the board store now um the only thing we have to do now is on the to-do itself I have to show the image so I want to do that now and I want to Whit list all the domains that we have to do that's the final sort of part I guess so what I've done here is I've actually created another helper function which actually gets us the correct thing so in this case okay so what I'm doing for the to-do card is I've actually made sort of a a helper function to to sort of get us the URL in the correct way so basically okay let me let me show you how we do this so I'm going to create a basically the the URL we we store the image bucket and file ID now the problem is that doesn't give you a URL to render on the screen so we have to create a function called get URL dots which is my helper function and what this one will do is it basically uses the storage um module and it basically we take we pass it our our image we give the bucket ID and the file ID which is what you need to get the file preview and because our you know access permissions are open right now it will give us a file preview URL and that will allow us to render something out as a URL okay so that's how we're basically going to do that part and then what I want to do is the to-do card I'm basically going to have a use effect whereby when if the to-do image exists it will basically fetch the image and then it will like upload it on itself so I'll show you how we do it so we got the to-do card we're going to have a piece of state which is going to set be resemblant of the image and by default it's going to be null okay now when that image when that to-do card mounts what I'm going to do is very simple okay all I'm going to do is I'm going to say that like when the to-do you know item you know rerenders this code should render now if there is a to-do image okay if there is a to-do image what I want to do is have a fetcher function inside so I'm going to say fetch function so fetch image equals an async because you can't run asynchronous code unless you have a rapper function inside of a use effect So eventually we'll call this function there you go then what I want to say is const URL equals get URL so I'm going to say await get URL await all that song This Is My Jam I'm say await get URL and then I'll say too image right and then this one's freaking out cuz we haven't imported it so we're pulling that in and you see this one's not applicable because type is undefined now the thing is I've already done a safety check here for some reason is not picking it up so we're going to go ahead and ensure that it's there okay then what we can do is so I'm going to say if the there is a URL right from this then I will set the image URL so locally so basically What's Happening Here is when the to-do card mounts this one's URL to string because it will actually come back as a uh as a URL value so this will be an actual URL which we can't show on the screen it has to be um a string value so when the to-do card mounts it's basically going to on Mount it's going to if there is an image it will fetch the image add that to the state of that to-do card uh component okay then what we can do is we can basically say if there is an image uh there so if the image is there now we can go ahead and do the following we can say div and I've already got some uh idea of the style here tell you what I'll do I'm just going to pop this in cuz that's this basically what I'm going to do anyway bam so I've got my div and right now my image I need to import from nextjs so we're basically relative height four width four uh it doesn't need to be relative I had that before because I was trying something else but width of 400 height of 200 to make sure it renders you know efficiently we don't need any bigger than that and then I'm basically making it take the entire width and height of its where I'm putting it now in this case object contain means that it doesn't shrink or act weird or look weird now if I've done this all right this will be crazy but what I need to do is I already know that it's going to freak out about the um pulling images from a you know a domain which we haven't wh listed now we're pulling all of our images from the uh app bright Cloud right so in this case we're going to whitel list that domain so now it's the Moment of Truth guys are you ready to see if the ad task worked because honestly I done a lot of changes there I didn't test it out so I I'm pretty confident in myself but I think you know anything's possible it could it could fail at any point so right now we should have put everything all the pieces of the puzzle together in a way that will allow us to open the model add everything to the model click add and then it will basically add that to the back end and it will upload the image if there is an image that we put there and then it will render because we change the global State and then it will show the image on the screen because that would have triggered the use effect on the to-do card which would then fetch the image which will load it so all of that should happen fairly I mean no stress right no stress um the only thing I need to change is the to-do so so you know when I do this right when I click done I want it to automatically highlight done so that's the only thing I'm being very fosty now so in column I want to do that last thing because that's that's like that's that's clutch that's really nice to have so when I basically handle add to do so when I press on on the column so right now yeah so here so I'm going to basically change open model to handle add too and I'm going to create a helper function at the top const handle to do it's going to be a little AR function and I want this one to basically open the model but I actually want to set the type we already have the type new task type here as well so I can basically go ahead and and say set new task typee I can pull it from the board State um no no no no no set new task type and then I'm going to basically say set new task type to the ID right now what will happen is it will modify based on which one I clicked so if we've done this correctly guys when I click on to-do it should have to-do selected cool if I click on in progress hey look at that if I click on done nice that's what I'm talking about right so I don't know what happened there I don't know what I did right but if I go ahead and type in if I click out okay that's weird right so let's type in this um take the dog or this just say build a Trello 2.0 app upload an image TR clone cool add task okay so it should have oh okay ouch um oh cuz I didn't restart I did do that God damn it I did do that I did do that right I'm going to go ahead and restart my server I told you it's a little bit buggy when it does that yeah but in this case it's fine it's fine I'll take that I'll take that I am pretty confident that that will work now yeah let's try again so firstly I mean it's going to go ahead and see let's see now so is everything's okay all right let's see oh oh that's what I'm talking about look at that and you can even move it over over there so let's go ahead and move that over there and let's create another one and let's call this one create a call app upload image what other apps have I got I've got like uh the DI 2 and GPT cool um boom let's go ahead and add that now let's see oh yes it let's go let's go look at that that's sick that's sick all right and if I go ahead and throw over there then this will show that everything's persisting and if I was to just put the icing on the cake let's for example delete this one move this one over here move this one over here now we should have tested all of our functionality if I refresh it should persist in that exact State perfect and then if I type in Trello boom just as the beat dropped that it couldn't have been cleaner couldn't have been cleaner that was nice look at that you got the you got the GPT working everything Al obviously right now I done it so fast the GPT didn't catch the catch the board exactly but that was cool that was cool so in this case now it should say oh no no it was right it was right it's because I had Trello yeah it was I knew it I knew it was right but look at this guys such a cool build honestly yeah there will be kind of edge cases where you know GPT might freak out or fail that's GPT right now it's still a bit bery but right now I think the only thing left to do is get this out into the development environment so this is probably it's lagging yep there you go it's lagging see I know yeah cuz right now I've got it set in the correct way it will work right so yeah see something here is yeah to GPT where I spammed it and moved everything around was just a bit crazy um but let's deploy this right let's get this out so I also have loads of things open so it's probably getting confused right let's get this deployed so what I want to do now is I'm going to show you how to deploy inverell right so I've got a few tricks to this um let's go over here I'm actually going to cut my app right and I believe that's all the feature is done yeah I'm pretty sure the role purpose of GPT in this build was honestly it was a it was it was to demonstrate how you can basically pass information to GPT to provide a summary in this case the summary was very spasic but the point of it is is to provide the platform show you how you can use nextjs API to send data like the to-dos in a to-do board to the open AI API and then you can basically get a summary of it right but in the end of the day you can really take like that's the platform and that's the approach to do it then by knowing it you can actually go ahead and really customize as much as you want but the point is once you know how to do that simple step I say simple once you KN that step then it's uh you can really customize it however however you want to do so I hope that helped yeah okay so this is sick do a deployment now so we're going to say Vel right so this is so if you haven't already done a deployment in Vel it's actually really slick so you need to install the Vel CLI right or you can do the GitHub approach I'm going to show you the Vel way so I've already installed the Vel CLI so just Google Vel CLI so Vel CLI also if you haven't used Vel we have a very special link and if you use that link I believe it is in the description um but yeah we have a special link in when you're using Vel it would mean a lot if you use that link because if you go ahead and actually you know continue to use it it supports the buam and yeah it's just a win-win uh and it's free for you to use so Link's going to help everyone out okay so the Vel CLI you can go ahead and do okay so now you can go ahead and see oops no I don't want to do that what am I doing okay freaks me out all right so let's go ahead and do it so Vel C you can simply import it then I've already done it and then you do Vel login I've already logged in so now you can do Vel to deploy so set up and deploy yes it will ask me which one so I'm going to do Papa react that's my account link to the existing project no okay then we can say what's your project name I'm going to use the Bas project name when which code is your code which directory is your code located so this one setting up your project okay so in this case now we can just let it do it thing modify no it's very simple to set this up and then there's two steps we're going to have to do now so this will fail I'm telling you now it will fail because it has no environment variables so this will actually fail right now so what I want you to do is go to the upright clone here settings go down to environment variables and here so now what you want want to do is open up your code go to your environment m m. local oops what am I doing no no no no no go to your m. loal and I'm going to hide my screen but I want you to click it okay so click inside it here your and copy everything so control command a copy all inside your environment file right now once you've done that I want you to go to the um what's it called I want you to go to the project settings page here and paste so I'm going to paste everything right now so I'm pasting right and then I click on Save right and as you can see literally if I press contrl + V paste it pastes it in and it comes like four blocks here and then it adds it and then you click save and it will add over here then once you've now that you've added it what I want you to do is basically cancel this build and do Vel once more okay and then I don't I'm not I don't know if I'm going to make this uh the the I'll share it a little bit but I'm going to show you a little bit because otherwise it's connected to an actual build build open AI account it's going to get a little bit crazy right so but yeah you guys can see so right now it's doing the inspection so you can click it and now we're redeploying with the correct things in place now this might fail on based on some silly reason but we can check ourselves so you want to let that do its thing and if that goes through then you'll see a deployment complete right so in this case we can go ahead and check you can see it deployed but nothing shows now the the final step to getting it working is this is the URL so what I want you to do then is go to your um where was it go to your app right settings and now here in your ight settings you need to go to overview oh sorry settings down here and you need to go to uh your domains where is it at custom domain no it was where's that setting on uh it was very easy to find uh databases is it here settings no okay where is it okay I found this literally a second ago and it's going to drive me crazy if I don't find this okay where is it here it is in platforms click on platforms There You Go Local Host yeah so you want to paste in your your domain so you want to do this and then you probably need to get rid of https so that's the one yes you want to do that and Local Host is always protected by the way so you can use it all right but now if I go back to my app there you go boom you can see it right now this is going to go crazy if everyone starts going on it so obviously I don't want to do that but yeah you guys I'm not going to give the URL but it works okay so right now as you guys can see this is all you guys adding it this is lit I can see guys adding stuff here this is cool man thank you Sunny awesome I love you I love you guys too wow that app was incredible guys it's very impressive when you've got an app that can do something interactive on your digital portfolio and this is the perfect app to do so congratulations on building the AI Trello clone with drag and drop functionality not only is this going to go ahead and impress at the next interview you go to but it's also going to go ahead and teach you how to add interactive libraries into nextjs 13 apps now if you got stuck at any point especially around the drag and drop features cuz that can be a little bit tricky then make sure you check out the GitHub repo because that's where all the code is going to be located so you can go ahead and debug against it the link is in the description to go ahead and look at that and if you want to learn more and actually really understand how to build up your skill set to understand how we write this code in the first place and get to that point of really mastering this stuff then I highly recommend you check out our course on community 0 to fullstack curo members are going to be able to help you out myself in the weekly coaching calls will be able to help you out and we have dedicated modules which literally hold your hand and guide you through topics that we've been talking about in this crash course so go ahead and check it out first link in the description and finally guys it's time for the fourth build of the AI crash course our fourth and final build is here we're going to be wrapping things up with a real time AI weather app not only is this going to pull information from an external API but we're also going to go ahead and transform that data and pass it to the open AI GPT service to go ahead and provide a summary so imagine that you have an AI weather person giving you a digital summary every single time you go ahead and check in on the weather that's definitely something to go ahead and impress your next interviewer by adding it to your digital portfolio alongside all of this you're going to learn the following in this build next js13 reactjs trema 2.0 how to leverage the free weather API how to launch your own graph cure back end using stepen how to write robust code using typescript and how to make your entire app look elegant and beautiful like you're going to see by implementing Tailwind CSS without further Ado let's go and build your fourth of four builds inside of today's AI crash course enjoy the build let's take a look at the demo right now check this out guys boom naturally I had to start off with Dubai look at this guys we've got a lovely lovely weather wrap right now and this is something I want everyone to have on their bloody portfolio because it's such a good way to Showcase your skill set fully responsive build look at this works perfectly on a phone we got these lovely nice graphs that are Dynamic responsive look at that it just looks absolutely beautiful I just skipped through a different page there we go and guys something I want you to pay close close attention to is this right here this is literally not me writing this this is a generated gp4 prompt that is gone ahead and being created based on the weather information so you have a full news report this is sunny reporting live from the papa headquarters in Dubai bringing you the latest update on the weather conditions in our beautiful city and it goes ahead and literally breaks down the weather now let's go ahead and do a little demo of this let's go to the United Kingdom and we're going to go to my first home London boom and wait for it look at that super fast Dynamic oh it's just so beautiful and this is all working off next year's 13.2 we have the the chat GPT API step Zen is powering this so yes we are using a graph Q interface if you're wanting to learn that this is the video for you we have trema 2.0 for these beautiful UI pieces like right there like you can see here all the these little lovely little call outs and these nice little cards everything that you can see here tra 2.0 Tailwind TSS to style it all and just look at that guys absolutely beautiful and it's actually really useful like it actually works we're going to go back to the United Arab Emirates and let's go to somewhere else let's go down to um let's do cowbo right and look if we don't have the information it's going to have a dynamic fetch so right now what's happening is it's crunching the numbers it's generating an AI summary using the GPT open AI API and then just very shortly boom just like that it has it and what it will do now is it caches that page so that the next time we go back to this page super fast right so if I go back a screen look at that London super fast for the screen CBA and then it's going to revalidate that page every 60 seconds or whatever the hell you want to set it to so that way no user will ever have to wait that long time again so absolutely incredible this is honestly like now we're hitting builds which are just in a different League of complexity in regards to how what they can do I'm going to make everything easy for you so you can feel free to follow this s if you're a beginner but let's go ahead and break down some of the TCH tack right here we have GPT 4 you guys know how we do it I have access to it you can also just for so that way you know in case you don't have access yet to gbd4 completely fine you can do this entire build with GPT 3.5 turbo and it just works just as good so don't worry about it right you can actually do it with all of those things as well let's go ahead and show you showcase step Zen is how I'm able to go ahead and take this incredibly like complex data from quite honestly it's a lot of data that we're going to get from this API it's called open Mato it's a free weather API and this thing gives us a huge dump of information and we're going to go ahead and pull it through with a beautiful graphql interface and steps taking all the comp out of it I have something new in this build which I haven't actually used before trema 2.0 now Jay introduced me to this I actually love this thing is so nice and clean look at this we have a react component Library I get so many like so much demand for this right I have so much demand for can you use a component library and I was waiting to find one which perfectly integrated with Tailwind CSS with next sh so that way we don't have to mess around with the kind of you know like we're battling between Tailwind CSS and component libraries typically not anymore this is where trema 2.0 came in it's absolutely phenomenal you guys can see here we have these beautiful looking components so you guys can see like we've got these lovely components you got these little tabs you got all everything you need for kind of a dashboard look at these and what I love the most is honestly not just the fact that it's really beautiful to look at I also love the fact that it's so simple to actually Implement so you guys will thank me so much because if you've ever used anything like chartjs or any of those kind of react charts um modules you'll find that sometimes it can be a little bit complicated but I'm going to make it super super easy quick little demo one more time to Showcase you guys how fast this website is Bam just like that we get a brand new AI summary so really really powerful and yeah we have so much to cover and I'm going to go ahead and start things off by getting a little breakdown on the screen so that way you guys can see what we're about to build so what I want to do here I had um I was teaching a few things before so what we're going to do here and I was actually teaching that in side of 04 s we run coaching calls if you want to be a part of that link in the description to join our community so what does this build consist of we've got react in the house we have nextjs 13.3 in the house right so we're actually using the brand new API Roots so if you want to know how to use those this is the right place to be we are using GPT 4 in today's video but don't stress you can use 3.5 turbo so you don't need that early access if you haven't got so got it yet we're going to be using steps in to build a graph ql endpoint right so we're going to be using a graph ql endpoint which will then be powered by something called Apollo right then we have the Tremor 2.0 Library this is going to allow us to create this beautiful looking UI that you see right here then we've got tailn CSS so if you don't know what this is oh boy you're in for a treat I'm going to teach you all about it then we have typescript and finally we're going to be deploying it on our amazing Vel platform right so this is going to be deployed afterwards I'm going to show you how you can actually get this live and up because cuz I want you all to have this on your portfolio because it is beautiful and it's a perfect demonstration of how you are using AI techniques with the latest and greatest like nextjs 13.3 steps and you know tell CSS typescript that good stuff so let's go ahead and jump into today's video remember if you haven't already check us out at zero to full stack hero and check out the University of code I promise you you will not be disappointed now first thing we're going to do is start our app so let's go ahead and I think it's time to push in into this build so I'm going to go ahead mix up the music a little bit if you sign up to the newsletter in the description you actually get the entire newsletter I always get people ask me I literally get this question all the time okay so what we're going to do now is if you haven't joined any of the streams before we're going to get into our Flow State we're going to start coding we're going to build this project out bit by bit and I'm going to show you my thought process as to how you are going to go ahead and craft this incredible app yourself okay and I'm going to break it all down don't worry about it we're going to do this very strong okay first thing I want you to do is run this command now if you haven't got MPX you're going to need to install node okay in this case I've already got it now I like to actually use at Canary instead of the uh latest but you can feel free to use whatever the hell you want right so in this case I'm going to open up my terminal now if you're using on Windows you can use that I'm going to use a terminal on Mac I like to put everything in an organized fashion so I like to put it inside of my build folder there we go and then I'm going to go ahead and run that command so at Canary that's what I like to do then we're going to give it a name right now you don't even have to a name here but I'm going to go ahead and give it a name I'm going to say this is going to be the stepen weather app YouTube okay hit enter to kick start things off now you should get a prompt now I want you to understand that if you're watching this video in the future there is a high chance yes you might have a different prompt popping up right now or it may not work don't stress out okay just use the create next app template and then install things like typescript and tell in CSS following the instructions on the website I really get that a lot of the time so definitely don't stress out when you kind of get that uh that that situation right would you like to use typescript with this project yes would you like to use es lint with this project yes Tern CSS yes would you like to use the source directory no and would you like to use the experimental app directory I want to use it so yes import aliases these are amazing this is how you can import more efficiently we're going to click yes and then we're going to go ahead and let it do its thing okay uh let's go ahead and wait for this to get started a lot of the time what you might have found was the old template that I used to use stopped working and yes I experienced that as well so that's why sometimes you might have to use a different template in this case I'm using this one right now okay so let's check this out so we're now going to CD into that new directory so CD steps Z weather app- yoube okay now I'm inside then I'm going to go ahead and type in code dot this will bring up my code editor which is vs code and it will give me my starter template now what I want you to do is open up a separate window or a second screen if you have one and basically set up your window so you can effectively work in such a fashion okay now the first thing I also want you to do is go ahead and you can remove that fine I'm going to make it a little bit bigger so you guys can see what I'm doing let me know give me some feedback if that's all good and we're going to be using next year 13 so as you can see we have the new app directory whereby everything inside of it is a server component okay so to spin this app up first things first we're going to go to app then we're going to go to the page. TSX and as you can see there's some code in here now I want you to do the following I'm actually going to cut off my previous app because it was running I'm going to go to output and I like to Simply close that one and close the debug console to make it very clean I'm going to close my previous app that was running I have taken screenshots for reference so that way we can actually go ahead and do it um pretty nicely right give me one second okay so at this point now we're going to go ahead and if we do command you can see we have a package Json now if you have a Yar lock file you will be using Yar I'm using mpm so in this case mpm run Dev this will spin up my app on my Local Host 3000 okay so at this point I want to allow it yeah because we are using typescript and then I want to go ahead and pop this open so I want to have if I about go back here I'm going to create a new Chrome um window pull it over here and I'm going to go to Local Host 3000 now what we should see here as you can see it's running in my server over here we should see our first starter template now if you're at this point well done give yourself a part in the back because honestly some people can get messed up in this area so make sure you get to this point very well now what we're going to do is we're going to keep this open and we're going to clean things up so first things first everything inside of the main we're going to go ahead and delete so we're going to scroll all the way down go to the div and we're going to get rid of it right I'm going to type in H1 and I'm going to say let's build a GPT for weather app right so let's build a GP for weather app now at this point you should see this what I want you to do is we want to have a clean slate so I'm going to clear out the class names and I'm also going to clear out anything up here so you should have a very clean uh section right here now because you can see here it's black you might be wondering but I don't have any stars so first thing you want to do is head over to global. CSS and I want you to go ahead and delete everything underneath these three lines okay now what you'll see is you should get back to a if we refresh you should have a white screen with a very blank uh text piece of text at the top okay all right so now one thing you should be aware of is you just want to make sure obviously it was working for us but here you want to go ahead and type in something like Tex 6xl just see that it's working okay so the these are utility classes and this is the power of Tailwind now if you haven't got these Auto completes so for example when I'm typing in you see these Auto completes we have right here then you're going to need to go ahead and install the following so you want to go ahead and type in Tailwind and what you want to do is grab the first one here so tail in oh my God tailn CSS intell sense so at this point we're going to go ahead and install that which we've already done and I also want you to get this one I always mention it every time because it's just such a good um uh extension but here the es7 react Redux Snippets okay make sure you do this this what allows to create files very very fast now we're going to take a sort of a nice breakdown structure to this app okay so what I've done is I've actually created a few screen shot for reference and I'm going to go ahead and pull those screenshots up right now so what I want to do right here is I'm just going to go ahead and uh pull out my screenshots and then I'll bring it onto screen so that way we can see it so here I have some design references so here we have the entire website so as you can see this will be like the city name at the top we have our lovely sort of you know our chat GPT summary then we have our different statistics now this is a really good build now like what's the main purpose of this build one you're using things like that graph ql you're creating your own graph ql interface secondly you're creating an admin dashboard like experience for your user but you're making it more interesting because you're adding the element of AI involved and what you're going to then show employers or anyone who's looking at this from inside your portfolio is your ability to you know take on the latest and greatest bits of tech bring it together and build something really beautiful so do not underestimate this build okay then we have the mobile U UI so in this case you can see that this one will look really nice on a phone so I'm going to go ahead and pull it up like this you can see everything sort of stacks up on top of each other on the phone so we're going to go ahead and build that as well and then we have the loading weather information screen so this will be the very simple homepage if you haven't selected any City but otherwise it will go ahead and pull up the City View All right so this is going to be the main City View that you'll be seeing inside of this build and do not be underestimated this is a very big build okay we have actually a lot to do here so we have we have to get very busy right now so okay so first things first what are we going to do we're going to go ahead and actually keep that reference open cuz that was very silly I need that reference so I'm going to go ahead and open up another screen here and pull this over here okay and now we're going to keep this in frame and what I want to do is my first screen let's actually conquer something like this right so I want to actually build out this sort of drop- down menu now the whole purpose of this drop down menu is I should be able to sect the country and then what I will see and remember it's a reusable component so the same component is being used here I will select the country and then it will show me the city and I will be able to select a city inside of that country now after that happens it should redirect me to the page in which you see right here so first things first I think we should knock out the homepage okay so that's exactly what we're going to do so the homepage let's go to our page. TSX and then at the homepage we are going to go ahead and start building things out now uh where did I go yeah so here now as you can see these elements right here here this is actually called a card element from trema UI right so that trema 2.0 and I'm actually going to go ahead and get that up and running right now so for this page element I'm actually going to convert it to a client side component you can actually you know you can actually pretty easily wrap what I'm about to do inside of a client component instead of making the entire page but for the essence of time we're going to go ahead and keep it fairly straightforward now the second thing is the only reason I'm doing this as well is because trema 2.0 has not been updated yet to support uh client components out of the box so that way we have to tell it it's explicitly a client component so what I'm going to do is go to trema doso I'm going to install trema so installation you can see if we go to nextjs you can see as you as you can see here so since we have not fully migrated to xgs 13 you need to go ahead and use the um wrap your terod in another component by using the Ed client directive Okay so we've already done these steps we're going to install trema into our project okay so let's go into our project command J and I'm going to split my terminal in fact I'm just going to open a second terminal so the first one's got my server running and the second one I'm going to say mpm install trema react okay so once that's done we are then going to go ahead and we've already done the tail ins set up cuz that was already in the template we then need to actually go ahead and extend our content here like so so we need to grab this selection right here really nice and then we're going to go to our tailing config and you can see where we have our content we're actually just going to paste that line and what this is doing is it's including Tremor files in that transpilation right so when it sees any Tailwind utility classes it's also going to go ahead and convert those as well so that's what we got to do there that's done nice we've already got this set up pretty neat and we can just start our run our server which is great okay now you can go ahead and uh do this so I actually did get this error in a few different areas so what we can do here is we can actually pop this in because I actually didn't I forgot to do this to be honest with with you because I actually did get that error that it's coming up with um so we're going to go to our next config as well and where we have the experimental we just going to copy this in as well okay and now what I want you to do is make sure that you go back to your initial terminal because you just changed the um the config file I want you to cut your terminal and I want you so contrl C so go into your Terminal contrl C and I want you to mpm runev to restart your terminal okay now with that done we're going to go back to our app we're going to refresh and we're going to make sure that the app is loading okay if we get an error at this point we know we need to fix it so take things at this granular speed let me know if the speed is so you can see our app works successfully that is amazing okay so at this point we're now going to go ahead and do command J to hide that okay so first things first we need to import some of the elements that we require from trema um the trema component Library okay so I've gone ahead and pulled those in great now what I'm going to do is I'm going to go go ahead and pull in a card so I'll show you how we can Implement a card so if we simply pop a card in like so what you will now see is that there is simply a card wrapping this element right so you can very subtly see it right so it's a card wrapping it okay so at this point now what I'm going to do is I'm going to use the text element and I'm simply going to type in weather Ai and you can feel free to name it whatever you want okay it's completely up to you I'm then going to go ahead and use the subtitle component right so I'm going to go ahead and use the subtitle component and this one will say powered by open AI nextjs 13.2 or it's actually 13.3 and uh yes so let's correct that 13.3 T CSS tra 2.0 and more and as you can see now we get their nice little UI that's really nice okay and then what we can actually do is start we what's really nice is that these trema doso uh components actually are built with T1 CSS in mind so you can just directly extend they also have their own colors and so forth they have colors they also have um and it wasn't the side it was colors yeah I don't know if is it font size no so you can just change it like this you say text for example 6xl and then you'll get your nice bigger text okay so we're just going to go ahead style this out a little bit right now we're going to say the text should be centrally aligned text should be centrally aligned and the margin bottom for this one should be 10 and now we've got a little bit of spacing Bolding it out that looks very clean right for the subtitle we're going to go ahead and say that it should have a class name of text extra large and it should be the text centrally aligned okay very simple very straightforward and then what I have underneath here is a divider now this divider is simply going to have a margin on the y- axis of 10 okay so we should see a a nice little divider now so everything is fairly straightforward fairly easy to go ahead and comprehend underneath here we're going to have another embedded card and this is where we're essentially going to have the country live right so this card right here so you can see where we're going towards right so if we go ahead and pop the card in right now you can see the card is on the screen and then here we're going to have the city picker uh component right so we're going to go ahead and actually create that custom component very shortly now for the class name for the card I'm going to have a back background which is a gradient and what we got to do here is we got to specify the from color and the two color okay so I'll show you so we say background gradient to the bottom right okay and then we say from this color to this color all right and you can actually choose whatever color you want I've just got two very similar shades of blue and it kind of is very subtle you might not be able to tell but that's exactly what we've done here okay now what we're going to next do is we're going to go over to uh the top and we're going to start styling this out so that way we've got the surrounding uh stuff like correctly done so here I'm going to go ahead and change this to a div cuz we're going to go ahead and update our main all right so we got the um div class name 66 I don't know why I put 6xl there okay we're going to say Min height of screen okay and then that's going to bring it up and then we're going to say background gradient and we're going to use the same gradient effect that we previously used okay so I'm actually going to go ahead and pop that in like so so I'm going to pop it in just like this I'm going to pull that in over here and what you'll see is that it's now using the maximum height of the screen so you we set the minimum height of the screen and then we're going to say padding should be 10 right now it's touching the sides we do not want that okay we want to have a bit of breathing room so padding 10 Flex Flex column and really it's up to you with this with this essence right what we're going to do is flex column because there's one child here and by doing this we can say justify that one child in the center with this little hack and what it will do is it will send to that evenly so we don't have to you know worry about how to deal with any of the calculations it just does it nicely okay and then you can put a Max width constraint if you really want to and so forth if you were going to do that it's very simple you just do Max width uh like 3XL for example and then you can see right here so that's actually done it for the entire children you might not want to do do that you would if you want to do that you would simply do it here you would do like Max width 4 XL and then you do MX Auto to maximum Center okay and what this will do now is it will M it will restrict that box so that way it doesn't take up the entire sides in the design you s it took up the entire size sometimes that can look messy so you might want it like this okay we're going to go straight over to the city picker right so let's go ahead and create a city picker component so first thing I want you to do close the app folder click on the package Json folder so that you're at that level now I want you to create a folder called components inside of the components folder and it's also worth mentioning that any component made in this folder is also going to be a server component by default so anything in next year is 13 uh uh 13 and above is actually um uh is actually using um server components by default notice say when do you start using GPT patience my friend patience right uh so we're going to say c C City picker City picker. TSX boom there we go RFC there we go and yeah just like that now I do want to mention anyone who's just tuned in the area which GPT is actually going to be amazing for is we are this is literally me providing a huge block of data to this to the GPT prompt and it goes ahead and gives me an amazing summary just like this based on all of the weather information that is actually Game Changer incredible powerful sort of thing to happen right so we're going to be doing that in just a second like shortly so we've got a C pick a function uh functional component so we're going to go ahead and pop that in like so and those aliases that we saw earlier is this now what this is doing is you don't have to go ahead and do the traditional you know upper level upper level upper level so forth rubbish now what you can do is you've already automatically set it as an alias and what this does is inside of your typescript config you can set the path now what it says is if you have your at for/ symbol it automatically goes to the home root directory and that's really handy because then you don't have to go up and up and up level you just go ahead and simply do at component and so forth and at Live or at um API and so forth like anything you need to do is just to jump to the top level you just do at right really cool and you can actually add custom ones any of that good stuff so I recommend you really do get used to using that now as you can see our city picker is there there so the next step is to naturally build our city picker okay so this city picker right here we're actually going to need something called country state city now I'll show you what this is this is actually an mpm package now as you can see here npmjs we've got the country state city package you can see it's quite a popular library and what this is really good at is it gives us a list of all of the countries all of the cities and we're going to use that to populate our drop- down select menu okay so first thing things first we need to install this so how do I do that we go ahead and mpmi Country state city so I'm going to go ahead pop this over on the side command J bring up my terminal HP into my second terminal and then we're going to do mpmi country state city now this is in installing that dependency into our project then what I want to do is pull in that dependency just like so so let's go ahead and do that right now boom now we have our country and our city right now we are going to need some client interaction components here like such as state and so forth so we are going to convert this to a client component okay so in this case that way we can have things like State and so for I'm not going to go too far into that if you are interested in any of those things remember definitely check us out at zero to full stack hero the course and Community the link is in the description I teach everything about xgs so if you if you're finding this like way over your head check us out and I promise you it will break everything down inside the community okay so next things for next thing we're going to do is we're going to go down to um our we're actually going to go ahead and install the select react select Library as well because we're going to need a select field right so in this case the next one we're going to do is the react select Library so this is a really handy library and it's very good for things like drop downs now what's good about it is you can simply type into it as well and it handles the type search select sort of functionality that we might need which is something which you're going to need a lot of the time right so we're going to go ahead and install this into our dependency remember yarn if you're using Yar you can use that we're using mpm so let's go ahead and do it like so pull this up install it like this and now we have a react select inside of our project and as you can see they've got a nice demo of the the the sort of type of data that you have to pass it in so what I always recommend is that you get very good at transforming dat a again we actually have a lesson about this inside the course but you can see that this is how the DAT a is expected to come in so we have to go ahead and just customize our data so that it pulls into that in in that shape and form okay and that's pretty much as simple as it is so now what we can do is we can go ahead and head over to our code and we can start using this stuff so first thing I want to do is import the select library at the top so just like so import the select library and then I'm going to go ahead and actually Define the options that you saw just there so remember these options right here I'm actually going to convert all of the cities that we've previously installed from this country state city into that format so how do I do that well it's very simple I can say const options equals country right so country do get all countries okay what this will do is it will return all of the different countries so if I click into this you can see I've got I countries and it will get have all of these bits of information inside so name phone code ISO code flag everything like that Etc we're going to map every single country into the following ship so parentheses and then brackets and then we're going to open it up now here what I want you to do is remember there's two types of information we need we need a value and a label okay so the F the value is going to include an object and inside of the object we're going to have latitude longitude and ISO code okay so these following data then we're going to have the label and for the label I'm just going to use the country name so this is the options in the in the state that we need it okay the next thing I'm going to do is I'm going to go ahead and pop in my um my select field here right so we're going to have the select field that we previously talked about then we're going to have the options right and we're going to Simply pass in the options from the above right that we went ahead and created now if we go ahead and hit enter now what I want you to do is I want I want you to just test it on your site okay so go over to your site and as you can see here look at that we already have all the cities inside so this is a great point to sort of test your logic see if it's working and so forth right and you can see you can click in and it saves it and so forth right so at this point you now are pulling in all all the countries inside of your app okay the next step we now we need to do is we now need to monitor the users so that way when they go ahead and click into this right so when they click into it we're going to store that piece of state and then we're going to show a city now what we're going to do is on that City selector we're then going to have um all the cities from the determined country that you've selected so if you select Angola it's then going to show the cities corresponding to Angola and so forth okay so let's go ahead and do that right now as well so first thing we're going to need to do is actually have a piece of state to track the user's input okay so the first one we're going to do is have a selected country piece of State okay so this is going to be a uh option right so we're actually going to create a new type called option very shortly and then we need to actually in import the UST State hug so what is this option right so the option is actually going to be the type that I actually went ahead and defined here so value label and so forth so I'm going to go ahead and show you how we can do that right now so we're just going to pop that in and this is a types script definition and what's really good about this is it's actually going to go ahead and make it um so that we can type protect when we're sort of you know messing around with things so that way we can be sure that we're not going to make a type error in the start without kind of you know moving ahead next up we need a selected city right so it's going to be the same principle uh in this case it's going to be a city option however so in this it's going to be a city option now a city option slightly different values and I'll showcase system right here so we've got the type option over there then we've got our city option the value in this case will be latitude longitude country code name and state code then the label will be string okay so not far off it but now we've got our C option and our option so we're pretty much prepared for the next step okay now the final step after that is we're going to have a router now the router is because what we want to do is once you've selected your country then you select your city I want to basically take that information and redirect you to the page where it's like for London SL longitude/latitude so I'm actually going to PO send you to a page where it's your city then it's your coordinates on in the URL and then that page is actually going to be cachable and so forth and there's a reason why we chose to do this architecture because of the way that the API works and everything like that but it works pretty nicely and you'll see for yourself now be careful when you import your router do not make this mistake you see if I did it this approach this is importing from next router we do not want to do that we want to import from next navigation since we are using next shs 13 so don't make that mistake I promise you it will bite you later on so you want to be a little bit cautious about that okay so what I want to do now is inside this select field I'm going to go ahead and map our value so we're going to say value equals selected country okay then what I'm going to do is I'm going to say on change right and I can simply pass in something like handle selected country and I need to create this function and this is going to be a function which is going to be responsible for handling the um when I've selected it okay so in this case what we're going to do is we're going to say con handle selected country and then the prop would be the selected option in this case we can rename it just simply to option and this will fire off when the user select a country okay so in this case handle selected country then what I will do here is I will set the selected country to oops no set sorry the selected country to the option okay and I want to set the selected City to no and the reason why I do that is because if you change the country you want to actually reset your city selection okay in case you kind of went backward afterwards so at this point we are going to check that this still works you see there we go we're still getting our selection value so nothing yet has broken okay then I'm going to just simply enforce that the text is black as we tend to use this in a few different areas later on okay so that's looking pretty neat so far after that I'm going to have a label uh on top of it we actually going to have the um a label like so so a label and this is for the country and this is going to be country like so okay and then I want to have a globe icon now I do want to use something called hero icons inside of this build okay so what I want to do is I need to install that now hero icons are how we get these lovely icons inside of our app and the icons in question right here are things like this and they also something used by the Tremor Li so if you are installing trema what you will find is that we are actually needing to uh install the hero icons package like so okay now you can install version 1.06 I'm actually just going to install hero icons react like that and then we can go ahead and continue on so hero icons react okay and just like that I just want to double check the versioning that I have on mine so you guys can get the same versioning so because I understand that sometimes things get updated so here are icons 2.0.1 7 that is correct okay so that's the value I'm using right now so now we can start using our the required um icons inside of our build so what I want to do here is I'm going to import it into my uh file so I need the globe icon inside of my file so I'm going to go here simply pop in the globe icon like so now here you can see we actually need to install the type definitions for this so as you can see here sometimes you need to go ahead and import uh install them separately so let's go ahead and run that command types hero icons react and then it should install the um type definitions for us I believe we might be able to do it this way let's see if it does it right so sometimes I get this a bit of an annoying issue I'm actually going to Showcase how I did it in just a second let's go to our package Json and it should have actually pulled those in to be honest with you what I think happened here was if I go back to my package Jason yeah so what's happened here is hero icons has been installed but the actual default hero icons has not been installed so what I want to do is I actually want to install just the basic hero icons as well okay so in this case I'm going to say mpmi hero icon cons okay that's added the package let's go back to our file and see if we have our type definitions yeah we should do to be honest with you let's go back yep so now okay that's a bit annoying we don't have it yet let's go ahead and debug it let's see so I've got my hero icons 207 and I have my hero icons Rea okay so the reason why is because I actually did opt in to use the one that they've recommended so what we're going to do here is I'm going to delete this dependency and I am instead going to replace it with the one that they're recommending just for this demo so that way we can kind of progress on I don't want to spend too long on this so we're going to install this version of the hero icons package okay so we're simply going to go ahead and use that recommendation there and what you will see is if we go ahead and uh oh we're going actually don't save that one go back into the file now we should have our hero icons 1.06 and then our hero icons here have 2.017 yeah there and there we go let's got rid of it okay so for the Dem most purposes that is completely fine uh you can feel free to debug it kind of get past that bit fine afterwards right so now back to our build I don't want to spend too long on things like that cuz we have a lot of cool things to do right so in this case I'm going to import the globe icon into my file so we already did that at the top and then I will pull it in like so and I simply style it up accordingly okay now I'm going to go ahead and style the div like so we're going to say class name Flex items should be Center uh centrally Space X of two and then the text should be white with an opacity of 80% bam just like that it goes in right so it looks clean and then here I'm going to say space y of four for every child component I have here so in this case you see how they spaced out a little bit okay so that's looking pretty good already I already like the look of this and what I want to do next is I actually made a little mistake here so I actually want to wrap the entire selection of things I have here so everything up to div here and then I want to go ahead and do space y of two I thought it looked bigger there we go nice okay and then what I want you to do is I actually want you to go ahead and very simply copy this so copy this pop it in like so okay now you have two you have country and Country Now the second one I want you to change it to city but here I'm going to add a conditional and what I'm actually going to say is I'm going to say select Ed country and and then I've got my parentheses and what this is saying conditionally render this only if you have a selected country so everything that we just copied I simply want to take it paste it inside of that okay now if I refresh this page you'll see that I don't have the city but the minute I pick something boom it shows a city now the city we need to go ahead and change it to the value is going to be the selected City and then the onchange will be handle selected City instead okay now handle selected City very similar push let's go ahead and create a different follow up here we're going to say con handle selected City equals this is going to be option but this time we're going to use the city option type definition okay and then we're actually going to say set selected City to the option that we pass in and afterwards remember I said we're actually going to redirect the user so what I want to do is I want to prepare us for that so I'm going to say rout to. push slocation okay I'm actually going to do back ticks here so I can have some string interpolation for/ location and then I'm going to go ahead and actually push through the name SL latitude SL longitude okay so location and then I'm going to go into it and I'm going to say option do value. latitude okay for slash option. value. longitude right and then that one we close up now as you can see they've automatically added this optional chaining in the event that option isn't working okay so in this case we've got this running now what I'm going to do is I'm just going to comment this out just for now while we're testing it CU I don't want it to redirect me otherwise it will say a 404 redirect okay now here for the options we actually have the city now as you can see I've actually just punched it in over here um no so you can't see sorry I need to show showcase that so we're actually going to create a city options now as well so for the city options I'm actually just going to do it in line to Showcase what we can do here but for the options I'm going to to go ahead and say city right so imagine let's just separate that we're going to say city. get cities of country and then here I'm going to pass in the iso code okay so this is actually getting the selected country value. ISO code now ISO code is like the sort of you know representation of that country by a special code and then what we do is we conditionally chain off of it say map and then we get um all the values back from it right so at that point we will get the city so cities and then we can go ahead and do the following so I'm actually going to just call this one state for now I'm going to do a parentheses and return an object and inside of that object I've got a value and a label just like we previously did before so latitude longitude country code name state code and label if you really want to make things a bit easier you can feel free to rename state to something like a city but in this case you can see we're just mapping it in line I'm just showing you how you can do it in line you can feel free to refactor this have it in a US fact that kind of thing you know as you wish it's completely your call okay so now we have handle selected see we've valued it um there we go and then we've got our options so at this point we should be pretty good so let's try out guys we're going to go over to somewhere like the Dubai so in this case we're say United Arab Emirates and I should only see cities now for yes theae this is perfect let's go to uh United Kingdom and now here we should see things like you know London so if I typee in there we go so let we only get the cities in London that's perfect if we go to somewhere completely else like you know we could say Al uh let's go to Portugal for example Portugal cities load up right amazing stuff right so you can see now it's working in a way that we wish so why the final step is I can simply go ahead and un comment this router. push and then let's see if it redirects us so pay attention to this the URL at the top let's go ahead and go to for example Dubai so United AR Arab Emirates Dubai and then now what you'll see is we should get redirected to that location and as you can see on the screen what we are seeing is you should be seeing something like this HTTP Local Host 3000 for SL location for SL a latitude and then longitude okay so we need to create a dynamic endpoint which will support this so let's go ahead and do that right so at this point we have our home screen done so we can navigate to our first city so this is where the real fund comes in right this is where we're actually going to start building our back backend infrastructure our graph QR API all of this good stuff and then this is going to go ahead and get things in right so next thing we want to do now is we want to go ahead and build out that second screen okay so I want to have some kind of screen that supports it so we don't get a 404 okay so how do we do that so if you're not sure on how to do Dynamic Roots especially at that level I will make it so easy for you that you will honestly be like wow that's so easy okay so we're going to have a for slash location because that's how we do the the the naming structure here so for the root inside the app pholder we have for slocation this will be resembled by for slocation on our website inside of that what we do is we have square brackets to determine to basically specify that there is a dynamic value that will be supported so in this case we're going to say the first one is City then clicking on City we're going to create a new folder and inside of there we're going to say latitude right so lat and then inside of there we're going to say long okay and the reason why I've done this one this structure is because I'm going to be caching based on city lat and long okay so this is really really clean all right so at this point we are going to uh inside of that long we're going to go ahead and uh add a new file page. TSX so we're going to go ahead and add that in page. TSX and this will create a page at that point RFC all right so at this point this is going to be we're going to call the this one um let's what did I name this one just going to call this one the you can really name this one Whatever you want don't really matter here we're just going to call this the weather page right so weather page get rid of this and then you can say welcome to the weather page right so now we should have a page at that route and it's time to test it so provided you did it all correctly let's go to somewhere like Albania let's go to B and then you can see for 400 so let's just double check location and then we have everything correctly set up let's let's have another look at what we have here so let's just confirm that it's in the correct folder so it is in the long folder what we may need to do is hit save one more time go back refresh okay so we don't have support yet in the correct place so City lat long let's have a look we got page. TSX export default okay that's all good that's looking fine and we are returning our div that's completely fine as well let's complete let's cut our server off on the first one we're going to cut our server we're going to npm run Dev one more time city is not in the URL oh thank you guys that's what I'm talking about ah there you go look at that that's why I love debugging on live stream right that's so cool right that's what I'm talking about so that's the power of pair programming right so that's where I forgotten it so thank you so much for pointing that out guys here we have our issue we don't have the city so option so so nice right so we have our city pick here and I believe it is just like that yep so option. value. name now we are doing it correctly okay that's that's phenomenal when I think about that and I think that you're actually watching it to that degree that shows me how committed the papa fam is I find that incredible right so we're going to hit save here now let's go ahead and restart our app I think it's rebuilding y there is is is rebuilding so we should see our homepage in just a short second all right so at this point we're going to go to Albania we're going to do uh we can do anywhere really bage and now what we should see is welcome to the weather page let's go that's what I'm talking about and remember that's so if you get to that point don't stress just do what I did there and speak to your community no no just go ahead and debug it right see there is always a reason why something's not working now how do I get access to that City that longitude that Latitude right so cuz I'm going to need that later on so how do I get access to those things well actually we get the props come through here so the props actually contain a few pieces of information right so really what we're going to do is Define our props and I'll showcase it to you so the props come through in the following shape and you can check for yourself but it includes the prams as part of the arguments right so in this case we've got C lat and long which come inside of it so what we can actually do here is an es6 destructuring technique where we can break open our uh object we can get the prams out and then we can break open that and we can get the city the lat and the long okay and then welcome to the weather page and then what I can do here is I can simply just pop out City I can say l long and just to Showcase to you that it actually shows that then we can see here welcome to bonage with the Lattin long right so perfect stuff okay so at this point now what we want to do is we are going to actually get the backend set up all right so we have our city we have our latitude and our longitude okay so what we're now going to do is we're going to use the free weather API provided by open matal but we're actually going to do it in a way where we basically are going to set this up on a backend supported by stepen now stepen is going to do a really cool job here because what we're going to do is we're going to use the free weather API to basically Define our optimal Cur request so for example I've clicked in a cur request here so you can actually go onto the website open.com and then you can click on this right here to sort of demo it out now you don't need a key which is awesome it's a completely open API and as you can see we have a ton of information that comes back now remember what I said we have loads of information so you know that summary that I showed you earlier so remember the summary that I showed you from chat GPT so in uh precisely this one you will not believe it but really I'm not joking when I say this all I did was pass in this information I cleaned it up I passed it in and then it defined this so from that information gp4 is going to give us all of that nice beautiful summary just like this so that is absolutely incredible right so what we're going to do is we're going to take this Co request and we're basically going to just go ahead and give the hard work to um Step Zen step Zen is going to do all of the hard work for us okay step Zen will then open up this page right here right so you'll see start for free create an account now I've already created an account so I'm just going to Simply go to my dashboard so I can head over to my dashboard once you've created your account and you're inside your dashboard you can simply go ahead and you'll see you've got a bunch of different endpoints and you have your nice sidebar now this is really cool you can go ahead and explore this for yourself but you can see we they give you tons of different endpoints it's really really awesome to go ahead and use okay now what I'm going to do is I'm going to go ahead and uh set steps then up inside of our project so I'll show you how to get started so we have an a documents over here and then what we can do is you can simply use this to read and check out I'm going to click install and setup install step Z so in this case I've already installed it globally but you want to run this Command right so step Zen now what we want to do is head over to our code and I want you to do the following I want you to go into package Json level so at this level I want you to create a folder called stepen and then inside of your terminal I need you to do the following I need you to go ahead and simply open up a second terminal and CD into that so CD into steps then now be very careful because now we're inside of this directory okay and there's a reason why we do this because when we're initializing it we want to se essentially create two separate areas right so one for the steps end backend and then we've got an xjs app right I didn't say front end back end cuz some people might get confused but the back end is essentially our stepen folder then what you want to do is Step Zen login now before I do that I'll show you how easy it is because what they've done here for you is you can simply go ahead and follow the documentation so once you're on steps end's website head over to the steps end docs at this link right here at the top then I want you to go ahead and click install and set up and read down here now the reason why I say this is because they give you the commands and they even give you your keys and everything to get logged in so you want to go ahead type in steps and login into your uh into your um terminal I've already done this so I'm not going to repeat that then it will say what's your account name you simply pop in your values you simply pop in your admin keys and so forth and it will give you your key here as well and you can also get your key um from the steps and dashboard and then yeah you can log to your account okay now once that is done we're going to go ahead and do quick start with steps steps and import CLI so I've already logged in so now what we can do is you see where it says steps and import K and so forth steps and import my SQL we're actually going to do a k authentication request okay so I'm going to show you how we're going to do this so I've actually got an ideal perfect uh string here and I'll show you how I've defined it so um what I want to do is head over to the free weather API we're going to click on features we're going to click on API and documentation and as you can see here you can actually select all all the things that you want additional variables like the UV index and so forth the weather code and even things like daily information so current weather with SE temperature settings wind speed and so forth with the time zone all that good stuff and then it will give you a pre-built URL okay so in this case if I as to select a city for example London okay and then click it it a time zone is required you have to give it a time zone so I believe we could do something like Europe London and then you can do uh again let's just do London like here and now what you'll find is if you go down here ignore this craziness it will give you a perfectly formatted API URL now if I was to call this URL for example if I click it here what you'll find is it gives me all the weather information I've requested okay so I've saved you a little bit of hassle here because what I've done is I've actually created a URL that you can use for yourself now I'm going to go ahead and keep this very simple I'm going to put this on the screen I've also gone ahead and actually included it in the papa GitHub repo inside of a test. text file okay so if you don't want to do the longness of this I'm just going to Showcase it on the screen right now by saying test.txt I'm going to paste it in like so so this is the text this is essentially the C request that I'm going to run okay so all you can do is two options at this point you can stop the video um and you can go ahead and copy this or you can simply get the papa GitHub repo and do that and basic Al find it in the test cod. TS txt file that I've submitted onto the G repo right so this right here or you could build it yourself based on these parameters right so we're going to copy this C request if you click it you can see it gives me a bunch of information and this is a great way to start things off okay so next up what I want to do is I want to go over to my terminal so we're going to go simply back save that file going to close it and now I'm going to do steps Z and it right so this is the first step we're going to do step Zen in it this will initialize a stepen directory inside of here what would you like your endpoint to be called melting camel is completely fine and then you can see it's created a steps then uh config.js for us right so very simple to be honest you can actually just skip that step and do the next bit so here we can say steps in import curl and then what I want you to do guys is literally paste in your C request now what's amazing about steps Z is that from this information a few things are going to happen right so I just want to showcase to you if you are stuck and you have no idea where to go you can actually get all of this information I'm talking about right now over here so even if you have authentication headers you can bypass them by passing in your authentication with the D- header argument okay now you can go ahead and import and what's really amazing about this guys what it will do once I hit enter is it would basically read the response create a perfect schema which will repres present that information and then it will create a graph ql API that will literally allow me to select and deselect the information that I want from this request now that is damn powerful so we're going to go ahead and do that right now I'm going to hit enter bam and what we'll see is it will go ahead and it will import a schema into step Zen so let's go ahead and go to our step Zen and as you can see I've got the K I've got index. graphql okay now as you can see look at this guys absolutely phenomenal it's found and it's determined all of the different data types now don't get confused this is graph QR not typescript but you can use this to then go ahead and create type definitions yes but this has literally gone ahead and done all of the hard work for us so you see that entire crazy object that I just showed you previously so this one right here it's gone ahead and created type definitions from all of that right so no joke current weather current weather is day you can see everything is literally been converted over to to a type definition or schema and then it's given us a query to go ahead and Showcase from right so and you can see the end point is here and then you can pass in the following parameters right so this is absolutely amazing right so we're going to go ahead and type in steps and start and what this will do is it will deploy our Ur our step Zen um API as well as set up a local host um instance for us so this will get set up at Local Host 50001 melting cam for us for you it'll be a little bit different but now if I go to the Explorer you can see I've got my query and I can go ahead and simply select the pieces of information that I want but you would have to go ahead and pop in the current weather daily hourly longitude latitude and time zone and then you can basically go ahead and select what items you want back so I will show you how to do this but right now if I was to do this you'll see it needs these pieces of information to go ahead and do that but I've actually done that for us so I'll go ahead and show you how we can do that next all right all right so what we're going to do now is we're going to go over to our application we already have our stepen API and it's worth mentioning as well in the stepen um dashboard you will see your new endpoint being deployed okay so that new endpoint that we just went ahead and deployed was called something camel melting camel so you can actually go ahead and play with it and interact with it here as well so it's something which I really like about steps in because imagine you're away from your computer you still need access to your API you still need to know what the hell is going on or you want to play with something just see if you can fetch some data you want to prey your queries all that good stuff you can actually access it completely from the steps and dashboard and you see how easy that was to implement okay so it's really really awesome in my eyes okay so at this point now I want you to do the following so we are going to create our type definitions from this because we're actually going to use this in the front end as well right so what I've done here is I like to grab this pull it to the right okay and then command B and then what I want you to do is close everything and at the top level at the package Json level I want you to create a new file I'm going to call this the typings dod. TS so these are all of your type definition files and the reason why I've got a left and right like this now is because I'm basically going to go ahead and map things over right so you can see right here we've got the temperature wind speed and so forth for this one I'm going to go ahead and create an interface to map that right so you can see there we've basically essentially mapped it over for the daily units I'm going to do the same thing okay okay so for daily units I'm going to do the same thing I'm going I've essentially mapped it over so you can see where we had typically a float before now I've got a string value okay now um you can go ahead and really play around with this as much as you want I believe that this is could be an array actually but in this case for now it's completely no sorry this is a string this is a string yeah this is the daily units so this is actually this value right here so I've actually gone ahead and skipped one so in this case the daily would be the following so for the daily units we're actually going to have so this is going to be the daily representation then we go down we've got our daily units and you see typescript is slightly different definitions but it's it's not too hard to follow out and you guys can feel free to type these out yourself or again the access is in the GitHub repo now for the hourly we've got this so this is essentially the one to one representation of hourly then we've got hourly units and we've got the root which essentially connects all these together so we've got hourly units let's go ahead and Pop That in as well and then we've got the root so let's go ahead and pull that in as well okay nice right so that's the roote yeah and you can see the route is actually connecting to our other interfaces at the top so that's essentially gone ahead and created one to one type definition mappings now why is that important because now when we pull the information in on the front end using the Apollo client which we'll do in just a second we're actually going to have an easy time of basically going ahead and safely accessing that information with our typescript definitions otherwise imagine trying to access all of that it will be like was it dot current weather and all this kind of stuff it gets pretty nasty whereas when we got our type definitions down it's actually pretty easy to go ahead and use to the point where I was able to do it without constantly looking back right so it's actually very very powerful doing that so we can now close our graph ql and now we need to set up our consumer so what we've essentially got our back end up and running now what we need to do is essentially create a Apollo client on the so Apollo client this is what we're going to be using inside of our app so I want you to go over to Apollo and you can feel free to read it out yourself you want to click on get started and you can install the dependencies inside of your project so we're going to go ahead and install the Apollo client inside of our app so command J and I want you to go into you see right now we have the first running on xjs app the second running on steps Z at the the steps and route we're going to create another one and you can you have to make sure you're in the correct directory so this is is in the correct directory do LS just to make sure so you want to be at the top level then we want to do mpm install Apollo client okay I just want to actually check that so we have the current weather yes you're correct I don't know why that came out actually so typings typing. DTS and actually current weather was is day so actually okay good shot Let's do let's go ahead and grab this what we can do here is the temperature integer so this one yes you're correct actually that actually has a number in it good spot weather code yes that's that's a very good spot so to make it OCD perfect there you go good stuff right so I missed a little type definition there right so this point we installed the Apollo client and now what I want to do is I want to go ahead and create so close everything up go to the top package at Jason and I'm going to create a new file called Apollo client Apollo client allows us to essentially create a connection to our uh backend right so the the the back end that we just uploaded with graphql so here I want to go ahead and do two things I want to import the things I need so very straightforward I'm then going to go ahead and um create a type definition for the client so the client is going to be an Apollo client or it could be a no value and at the beginning we're just going to initialize it with nothing and this is for a server pattern so don't worry I'll explain that afterwards but we're going to say export const get client and this is a Singleton patter because basically we're going to use this to go ahead and get an instant of the client when we're using our app so whenever I want to go ahead and interface with the graph K API we can go ahead and do it that way so I'm going to say con client equals and you could have done that if client check if you really wanted to we say new Apollo client and then I need to go ahead and pass in a URI so in this case it's giv me a URI that's not correct what we want to do here is basically you can set up your environment variables but I will keep it very straightforward and easy for you for now so for now we're just going to set it up for this one but you can do a a check to make sure that if you're in development you'll have this one otherwise you'll have your production one but for now I'm simply going to go ahead and put this in in fact no I'm not I'm going to do it properly I'm going to go into my folders I'm going to do M local to set up an environment file and here I'm going to say API URL and I'm going to pop that in there okay now that means that we've got our URL defined in this variable heading back over here we're going to say process mv. API URL and that way when we deploy it we will actually have things correctly set up which is much better uh doing it right then we say cach new in memory cache and then we say headers this be I want you to pay extra extra extra careful attention to um we're going to go ahead and pop in an authorization key okay so I'm going to pop in an authorization key like so okay and then just just like so and uh where have I messed something up so there we go yeah now as you can see we need to create a next public steps and API key right now I'm not actually sure if this needs to be next uh public but we'll check it out so next public uh steps and API key so where do I get my key from I will show you so let's go over to my stepen dashboard so we're going to go over to the steps and dashboard and then what I want to do is I'm going to hide my screen for a second after I click this but you want to click on the account tab so I'm clicking on the account Tab and then what I have here is an API key so on the account tab you'll see the following okay so I'm going to Showcase some of it but you'll see an account you'll see admin key and you'll see API key so I want you to copy this value okay copy this value and then paste it inside of the value here so copy it and paste it inside this value okay okay let's go ahead and do that right now so I've gone ahead I've copied it and I've pasted it into that value okay then what I've done is I've closed my environment file right so now I've saved it and we have access to it there okay and then I'm just simply going to go away from that page that way I I don't leak my plan by accident Okay cool so at this point I have my step Zen key all set up as well so this means every time we send a request it's going to go ahead and include the authorization headers inside and it's got to be appended by a API key to begin with right or prepended all right so once that's done we're going to return the client cool yeah and then this uh function right here we can export it that's perfect okay so at this point now we're not actually using this client so we can get rid of that my bad right so we can actually go ahead and get rid of that it's easy okay and if you do want to do it you can actually say client and then say if client and just directly assign the client like this you could do this and then say if there is no client and so forth I'm just going to keep it relatively simple now and create a new one each time but yes for optimization purposes you could do that okay so let's go ahead and get rid of this for now cool all right so now what do we need to do well now what we want to do is essentially create a query from our front end to the back end okay so we're going to call this one the fetch weather query okay so how do I do this well I'm going to create a folder called graph ql and then inside of my folder I'm going to have queries okay so queries now here I'm going to have a folder called a file called Fetch weather oops feather fetch weather queries TSX okay TS sorry this is not RFC there we go yeah cool now at this point we're going to have um basically our query that we're going to make to graph QR now how can I make this easier for you so what I want you to do is remember we had this link to click into steps Zen I want you to click it okay now if you go over to the export button you can see we actually have a really nice kind of setup here so what you could do is you could go through click every single one and then you'll get a nice kind of query over here now that's what exactly what I did I went ahead and clicked through each single one so you can actually go ahead and do this and you see how it's building this out right so you can feel free to do that in the same way um and then it will go ahead and build out the perfect query to get you everything obviously you don't have to do this if you don't want to over fetch um but in this case I just want to showcase something to you right so once you've done all of that get all of this information included all right so you can go ahead and select them all I'm not sure if there's a quicker way of doing that if you can select them all can you do no no you can't okay that's fine we're going to do the same thing you can use chat GPT 3.5 don't worry if you haven't got access to GPT 4 yet I see a question already in the chat don't worry about it you can do that I'm just going to click all of these just to make your life a bit easier easier Okay cool so at this point you can see we've got our conditions there and then we've got everything else here so I want you to just copy this right so copy that entire thing in fact copy up until it says const get query right so copy that entire thing right so I've actually already done this and what I will do is I will showcase it to you with a few minor differences yeah so I'm going to go ahead and um pull that in at the top right now so just like so so where's my code here we are going to hide everything and then paste it in so at this point you've got gql so I need you to install a few dependencies at the top and I'll show you what I modified here okay so we I've changed the name here to fetch weather query and then you can see where we have gql right and if this isn't being highlighted for you you just need the graph ql extension very simple just install it but you've got the query so everything else was pretty straightforward everything else was the exact same as yours the only different thing now would be the parameters that you pass in here okay so current weather we're just going to say string and then we're going to give the following values here so latitude longitude and time zone we simply say string with a uh exclamation mark now for the daily and hourly you can feel free to get this code from the pap G Reaper or just pause the video and copy it yourself but these are all the different values I I'm attempting to get get from the daily readings from the hourly readings and you can feel free to use that as you wish okay so we're going to go ahead and Export this now so we're going to go all the way down we're going to say export default fetch weather query okay so just like that I have a query now okay so let's test this out how can I actually go ahead and make a call to my query and you're probably wondering this is where it gets really hard no how is he going to do that well it's actually this is where it gets pretty easy right so in fact we've actually done all the hard work because step Zen made it so easy for us that now we actually don't need to do much work right and I'll show you exactly what I mean so what we can do is the first step now what I love about next J 13 is that we have server components by default this means at the functional component highest level you can do async away that's Game Changer that is absolutely Game Changer stuff so this makes things like you know fetching from our next year graph C back using steps and super easy right you can do fetches all of that stuff at the highest level so let's go ahead and pull in the information so first things first I need to actually go ahead and pull in the get client right so by default this hasn't this does not say use client which means this is a serice side render component because that's the default Behavior then what I want you to do is I want to say const client equals get client okay and simple as that and then what we need to do is we are going to go ahead and say const and we're going to say data we're going to extract the data like destructure it like so and we're going to go ahead and say await now you can see we don't have an asynchronous so we need to make this asynchronous we're going to say await client. query okay and then we've got an object that we passed in here now the first thing we're going to do is say query and we're going to say fetch weather query so remember that query that we went ahead and created earlier this one right here we're actually pulling that through here okay then we need to pass in the variables right so the variables in question here are actually like so we're going to say the current weather right so what I'm going to do just to make this extremely clear is I'm going to pop this on the side so you can actually see what I'm doing right so remember these these different values so the current weather so the current weather is actually going to be true okay so what I'm doing here is that this is essentially mapping here so what I'll do is I'll write it out and then I'll draw this out right so we're going to do current weather and then we're going to say longitude so in this case it will be a longitude equals long and then we'll say latitude equals lat and we'll say time zone in this case I'm just going to hardcode it to GMT okay but really what's Happening Here is we've got a nice little connection going on because we've got the current weather being mapped over here we're passing it through the longitude is being passed here the latitude is being passed here um we've got the time zone being passed here and then the daily and the hourly have got default values based on these right because I only I always want these to be set values so you see how we're doing this right so that when that way we're going ahead and we're passing it through now what I want you to do to test that this is working I want you to firstly go ahead and say const results and we're going to map this to root remember that that interface we created earlier on so if we click into it remember the current weather all that kind of stuff the type definitions we're going to map it to room and then we're going to say equals data do my query now you're probably wondering why is it on my query because remember when we actually had our query inside of um Step Z in our uh schema the data is returned under my query so inside of the response it'll be under my query okay and then what I want you to do is console log those results and what we should see is a beautiful thing so now if I go over to my website so it's go over to create uh uh weather app and we're going to Simply go ahead and remember this is being rendered on the server so you won't be able to inspect it because it's serers side rendered so now what we do is we pull open our terminal we go to our nextjs app we uh clear it all and then we refresh and just like that guys look at that we have all the information coming through so here we have the longitude and latitude of this address so 19.8 125 so uh in this case 19.8 I think that's fine here so 40.8 125 so it's done the closest they can to it which is perfect Time Zone GMT perfect okay that's absolutely amazing and then we've got the temperature the weather code the wind speed the Direction all that good stuff that's what I want to see right and then we got the hourly temperatures and everything so this is perfect right amazing amazing stuff so now what we can do is we can actually go ahead and um start passing that information and then eventually what we'll do is we'll clean up some of that data pass it to GPT 4 gp4 will create a summary of that data by using the chat completion API and then it will pass it back to us so I guess the next step that naturally to do is build the beautiful UI that you see right here using the data that we have got back so let's do exactly that okay so command J to HDE this let's carry on guys so we have the div now what we're going to do is this left T section we're going to call it the information panel right so this is going to be a information panel so what I'm going to do here is I'm just going to say information panel and I'm just going to assume that this is a component that we're going to build so I'm going to kind of comment out just to draft things up we already know that we get the weather page here so I'm going to go ahead and move that out the way and then what I will do is I will start building things out as I wish right so what I'm going to do is probably leave out this left hand side and showcase this first and then we can build out the left left hand side and introduce our functionality as required so first things first open up a div another div inside and here we're going to have a H2 so actually here I'm going to have another div I'm going have a H2 saying today's today's overview okay and then we're going to have a P tag and you can feel free to customize this with you know trema components if you really wanted to and so forth we say last updated at and then remember we actually have access to that data now which is returned so I can actually go ahead and do really cool things here so at this point we've got the um last updated out and then I'm going to say we're going to pass the date that came back so we say new date and I'm going to say results Dot and this is what I love about typescript right so if we say current weather dot time thank you Jay that time we'll say to local string okay and then here I'm going to have in Brackets we say again results do time zone okay and now what you can see is it says last updated at so the data that we fetched was last updated at this time zone right so it was last update 1970 is not correct which means that we have made a mistake that means that no date was provided back for this um for this uh location so that's actually the beginning of the Unix time St so current weather was not successfully returned then which is fine we can probably change that afterwards so we'll have a look at that afterwards and modify that but for now I will leave it there and we'll fix it afterwards okay so um that's fine for now and then I'm going to start styling out so this P tab this div is going to have a padding bottom of five this div is going to have a padding of five and then the H2 is going to have a text extra large font Bo okay the P tag is going to have a text small text Gray of 400 boom and we should start seeing things change up there we go that looks a lot better already cool and then what I like to do is I click on this one to know where I'm at okay and where we had the padding uh five this one I want you to click in we want to stay in that level okay so here I'm going to say a div and here I'm going to have something called a call out card okay okay now the call out card here is going to be the GPT summary so this is going to be referred to as a callout card this is also going to be a callout card okay now because um the truma 2.0 has not yet introduced uh direct support for next year 13 we have to go ahead and create a wrapper component for it so which is not which is completely fine so inside of components I'm going to create something called a callout card component. TSX RFC to create our callout card component and then we can go ahead and do the following now this call out card will accept two props it's going to have a message prop so we're destructuring and a warning prop we need to Define these type definitions like so so I'm going to go ahead and say type props equals and we're going to have our message and then we're going to have a warning which is a Boolean now the warning is optional it doesn't have to be included okay but what we need to do is as I mentioned this is a wrapper so it allows us to have the used client directive okay so that's basically going to allow it basically say that you have to essentially render on the client the browser okay then what I'm going to do is I'm going to pull in two different icons right now what I'm going to do here is instead of pulling out this I'm going to instead render a call out card so I'm going to render a call out card so this one's just going to be called call out which is a self closing component and then the title here is going to be the message that we pass in the title um the icon is basically going to say if it's a warning it'll have the exclamation icon otherwise it will be a check Circle icon and then the color very similar approach we're going to have again if it's warning it's going to be a rose color and if it's a success it's going to be a taal color right and then a little bit of styling to kind of make it finishing touches look good class name margin top of four cool so we've got our call out card ready and it's reusable as a component so let's go ahead and do the first instance of it so here we're going to have our call out card so let's go ahead and pop pop this in like so we're going to say call out card and then I will pop this in and I'll say message right so here now we've got message you see my nice little popup so we got message and here I'll just say this is where GPT for summary will go Y and as you can see wait for it we should get a lovely look at that amazing right and what's really nice about this if I simply pass in a warning right right now you'll see this will become a nice red message as well so we're going to use that later on for such things like the UV is too high and so forth okay after this div we're going to move down we're going to have another div now for all of these individual cards we're going to create a component called stat card okay and then we're going to reuse that component and that's going to have a title metric and a color prop associated with it okay so let's go ahead and do that right now so command B we're simply going to go into the com components and we're going to say stat card. TSX RFC inside of here so here we're going to go ahead and say the following so I need to go ahead and import the card so firstly we're going to say use client and then we're going to go ahead and import the following and then we've got our props so we're going to say type props and let's define what the props are please can you do a build with material UI I will definitely consider it we've got a tile prop a metric prop okay and then we've got a color now the color is optional but the color it has to be basically defined by one of these colors so there's a reason why I had to do it this way I'll show you so we've got Indigo slate gray zinc neutral Stone red orange Amber and so forth and I'll show you why I've decided to go go down this route right really they should have had a color option inside the Tremor but these are all the colors that they support right so in this case I've just defined the here and then we're going to destructure it we're going to say title metric color from the props and then here we're going to say it's a card with have text inside of it where by that is the title I'll drop the volume down just a notch and then we've got the metric component which is our metric element right here just like so now that looks pretty good so far so the color now I'll show you what happens here so if you do decoration color what you'll find is if you hover over it you'll see or if you click into it rather you'll see color right now I can't actually pull this color value um but what you'll find is the color values is a read only store uh of these values so what we done is we created a type definition from that color right so this color I couldn't pull it in right but in this case I mean maybe we could let's actually give it a try I can that's such a silly mistake color oh my God God can we do it no way okay let me see color is okay oh my God okay you can do it so don't ever underestimate yourself right don't do what I did that was a silly mistake you can I thought so I was like all right so color yeah nice in this case we say color that's good and this is going to be um expression yeah there we are nice right so we got the decoration color then we're going to have the decoration on the top and the decoration all it is is that line right so you want to have a different color line for each one it's quite a nice little Finishing Touch right so let's head over here now back and what we can do is we can use our reusable component to actually Define those stack cards I will show you just how easy this is now there's a there's a point that I want to prove here right when I talk about reusable components it's for a purpose right because it's so easy to then build amazing UI wir is like this if you do it once correctly so now we built a stat card so I'm going to show you how we can basically reuse it in different use cases so in this case we've got the stat card so let's go ahead and use it right here so stat card going to import it from the top so stat card and then we've got some components we have to pull in so in this case the title here will be I'm going to say maximum temperature tempure yeah and then we've got the metric itself now the metric itself here I'm actually going to go ahead and copy the values we're going to do a little bit of string interpolation with a little Celsius kind of degree sign so here we've got two fixed and you can see we got this little Celsius kind of degree and then we've got color equals and if I do this you see we get all the colors nice all right so color now if we do this and refresh we should see look at that oh my God like look how nice that is simple clean effective right and you see where I'm pulling it from the daily results now what I'm done done here is i' I passed it in from the daily results the zero Index this means today uh one would be tomorrow two would be in two days from now and so forth so you can feel free to use that information however you wish but this is how I've done it okay so now what I'm going to do is pop this in on I've got another one here for minimum temperature which is using 2 m Min and you can see look it's just so clean right so so clean the next one we're going to have is a UV index and I'll put this inside of a div for a specific reason now and I'll show you why so we got the index what I'm going to do is I'm actually going to basically pass a value and what that value is is the so forth so I'm going to go ahead convert a number to a n so I'm converting this value the UV index Max for today to a fixed value now what I've done is I've converted it to a number so I can do a numerical comparison here against five so if it's greater than five then I will show a call out card saying the UV is high today with a warning message okay so in this case UV is 7 so this should be high yeah perfect and if it was lower than five so for example if I made it 10 it had to be greater than 10 this you wouldn't see that perfect right so now you've got a nice little kind of thing that pops in so we've got a number here there we go we've got that uh stat sorry up there we go and then I've got two more for the wind direction and the wind speed right so div and we are be we are going to be using CSS grid here as well right so I'm going to do stat card uh and in fact I'm just going to pop this in make it a little bit easier got two elements here stat card for the wind speed and wind direction so wind speed and wind direction okay I've got milliseconds and um or me/ second and wind direction with the degrees of the the direction that you're doing with different colors okay so really nice right now for this one I'm going to say class and this is going to be a flex uh container so I want them to be squashed into a row with a space of three and you'll see these will pop next to each other again the whole point is do beautiful things perfectly fast then you can reuse the components makes the entire thing a lot easier right it looks very nice right this is very clean and then what I want to do is that uh div we can leave that parent div but this one at the top div right so the one that we first got the first div this is where I Define my CSS grid so first thing I want to do is grid right I want to make it a grid so if we do that by default nothing changed because it's by default of grid one right grid columns one so what I want to say is remember when you're doing any TN CSS stuff it's mobile first so by default on the on a mobile it's going to be a column of one then as we hit an extra large screen then I want to go ahead and say then you go to a grid column two okay and then the gap between everything should be a five margin of two right so in this case it will pull in a little bit more so you'll see it pulls in a little bit more cuz of a margin two and the Gap five between everything is nice now when I hit past a extra large screen we should see boom it pops over there now this you're probably wondering say that looks really stretched out why because think about it once we actually get that sidebar in it won't be so have so much room okay but that already is looking pretty beautiful right so on a mobile view on a bigger screen that's so clean right by using bit of CSS grid and a correct container management so I love it absolutely love it right so we're almost there guys we're getting to where we want to get to now for the callout card where the summary goes I actually want to style that container so I just want to add a little bit of styling in I just completely forgot margin and then around it of two and margin bottom of 10 to give it a little bit of spacing to move away right um right so in this case we've got this perfect stuff look at that that's already looking much more breathable okay good stuff now next up we have after all of these divs we actually need to make sure we do this correctly so the first div second div third thir div first div second div third div after this one we're going to have a horizontal row line you can actually change that for a divider if you wish but you're going to have to wrap it in a component if you're using Tremor uh with a use client directive so in that case I'm just doing a horizontal line so you see our little horizontal line there and then I'm going to have a div and this is where the charts are going to go right so the charts are going to be space y of three because I want space between them you can even add a divider as well but I'm going to have the charts here so I'm going to have a temperature chart temperature chart chart I'm going to have a rain chart and a humidity chart so temperature chart rain chart and a humidity chart cool so we got three different charts that are going to go there these are going to resemble these three individual charts okay so we're actually making significant progress here I love it right so that's looking pretty good now at this point I think what we could do is do the information panel right so let's do the information panel then we will do the charts then we will do the gp4 summary and so forth okay so the information panel so we're going to go to our components we're going to say information panel. TSX RFC boom going to go up here get rid of this and the information panel just for reference is this side part right and then on a mobile view this will become at the top right so we want to be basically a mobile view and then on the side it's going to be our sidebar but we're going to call it the information panel because I'm weird like that all right um so we've got the information panel here and then what this will do is it will take a few props actually so I'm going to pass through the city the latitude the longitude and I want to pass in the results themselves right so the props are going to come through which means we're going to have to define the props like so um and then I'm going to go ahead and Define it here so I'm actually saved us a little bit of time I'm going to go ahead and pop in the props like so okay and then we're going to need a bunch of dependencies here so I'm actually going to save us a little bit of time here by going ahead and popping it in like so uh we haven't got that one yet that's fine so we're going to pull in the moon icon Sun icon image and city picker okay now starting things off with this div we're going to go ahead and get rid of that information we're going to have a div inside of here with a H1 and H1 is going to have a city right now I have made a little helper function which will help us out a little bear um actually not haven't no instead we're going to use a decode URI so in this case uh let's just pop in this we're going to say decode uh sorry decode U and we pass in the C and what this is is basically you know when sometimes you have escaped characters it essentially removes that escaped character from it so if it's like you know that that kind of weird symbol which represents a space sometimes it's like percentage 20 which resembles a space it basically gets rid of that so this case it will get rid of that so let's go ahead and just pop this in so we can actually see it on our page so we go back to our page and we go to no sorry our location page and we uncomment this out and we import this in now if I hit save this will probably error out because yeah we don't have it I mean right now it says undefined cuz I'm not passing in the city so we probably should pass in the values as we can so the city is equal to the city the results are going to pass in as the results the latitude we're passing in and the longitude is the long okay and now we should see the city bage yeah there we go so that's the city that we started the everything off with so I chose a random City in the beginning and that will do just fine we got the H1 here and we got the P tag um and then I'm going to say long L and then I will have the following I'll say a long L yeah now let's style this up let's go ahead and say that this one should be text extra small text should be gray 400 and then the H1 should be a uh text 6 XL I want to be much larger it's pretty dominant font should be bold for the surrounding div I want this to have a padding bottom of five and then the overall div I want this to have that blue gradient that we had previously in that initial screen text should be white and the padding should be 10 so I'm just going to pop that in save a little bit of time as you can see boom as as soon as we pop that in immediately looking a lot a lot cleaner we got thep the div there we go and now what I love about this is remember we actually went ahead and created um reusable components in the beginning from a uh which was a great use case for it because now we can go ahead and say City pickle right so in this case City picker we can pop in and just like this watch super easily right just like that we have our city picker and this is the power and beautiful thing about this right because now if I type in something like United Kingdom let's do London watch this guys it will go ahead and fetch the information from London and just like that we have it right so amazing stuff you see how numbers actually changed so if I did United Arab Emirates I did Dubai watch the temperature changes that's perfect that's amazing we have to figure out this date as well afterwards it's fine for now all right so Dubai perfect stuff okay so next up we need to go ahead and pop in a horizontal row I'm going say a margin on the y axis of 10 separator right good stuff and then I'm going to have a div with a div inside so we're going to have a div inside of here I'm going have a P tag or actually a div inside of there with a P tag inside of that and this will have the date right so I'm going to pass the date in the following format right so here I'm going to go ahead and take the current day I'm going to format it in GB and I'm going to say weekend should be a long type numeric long and day for the day numeric should be for the day so here we can see Friday 21st April right for example uh we can go ahead and do class name text should be extra large right outside of this p tag we're going to have a time zone message so here I'm going to have the time zone and I'm basically going to go ahead and resolve the time zone from our current time format right so this is our current time zone that we are in right so the current time zone that we are in is so the current time zone that I'm in is Asia Dubai right so that's how you basically go ahead and get your current time zone font extra light so that's a handy little uh built-in functionality in JavaScript if you you did not know okay now outside of this div in the total surrounding div we're going to have margin top of five we're going to have a flex items should be centrally aligned justify the space between everything space between all of those things as 10 and then margin bottom of five and this is basically going to represent afterwards this so you see like this kind of uh this Gap and so forth right so we have to put the the current time in now as well so I want to have where I have the time zone outside of that div this is where I will have a P tag and this one will have the current time and I want to have it in a 12-hour format not in a 24hour format so this is how you do 12h hour format you say hour 12 true after you uh pass in to local time string you specify which times on you kind of want I'm using GBP uh GB sorry and then you can do hour 12 true if you do hour 12 for post you will see a 24hour clock right so in this case you see 24 hours so it's completely up to you and how you want to do it but I know I actually have had that question a lot of the time how do you do that um so that's how you do it right class name here we're going to go ahead and say uh text XL font bod we have some crazy Focus right now uppercase right there you go and just like that we have a nice little bit of text look at that that's looking beautiful right now I do want to mention as well while we're here if you haven't already remember check out the University of code absolutely incredible resource um little cheeky plug here because trust me it's one of the best ways to practice your JavaScript knowledge everyday coding problems is the way that you can practice that right remember it's not going to just come to you in a day by watching a video so coding problems every single day you get the solution the following day and I promise you it's going to be something that you can really benefit from and it's only $4.99 a month like seriously crazy value we have to create coding problems every single day for you and we send them to your inbox like you're literally getting spoonfed how to how to develop as a developer so something I'd recommend you absolutely crush and Destroy right who's coding along with me right now let me know so in this case we've got the uh that's looking great now after this div we're going to go ahead and pop a horizontal row with a bit of styling we've got a div next with another div inside and then here we have an image now the image I've actually got a a clever kind of approach to this bit so we'll talk about the image in a second so this image is going to resemble this all right and what I've done here is I've created a little helper function which we'll sort out in a second but before we do the image we're going to have a div this div is going to have a P tag inside of it uh let's hit save and this P tag is going to have the current weather in fixed temperature right so and remember if you really get stuck feel free join zero to full stack hero that's the OG place to be right that's where we literally go ahead and just crush it as a team of developers right so here what I'm going to do is sorry I completely missed oh yeah so here I will now have here where we have clear sky and this image I have a helper function to help us achieve this so I need to actually create that helper function right so here I will say weather code so what am I talking about here well what we actually have is I need to go ahead and create a function called a weather code to string in the LI lib folder so what I want to do is I want to create a new folder called lib and this is like think of this like oops no okay I don't do it there go into package Json create a new folder called lib y there we go go into your lib folder and create a function called weather code to string. TS right now inside of this file what I've essentially done is I've created a very helpful helper function now I'm not going to go through every single detail here but I will explain essentially what I've done in a nutshell so here we have a simple mapping right so this is a simple mapping and all it does is it takes a key and it returns an icon and a label so if your key is zero it will return the icon Co 1D and it will return a clear sky label and what this is is basically certain weather API return like weather conditions right so some might return a weather code of 80 that typically has a label of rain showers and a specific icon associated with it so what I've done here is I've created a weather code to string so I'm going to scroll down and you can feel free to pause the video and copy this out all you have access to all of this inside of uh the puppet GitHub repo right so this is a helper function that we've created to go ahead and help benefit us so I'm going to go away from that now and I'm going to use our helper function okay so now what I'm going to going to do is I'm just going to Simply pop in the following so the image is actually going to get pulled from that but before we actually do anything like the image I'm just going to go ahead and use our helper function to get the label for the current weather code so we're going to replace this with the following so I'm going to import my helper function from the top like so and now you can see weather code to string we pass in the current weather code and then we get the label for it now if I go over here you can see 28° clear sky right so in this case the API is returning a weather code we're then using our helper function to determine what the label is for it right now the image I've done the same thing but except I'm pulling the image from weatherbit doio images right so in this case what I will do is I will replace this with an image tag and then here you can see what I've done is I've concatenated so I've actually got a URL here and then I've concatenated the icon code and then it'll be PNG right and then the old tag is simply the label we've got width and height so I've got I've imported the image tag from from the next image now we will get an error because we need to go ahead and whitelist weatherbit doio from our list of images to allow optimization from so in order to do this we simply go into our next config we go out of the experimental tab we say images domains oops images domains and we simply pop in weather.io okay hit save close your ter your server run your server once again because you've made a change to your next config and then do the following yes if you're using hero icons V2 then you would need to import the icons from hero icons react 24 solid yes I agree with you that is correct yeah completely up to you on how you want to do that so at this point now what we can do is we can go back to our code and we can refresh okay so let's refresh this sitting we on my ears today so as you can see now we should see hey there we are perfect stuff right now if I go to London for example United Kingdom City and let's just wait for it type in London boom now you can see rain showers with a rain shower icon that's awesome nice so we've got our nice little our icon set perfectly working so we go to our div let's start styling out say Flex items Center justify between and now we should have things pushed across in the div here we've got in this div we're going to say Flex items Center justify between Space X of 10 there we are and then we have our um let's just have a look yes so that's perfect that's what we wanted and then we want to change our P tag here to be much larger so we're going to say text 6 XL font should be semibold the P tag here should be text right font should be ultra light or extra light sorry and it should be text should be large and just like that we should have a massive difference here with this there we go that's looking immediately better right so justify between justify between item Center awesome stuff okay and with that said now that is looking a lot cleaner so I just want to check something here yeah so you can see that's perfect that's what we wanted yeah and now after this div we want to do the following so after that div we can exit the div down so we can go from this div down outside of here and then we can start building out the rest of it so we've got a div here and then we are now building right so after that we can have this area so the sunrise and sunet right so here we've got essentially two copy and pasted kind of setups right so I'm going to go ahead and make this a little bit easier for you to follow by simply popping in a snippet and then we're going to show you how I break it down so you see this snippet right here so I'm just pasting it in right so you can feel free to revise this snippet and see for yourself what we've just added in but essentially what we did here was we added a div Sun icon in a bunch of styling in just for the colors and then we've got a div with a flex inside of it we've got the children one of them just Sunrise we've got a P tag to represent the uh time and you can see justify between has pushed these across from each other and then you got the sun icon around it so the sun icon is next to it then you've got the P tag and then youve got the the div sorry will justify between and it's Flex one so it takes up the majority of the room okay we've got the exact same approach for the other Moon icon except that it won't be sunrise it will be sunet right so what I'm going to do is go outside of this div simply pop that in like so and now we have sun set as well nice now at the top level div I want to say space should be between each y child and we going to say padding on the y axis of five and what this do is it'll space these out and it'll give it a bit of padding around it there we go so just like that absolutely beautiful and we have our sidebar essentially complete we just now need to make it appear to the side of the screen when we have the setup correct which means that we have to go to the page. TSX so this is our page for the entire page so now heading back over to that page I want to go ahead and basically configure the surrounding div so this is where everything gets styled out so this div is where the magic happens we say by default on a mobile it should be Flex column so it should be in this view okay then what we want to say is firstly it should be a minigh of screen so that way it will always fill up the color of the screen but on a medium screen or above it will change into a flex row now let me show you what happens so as we hit a medium screen boom look at that very very nice now the only issue we have here is that this div does not use flex one so how do we conf fix this we simply go over to the div here which is using that remainder of that space we say Flex one padding of five and I'm going to say on a large screen padding of 10 now let's give it a try we go over here now you can see it's using up the full space and it's got the uh the uh appropriate padding so look at that absolutely beautiful that is absolutely lovely look really really nice right so look at that it's just so clean come on like so so clean United Arab REM let's go back to Dubai bam right we go to Abu Dhabi oh sorry now this Albania uh baj that initial one go to Armenia I'm just picking random cities here right so United Kingdom back to London cuz London's obviously got great weather right always raining right so at this point that's really good right so looking looking really good so let's get the correct time for sunset and sunrise oh yes you're right actually so it appears that the API is not actually returning the um the correct times for this yeah you're right so it's 4:00 a.m. um so where have I put the sunset sunrise so let's go to the information panel and right now at the bottom where is it Suns set Sunrise okay so it looks like my API Coe that I initially made was maybe a little bit wonky this is just saying 4: a.m. 4:00 a.m. oh that's because I mean so it's not actually pulling in the correct dates I believe all right we can debug that at the end for sure we can debug that at the end yeah so this is actually what is returning and as you can see the time zone the time was actually being returned here and then yeah we should have had it back and then if we go to Sunrise you can see Sunrise yeah so we are getting time back which is interesting we're not getting the the correct time though okay I mean we'll have a look at that we'll come back to it uh I will check to make sure that we actually conquer that bit because I do want to get that right in fact I just want to check the URL that we initially called so this was the URL that we initially called um so I have a feeling we're not passing in the correct details into our query so I just want to check something let's go to our fetch weather queries yeah so that's the exact same and then when I call it is the next question so when we have the page and then where is it it's here so uh in page let's have a look let's just double confirm this so the variables that we passed through is the same yeah uh okay so it's interesting um I'm not quite sure to be Hest I think to be honest what could have happened is it could have maybe let's go ahead and disable the cach and refresh okay interesting we'll have a look as to why that happened afterwards but right now my yeah my time isn't seem to be rendering correctly interesting all right um let's carry on we'll come back to it so I think the next natural step is the charts let's get the charts down and then we've got GP PT summary and then we are good for deployment which is amazing right so let's do first up is the temperature chart so for the temperature chart what we will do is create a component so temp chart. TSX and this essentially going to be once we do one of them honestly it's very easy to replicate right so RFC and this is going to be a temperature chart it's going to take uh let's go up get rid of this it's going to be a used client because we are using some stuff from Tremors we're going to import the things that we need we're going to have a type props and this will have the following inside of it it will have results which is of type rout okay temperature charts is going to be the results okay that's the prop that comes through and now we need to do the magic behind it so firstly let's just show what we're going to render so here it's going to be does it matter if it's TSX yes cuz TSX is essentially saying you're returning jsx as well right so it's TSX right so in this case we've got the card and that's we okay the cards and then here I want to have the title this title will say temperature and UV index because it's going to contain both the temperature and UV index now feel free at this point as well to also pause and go over to tr. aisle to look at the line graph documentation they actually break down really easily really nicely and then you can come back here to kind of you know inspect how I've done it but here I'm going to use something called an area chart and then we've got to do a bunch of things right so we have to give it a bunch of information so we have to firstly provide the data now the data here we have to map it into its correct format and we also have to do the same thing with the hourly information now the hourly information that comes back from the API if we go up to hourly what you'll find is that this has information for every single Hour 1 2 3 4 5 6 7 89 9 10 11 12 all the way up for like you know a very long time we only need the first 24 to get the day right so what we will do here is we will say we basically we're going to only get the first 24 right and we're going to change each of them to a 24hour uh um um time instead so we're going to say const so this is called Data transformation right we going say con hourly equals results do hourly so results could be you know we have to protect ourselves. time do map right and for each bit of time what I'm doing is I'm returning so I'm directly returning a new date whereby we pass through the time and I'm say to loal string oops two local string yep and then I'll say us and then I'm passing in the hour is numeric and the hour 12 is going to be for false because I want to be in a 24hour sense and then what we're doing is we're mapping through at that point and then we're going to slice now what the good thing about this is I want the first up until the 244th value so this will give me every all the only the first 24 hours right from this so I'm basically correcting this down now and this will basically become 00 0 0 1 02 03 04 all the way up until 24 okay so that that's actually a really nice little trick you don't know you you may not know yeah so in this case the next one is we need to prepare the data so the data has to be in a specific format so I'm going to map through those hourly things that we just went ahead and uh provided then I'm going to go ahead and say each hour and we also have the index and I'm going to return a object so I'm doing parentheses with a curly brackets inside first key is going to be the time and this is going to be the number for hour so I'm passing the hour as a number okay second is going to be the different things we want to have on our graph so you know our y our x-axis so in this case we're going to map against the UV index well actually this is going to be the time will be the x-axis the y axis is going to be the UV index and the temperature so in this case it's going to be UV index and this is going to have yep so it's going to be UV index and it's going to have the results the hourly UV index and it's going to be I yep and then we're going to have the temperature as well now the temperature I'm going to say temperature and I want to have C for Celsius okay and this is going to be just like so hourly temperature 2 minutes and then it's I so now what we're doing is we're mapping through and we're putting the data in the perfect way in which area chart expects it okay so this's start styling it out so class name is going to be margin top of six and then this pass through the data so the data is coming through like so we're going to say that we should show The Legend we want the index so what is the x-axis essentially well this is going to be the time right so this is going to correlate to that so the time then we have the categories now now this is going to have to exactly match the key values here so temperature and UV index then we've got the colors now each one that we passing inside this array will correspond to so yellow will be for temperature Rose will be for UV index then we have the minimum value the minimum value here we want to set to a manual value of zero and then we've got the value formatter so in this case you can format each of the values now I've essentially just made it very simple so every time you look at a value on that graph it's going to format with a value of Celsius right so yes I know it doesn't it's not going to be UV it's going to be Celsius but for this one instance I'm letting it go right just for demo purpose right so it's completely fine but I'll show you it'll make a lot of sense what happens and then the yxs withth is like essentially padding on the yxes for the legend right so we have our temperature chart so now if I go to my page and I simply replace this with the temperature chart like so and then we pass through the results right so the results will be the results here I go to my local host I hit save and I refresh and hopefully we'll see how this goes so now you can see oh look at that guys so in bonage right now it's pretty wild actually oh my God so this is 444 okay so the time is not being passed correctly so we've got the same issue that we had previously so I need to inspect and debug so right now the data coming back is not returning this result that I expected to right so what we need to do here is actually I need to actually go ahead and inspect my results so I want to inspect firstly the daily units so let's just go ahead and console log just a daily refresh and I want to have a look what's happening here so if we go all the way up here you see it's quite quite intense actually how much we get so let's look at temperature um let's look at the so what is our x-axis firstly let's have a look so let's go to our temperature chart so temperature chart and then we mapped hourly do time okay so hourly do time is what I have to inspect so let's have a look at that hourly so we're debugging right now so hourly do time and let's have a look at what values are coming back right so I'm going to go ahead and refresh and you can see null so we're not actually getting any time back so this is a bit of a problem that we have to fix right so why are we not getting our time values back is the question that is the golden key um so right now I believe it's because we're not doing the execution of that query correctly so let's have a quick check at our code and let's have a look what's happening so it's because we did not we did not do our setup correctly I believe with our query so let's go back to our this is good yes then we go to our Apollo client that's fine no sorry steps z uh c Index here we are all right so we got the forecast we've got our current weather our daily our hourly our latitude longitude and time zones right and then we've got everything here now I think what I've done is I've made a mistake with the way I'm reading the information so I have a feeling my type definitions might be wrong so we have time is date time um and I just need to double check that everything is correct as in what I saw before so hourly do time so hourly so like hourly and then we go to hourly time is date time so I'm just checking on my other machine so hourly date time string so I believe the issue here is actually that the time is being passed as date time here when in fact it should actually be a string value so this is going to cause an issue so we're going to change this to a string value and then what I also want to check is um that we have that correct in other areas so we're going to change that to a string value and then where we have time here that's great sunrise and sunset should have also been string values so this this and this should also be string values right so not date time but string values I believe that's what's happened here so let's now do the call again so refresh and let's it would have cached the page so you would have to refresh with disabled cach on the network Tab and boom look at that guys that's what debugging is about oh yeah got the time out so we got the correct time now which is banging it's just the hourly markers so my slice function is clearly not working here this is doing the entire day this is like days and days and days of data which is not right okay so we have to now get this correct so basically go through your schema and make sure that it's not date time it's stram so it can remember it's trying to interpret itself so very easy fix that but we found it so now what I want you to do is go over to your um this is now we need to go over to our temperature chart and we need to basically find where I'm slicing because this is where I'm basically screwing everything up so where I messed it up was here so let's cut out the slice let's do this so for now if I map through where's my ending map so my map finishes here what I was making the mistake of is I was slicing here which is not correct afterwards we want to slice here 0 to 24 that's correct now what you'll find is if I hit a refresh boom that's what I'm talking about guys now I'm slicing the correct values so look at that so now we're getting 24 up until 23 that's perfect so this is kind of midnight 1 2 3 4 5 up until 11:00 at that night that's amazing that's exactly what I wanted I'm very happy with that right now at this point you could also you could obviously slice if you didn't want this you could do like one up until 25 or whatever you want to do it's completely your call okay okay but this is H this is good this is very good right we're making good progress here so now we have our temperature graph nailed in and you can see here look that date format is putting a Celsius on the UV index if you really want to make this perfect honestly what you do is you go to your date format and you just return the number right because you already got the Celsius in the in the the other bit but if you wanted it to say Celsius and by the way what you'll find here is when you re you have to refresh sometimes for the responsiveness to kick in right because you are rendering a graph so you may get little issues like that but it's completely good right and even if you go here sometimes you see like it doesn't refresh but if you refresh when it rebuilds it will get it perfect okay so don't stress it is responsive right so in this case UV index perfect okay now let's do the other graphs so we've got this graph down and I want to do the exact same thing but for another graph so I want to copy My Graph and I'm simply going to go ahead and change my temp chart to oh this reminds me of the twitch days so we're going to change this one to rain chot now rain chart. TSX and what I'm going to do is I'm inside a rain chart now I'm going to go through and just refractor some things so I'm going to say chart this is going to be called um my rain chart okay uh the exact same things are going to apply we are going to have the same slicing happening for the hours except here we're only going to have one uh in uh indicator here and we're going to have a rain percentage rain percentage and what we're doing is we're saying hourly precipitation probability right go back down here and we say chances of rain chances of rain okay and then for the area chart here we've got the exact same situation except for here what we're going to do is we only got one index we don't need this one we can keep it as an AR doesn't really make too much of a difference and this one has to exactly match up with this so we pop that in there get rid of the second one and data format we can actually go ahead and safely say it's percentage now for the percentages your max value is going to be 100 your Min will always be this that is how we always work in percentage world so rain chart there we go now what we can do is we simply import it into our page so go back to our page head down to where our other one was and we say rain chart like so passing the result like so and just like that we now have it I'm just going to make my camera a little bit BR there we go and just like that we have chances of reain zero so let's look somewhere where it's likely to rain right so you can imagine where I'm thinking United Kingdom right so London always has rain right now today does yep I told you it always has rain right so in this case that 87% en chance of rain at four oh the timing is also messed up here oh God okay so I fixed it and then I broke it so where did I fix and what happened okay let's have a look so okay I've gone back to not fixing something so let's go back to our step Zen Co I had this all fixed no come on oh okay so the reason being sorry why you might see this so this is a very good learning point what happens is it's caching right so you actually did everything perfectly but you had a cash value in the Page hit the refresh button with this disabled cash and then you will get the fresh data so that is something you have to be very careful of okay so disable cash in the network tab when you're deving you want to make sure you actually update that because now you can see that it was fine but you sit there for ages trying to figure out what the hell is going on right someone says check for Serbia Belgrade Serbia Belgrade let's see oh there you go nice there you go I'm see I'm I'm with you dude um really good stuff right let me know Kakashi if that's correct but in this case now what we can do is a final one which is actually the um the the humidity chart right so we're going to do the same approach guys we're going to go ahead into our rain chart then we're going to go ahead and we're going to rename it to humidity chart right humidity chart. TSX right so humidity chart we're going to change rain chart to be humidity humidity okay and then we're now going to go ahead and just basically Swap this out with the information from the humidity right so fairly straightforward all we're going to do here is swap out where it says rain I can press command D to to get multic cursors humidity change the precipitation probability to the relative humidity 2 minute marker and then it's still going to be percentage and everything else is pretty good except the color here I want it to be till okay hit save and this one the max value we're not going to have a zero oh actually we are cuz it's going to be I guess it's going to be up to 100 so that would be pretty handy to have it there and then what we do is we simply go ahead and we take our humidity chart we pass through the results just like so and we make it a self-closed component we hit save and we go ahead into our page and we see for oursel the results and I think I forgotten one thing yeah I've forgotten to change chances of rain you see the humidity is there uh let's just go into the temperature and yes you could probably make a responsive um you know you could probably customize this with different props so that way you're not you know passing in the same kind of data because you could make make this a reasonable component really right this one will be uh humidity levels so humidity levels awesome stuff now just like that we have humidity levels looking bomb right so that's absolutely beautiful right and then the UV index is 6.2 if it's high but otherwise if it was lower than that it wouldn't be so someone let me know if it's uh if someone says BR seems to be wrong some time no so the time is actually correct but it's offset against um Dubai time so in Dubai at 3:42 it would be your Sunrise that's essentially what's happened right so that's where the offsets happened and the sunset in Dubai 531 would be belgrade's um Sunset so that's actually what's so what you're doing is you're looking at this in regards to this so for for me that would be your Sunrise that's essentially what's happened yeah um okay so next next up guys we have the fun part the part where you've all been waiting for and everyone's been very patient I must say yeah so now what we're going to do is we are actually going to go ahead and create um the chat GPT section of the build right so now we're actually going to go ahead and pass in the data from that massive Json that we had we're going to clean the data then we're going to create an endpoint which communicates with open ai's API and then we're actually going to use GPT 4 and you can use GPT 3.5 to go ahead and create the summary and the summary will be looking like this and it will essentially go ahead and provid us a perfect breakdown of what the hell is going on right so right so at this point we are going to also before I carry on let's actually Implement a loading right section so where we have um any loading situation right so uh in this case if you're at the home screen and you are in initially loading for example a page right so if we go back to the home screen and you're loading a page right now you're just waiting okay so at this point what I might do is I'm going to use in xjs 13 you've actually got this beautiful thing you can adjust the time zone um according to C chosen but I'm not getting into that right now because there's a lot of things that we have to do you can feel free to extend it yourself do that right loading. TSX so RFC boom that should is relatively easy in the grand scheme of all of this stuff right so loading um and now what I'm going to do is I'm just going to have a simple loading now I'm not going to spend too much time describing how I built the loading screen it's very kind of straightforward in regards to the actual stuff that I'm putting on there it's just a div with a bunch of stuff inside of it and this is the styling we have so it's going to be a sun icon loading City weather information hold on we're crunching some numbers and so forth now I want to have the same loader it will actually carry over but I found that in some cases it was being a bit weird so I'm going to put the same load out in here now that means at this route we're we're going to load it and at this L this route we're also going to load it but typically it should just kind of use the highest level one if it doesn't have one at a local level now with that said what we should find is anytime we have a blocking element for example this is a blocking element sorry this one is a blocking element it will go ahead and cause the uh loader to kick in so if we do country for example Albania we do something like um delvine look at that loading City weather information boom nice right and then if we do Albania sort of like I'm just doing Albania cuz it's there b boom and if I did like United Kingdom because we already have a cash value it shouldn't actually load very much so it'll be London boom you see that because it already had a cash value so it actually need to load it right the only thing that I would recommend here is because you've got cashed values you still want it to revalidate after a certain point in time so to make sure that it revalidates you can do a very simple change here go to the top simply pop in revalidate export cons revalidate 60 now every 60 seconds it'll revalidate the cach simple as that now you've got ISR you got incremental static regeneration of that static page so every 60 seconds it will trigger a rebuild of the cash page provided that someone has visited it so that is absolutely awesome right quick little water break and then we're going to go ahead and do chat GPT so we've actually implemented the ALB says you're the best bro thank you so much I appreciate you man right so at this point now we're going to create the endpoint for open AI right so what we're going to do is we're going to use the new the brand new open AI um brand new nextjs 13 routs right so in this case you see in the app we have our API and we have a Hello route right so this is simply a hello sort of um endpoint right now I'm going to delete that because I don't really care about the hello endpoint and then I'm going to go ahead and create a new API endpoint called get WEA summary get weather summary okay now inside of get weather summary the new syntax is all you need to do is type in root. TS cool and now inside of root. TS we are going to basically create a uh post request support right and what's nice about this is you can go ahead and you know support post request get request put update patch all that kind of stuff but here this is how you do a post request you can do the same for get and so forth right but we're going to do only a post request is support at this route very simple then what I want to do is I need to install open AI so we're actually going to be using open AI API here so let's head over to open AI um let's do open AI documentation so API documentation and something I want to mention is that in zero to full stack Caro inside of our course we have actually gone through this extensively in recent coaching Calles so I highly recommend if you're on the fence you kind of want to you know learn a bit more about this stuff and you want to do a deep dive check us out at 0 to full stack C or scan the QR code on the screen right now right and that's going to help you basically get dialed in with any of this stuff cuz we've done this loads in coaching course so we're going to install open AI at the package so let's go ahead and do it right now so command J and then I'm going to go ahead and pop in like so so remember make sure you're in the correct folder so the top level install open AI like so now while that's doing it we also need to have an open a I key right so this is very important because you need to pass it inside of your requests right so what I want to do is go into my personal view API keys and so forth so I've got a few Keys here you can go ahead and create a new key now it's worth mentioning yes you do get a free tier I believe when you're using open AI so chat GPT 3.5 you're getting a free tier and it's also worth mentioning the chat GPT uh GPT sorry 3.5 turbo is extremely cheaper than GPT 4 because gp4 requires a lot more like calculation intensity I guess on their side to go ahead and process process your input and output it's also slower than GPT 3.5 turbo so it's something worth mentioning so if you're testing this out I I ran up like $5 but um you'll get a free quoter here so you can probably use your free quter for as long as you want but I added a billing um card to my account so I could just keep testing this thing I didn't care about paying $10 whatever so you can go ahead and do that right so in this case um what I'm going to is generate a new secret key so I'm going to click on this I'm going to name my keys so I'm going to call this YouTube uh demo key and then I'm going to go ahead and create secret key so I'm going to go ahead and create it right now you guys thought I was going to give away my key didn't you then I'm going to copy that key right so now I've copied my key okay so copy that key and then you go back to this screen okay so now I've got my YouTube demo key here and then what I want you to do is go over to your environment file okay so head over to your environment file where's mine I'm going to click into it now I'm going to hide some delicate environment file information right now so I'm going to going to go ahead and hide some quick little information as I show you something so I'm just going to pretend that I like I'm just going to comment this up one second okay I don't know how to do my little trick okay my trick don't work anymore um but what I'll do is I'm going to hide this so I basically got rid of one of my keys and then I've gone ahead and said open you should have had your API your next public steps and API key here as well but now I've got my open AI API key and I will paste that value here okay so I'm going to go ahead and paste that value in so now I've pasted that value in and then I'll put back my old key the one that I just removed a second ago so you should have in your environment file I'll just say it out loud you should have your API URL you should have a next public step an API key and you should have an open AI API key okay so those two things save and then close your file cool now we have our environment set up okay so that's done and then we have our open AI should have installed correctly there we go it has installed right so cool so now what I want to do is I want to import two dependencies into my project boom like so and here you can see at open AI cannot find open AI or corresponding oh yeah because now I need to actually create a helper file so at the top level at the package Json level create a open ai. TS file okay now inside of this open ai. TS file we are going to go ahead and create a little bit of a setup file for us right so this is very simple we're simply going to import two things configuration open AI uh and the API then we're going to create a new configuration by passing in the open AI API key so this has to correlate to your environment key value okay so then you export it so you basically create a new open AI API config by passing the configuration in so this is your connection to open AI then we export it so we can use it so heading back over here now if we do this why is this freaking out so at this point where's my open AI it should be completely fine I'm not sure why it's being weird yeah so there you go it's working okay yeah so we have our post request now so now we can do the magic stuff all right so here I basically I'm going to pass into that post request some data in the weather data part of that Json object right so I'm going to pass through some weather data in the body right so this is going to be uh weather data is going to be in the body in the body of the post request right so imagine that comes in in the body of the post request then what we'll do is we'll say const response equals await all right open AI do create chat completion okay so create chat completion now here's where the magic happens really right so the first thing you want to do is put the model in okay so model is going to be uh essentially it's going to be GPT 4 if you have access to the gp4 API I do have access to the gp4 API so we can use it but if you don't have access to it that's fine okay you can use the GPT 3.5 turbo which is available to everyone and it's also worth mentioning that this completely works fine with the build right so you can use gp2 3.5 as well right but I have got access to GPT 4 so we can use that okay next up you will get a 401 if you try to do this with gp4 and you don't have access to it right but you can request access on the website so in this case now we're going to go ahead and say temperature is going to be 0.8 this is a value between 0 and 2 and it basically s symbol izes how random or focused it should really be the number of responses we want is one we're going to disable the stream because we only want the entire value to come back in one go and then we're going to pass in the messages okay now the messages is an array of items right so we need to basically pass in the conversational aspect of what we're going to be doing so the role in the beginning is going to be the system message this essentially sets up what the context is for the chat so you you can use the system message in a way to be like that you you should pretend that you're a weather news presenter and you're going to present the news in this kind of way and all of that kind of stuff you're basically setting it up before the chats even begun and then you can provide it a second piece of information saying hey actually here's the today's weather in this format and this is going to be the Json information and then what it will do is it will give us the response back right so it's going to be perfectly primed in a way to give us back the information that we're after so what I've done is I've been a bit Overkill here just to extend like be a bit crazy about it but I've said pretend you're a weather news presenter presenting live on television be energetic and full of Charisma introduce yourself as Sunny so you can introduce yourself as whatever you want and say you are live from the popam headquarters State the CE your is providing a summary for then give a summary of today's weather only make it easy for the viewer to blah blah blah okay so you can go ahead and do that kind of thing yeah so um and provide you provide a joke regarding the weather assume the data came from your team at the news office and not the user because what was happening it was like it was saying to me oh based on the Json data that you provided and I didn't want it to say I just want to say hey tuning in here from sunny at the headquarters of Pap fam the weather today is so forth right so that's what we kind of wanted it the next one is you're going to pretend to be the user and the user is going to say the following the user is going to say we're going to do string interpolation here it's going to say hi hi there can I get a summary of the weather so it's going to be somethingone that's hi there can I get get some today's weather use the following information to get the weather data and then what we're doing is we're stringifying the weather data so it becomes a piece of text right and really this is quite nice right so what this is actually doing is it's stringifying that data we're not going to pass the entire data in by the way we're going to clean it up so you're not going to pass that entire chunk because then you're you're running through your tokens like nothing right um and bear in mind that this can be token exhaustive right if you look at this this could be actually considered quow tokens so just bear that in mind okay so if you're going to run through your quot pretty quick then consider maybe adding a card just while you're testing this out that kind of thing right then we're going to basically get the response the data out of the response okay and then what we'll do is I'm just going to debug here so I'm going to say something like um data is and then data and that that allows me when I'm debugging it it's actually a pretty handy thing that you can do and then all I care about is what did it reply right so next response data. choices Z would be the first response that he gave us message right and if everything was successful this would have the response for the summary inside of it okay cool so at this point now what we're going to do um is we're going to go back to my page and we're going to go ahead and create a cleanup function so something which allows us to essentially clean the data so the reason why I need to clean the data kind of function is because I don't want to pass in the entire object right um the entire results because the results is so big that chat GPT can right now even on the um even on the GPT 4 model it can it can handle up to 8K context or the bigger model can handle up to 32k context but you're paying per that many I think it's like 3 cents per like a th000 uh tokens or something like that but the point is you like we want to minimize it right it doesn't need all the data especially if it's only giving me the things for today right so we can actually save ourselves a lot of money right so what I'll do is I'll go ahead and I'll create inside of our lib folder I'm going to create a clean data um file and what this is do is just basically transforming it so it's a lot cleaner so we don't have a lot of the bloat behind it okay now what I'm doing is I'm saying clean cons clean data cons clean data equals and I'm passing in two things I'm passing in the data which is of type rout and I'm passing in the city which is of type string okay and then what I'm doing is I'm return I'm basically saying the following thing so I'm taking the following properties from the um uh I'm taking the following properties from uh the following so I'm stripping out the current weather times Zone hourly hourly units and time zone abbreviation from data okay then I'm stripping out the following from current weather so then I'm getting the temperature wind speed wind direction weather code and time from current data from current weather then I'm getting the sum specifics from the hourly because I don't care about daily and all that kind of stuff I just need from the hourly information that I stripped out I need temperature snowfall rainfall relative humidity precipitation UV Index right now with that said I'm going to return a new object only including some of this information right so I'm going to say return and then what I'll do is I'll return the current weather with a key value like this we got the current weather then I'm going to have the hourly information which is going to be the following and what I'm doing here is I'm passing back the temperature snowfall rain relative humidity precipitation and UV index but I'm slicing only the first 24 hours worth of data so that way I'm not including all of the extra information because otherwise what's going to happen is you're going to have so much extra information that it just ruins your quote with chat GPT right and that's just pointless then we've got time zone city um time zone abbreviation hour units and City I'm passing in and actually extending the object to so now we have not only a smaller object from that initial large results object but now it's also got the city uh character in so that way when I pass it to chat GPT or GPT 4 it knows what it's doing okay so it knows what city it's in sorry that way it can kind of provide that useful information okay so now what do we do we go back and where we have the results here I'm going to have uh a new variable called Data to send right or the results to send and what this would be is it will be we're going to say clean data and I'm going to pass in the results and I'm going to pass in the city okay and that will be the clean data yeah and then what we'll do is I can get rid of this now I'm going to say a const res equals await Fetch and now I'm going to make a call to my back end right now I'm also going to make a helper function here because what we need to do is we can't just say for/ API for/ summary because we're in a server function now the server function does not know where it is right it doesn't know if its relative path is local host or if it's relative path if is is the Vel URL so I'm going to create one more helper function in lib and this is going to be called get base path right this will tell um basically our code where the hell your base path is right so this base path is going to look something like this we're going to say export default get base path and what we're saying is if you're in the development environment it's going to be locost 3000 otherwise and obviously you can then go ahead and even go further with the port number and all that otherwise it's going to be https slpress and Vell and this is basically once you've deployed it that's where you'll be deployed to Vel is automatically given to you and then that would be your base path okay and you can get some debugging issues when you're having this bit so make sure you take care okay so here what we'll say is we'll do the following we'll say uh get base path like so for/ API for SLG getwe summary okay so for SLG get weather summary and then we have the object and it will be a post object the headers are going to be content type application J the body is going to be a stringified weather data so in this case we're going to pass remember the weather data is what we set up our route and we're actually going to give it the data to send not results okay so that way it's a lot more cleaner in when it's dealing with it now that will go ahead and get us back the GPT data right so what we can do is we can get the GPT data and pass it out so just like so and then we can go ahead and extract the content out of that message okay so we can extract the content out of that message now once we have that we can basically go down here and remember where we say this is where the gp4 summary will go we can actually go ahead and straight away put that here now if we did all of that correct what we should have is a clean data function which will clean out the results into a smaller more efficient object we will then go ahead and make a request to our API which will then go ahead and pretend it's weather Center it will use gp4 it will be um connected to our correct configuration with our open API open AI key and then it will return us the data which with the message inside of it and that will basically will pull the content from that message and then we will pass it into the call out card okay and now with that said we might have everything optimally done so clean data uh let's go ahead and refresh so it's loading the city weather information clean dat is not defined okay so where is clean data I don't think I've actually exported clean data that's the problem yeah I haven't so clean data yeah so we didn't export it my bad export default clean data and then we go down here import clean data and now let's give it a try guys so let's go ahead and remember you want to go ahead and disable your cach when you do your first reload clear this out so now it's loading the city weather information and remember what it's probably going to take a little bit more time for in the initial run is that it's actually calculating the GPT summary and GPT 4 is known to be a lot slower than GPT 3.5 turbo now this is using GPT 4 right now to come back with the summary so let's see if it did it right let's get hyped up because this is a moment of truth if it's going to work this would be so cool but we're going to we're basically doing it for London right now it's generating that chat GPT aai summary um using GPT 4 it might take a little bit longer and I'll show you the speed difference with 3.5 turbo as well but remember once it's done it will only revalidate every 60 seconds so users won't actually see this uh every single time okay so I just want to check something here um let's go back over here let's just see did it um actually okay so it's come back with some data look at this guys it used up total tokens 983 um and it's doing it a few times over so let's see maybe I refreshed it a few times oh guys look at that ladies and gentlemen it's time for some weather action I'm Sunny coming live from the papa F heads bringing you a fantastic summary of today's weather for the lovely city of London all right folks get ready because we got some interesting weather coming your way the current temperature is sitting at a cool 9° C yes it is with a wind speed of 9.2 there we go and then coming from the 11 116° Direction awesome I think I messed that up that should be kilm per hour as for the weather code it's a which means we've got some light rain showers and that's perfect to bang on we'll be experiencing some light rain da da da but no don't worry snow levs because there won't be any snow for today in terms of humidity da da da and then now for those of you are concerned about the UV index it will range from 0 to 5.4 so make sure you wear some SPF if you're going outside because it's if it's higher than three just to be on the safe side and then it even gives you a little joke right why don't meteorologist like to die Outdoors because it's too windy butum okay that's jokes right so in this case now if I go to United Arab Emirates and let's go to Dubai and hit enter now you can see it's loading City weather information for Dubai and remember as I said gp4 will take a little bit longer right so just something to remember now I want to show you something once this is loaded it's really worth mentioning it will cash the previous page and it will do it for every 60 seconds based on if someone has visited so they won't see this long loading procedure right it's only the first user to ever hit that page so after that it will happen in the background and the user will see the previous summary and then every hour it would always be up to date so it's actually really really nice as to how this will work right so let's go ahead and see this right now so after remember again GPT 4 a little bit slower I will show you the difference between 3.5 turbo and four but this is absolutely phenomenal because once this loads out it will be incredible and I'll show you again remember it will actually go ahead and have a really nice effect once you have the caching in play so let's go ahead and see um once that's done just give it just give it some a moment right so this will go ahead and do its thing and the data is right so in this case it's still coming back from us right so let it do his thing right uh again the demo Gods always against me so right now and there you go you can see it look good morning everyone this is sunny coming from a beautiful city of Dubai the current temperatur is are warm 28 yeah we go wi 15.6 km yes I definitely need change that uh as we progress out the day temperatures will rise that's awesome stuff look at that the only thing is the time came back weird that's again strange uh this means today is oh because I okay so again remember disable your cash right so let's refresh let's let it do one more build for that that was my fault again this is something which I'm really happy you actually saw because cashing can be a bit of a concern especially when you're coding you might be like hang on all my code is s why is this happening right um so yeah this can be a bit of an issue so so in this case we'll give this a second Tod doest thing and I will show you so um it's actually not too bad waiting for this in that sense so you don't like obviously this would be a bit long for a user in my opinion and again once you deploy to Vel it's worth mentioning that anything over 10 seconds in a cloud function requires their paid platform right so uh it can take a little bit extra so now you can see look the time came in after we cleared the cash and then bam look at that it's really really nice and it tells us that the buy is going to be blazing hot essentially right hello folks sunny here coming you live from the pop and now I want to show you something okay let's go back to London and then you're probably thinking oh no but it's going to load all that long time again bam see how it's really fast right once it's done it once it's cashed it and if we go back to Dubai boom that's what I'm talking about right so that's actually really powerful because now this will be cached on the Vel right Vel side so what will happen is it won't have to go ahead and redeploy those or or figure out those static assets it will only do it after 60 seconds uh whereby somebody will see this it will trigger the rebuild in the background and then the next person to come on will get the new version right but in this case in weather sense you don't really care if it's like you know an a minute out or something like that it doesn't really make a difference right cuz you're getting the overall Day summary of weather so this is actually really really awesome so in this case you've got a nice little setup now I would probably recommend you change that revalidate to even a day because you don't need to know per hour the difference so I would probably change this to be like 60 times by 12 um uh 24 sorry so probably 1440 so every day it would PR pretty much be revalidate but just so you can you know it's kind of doing this right um right now I've simply got a loaded showing because it's blocking at the top level okay um so now what I need to do is I want to showcase something I want to show you the speed difference of if you haven't got gp4 access how can you do this build right so all you need to do is change the model here to GPT 3.5 dturbo and there's other models as well right so you don't have to just use these but let's go ahead and try somewhere new now let's do um somewhere like s so now notice the speed difference here right there will be a noticeable speed difference this will be actually a lot quicker than GPT 4 although the answer may not be as profound but it would be something to just bear in mind it would also be a lot cheaper than GPT 4 so you see how that was a lot faster yeah and it's still pretty decent right like I would still accept that fully right and then if we go to United Kingdom we go to London for example our previous value will still be cashed I believe so yeah it's still cashed right and if we go back back to United Kingdom and let's go to like for example Manchester right Manchester boom now you'll see again it's loading that one because it hasn't fetched that previously so this is a really nice balance between xjs 13 some new features a lot of the sort of you know magic behind you know ISR that kind of thing and how it can fetch in cash on the verel side but um something to definitely me mentions but look at that it's a lot faster doing it from um GPT 3. .5 I would recommend you probably use this for this approach cuz it's really not going to be such a big difference except I'll be honest with you it be a lot cheaper to do GPT 3.5 okay but it's you can do it as you saw for yourself we can use GPT 4 to get a really more like high level ACC remember GPT 4 will give you a better answer it's a lot more of a higher trained model and so forth right um because because look s and Google how beautiful beach is out nice all right so in that case that's awesome so let's I think at this point guys we are ready to deploy right so we're about to go ahead and deploy this bad boy of an app right so this is absolutely huge let's go ahead and deploy this thing so first thing I want you to do is you can go into your um uh browser so you need to I'm going to show you a few ways right so you can you can actually go ahead and um inside of Vel so so you want to go to Vel and type in CLI so type go to Google type in cell CLI install this CLI right so you want to go ahead and install this globally I've already done it so you don't need to I don't need to do it now at this point I'll show you a very easy way to install you can do it with GitHub but I'll show you an even easier way so at this point go to the top level of your app go here and I want you to type in Vel right now what this will do is it will set up a and build a kind of app for you so set up and deploy yes right now it's worth mentioning that I have set up a team okay if you did deploy it on on a normal hobby plan so the normal hobby plan will basically fail now the reason why it will fail is because when it does that chat GPT step that call that functional that sort of functional um when I say fun Cloud function is essentially when it uses makes that request to a post end point it's going to take longer than 10 seconds and because it takes longer than 10 seconds to do that call it's actually not allowed in the hobby plan so any anything over 10 seconds you need a paid plan so you can go ahead and do it but you could basically dummy it up and make it a bit simpler so it maybe didn't take as long or use a simpler model which is even quicker but it might just not be as efficient or B as as high quality on answer but in this case I went ahead and set up a YouTube team on Vel and this one is actually going to allow you to go ahead and do it so on Vel you can do that I'm going to link to an existing project no project name steps and weather app YouTube directory yes and then and so forth so when you deploy it on a team you don't have that limit of 10 seconds right want to modify these settings no that's fine and it will deploy now here is a bit I want you to pay attention to it will show you an inspect now this deployment will fail and I'll tell you why it will fail because we haven't got the environment stuff set up so I've got a trial you can also get a 14-day trial just to try this out as well so set up a team account so you just go here and you set up a team they blocked one of mine because they got spammed with on a YouTube build but your personal account a hobby one will not be enough to get past that 10c limit when you're basically using GPT right so now I want to go I want you to go to your overview steps end weather YouTube app and I want you to go to your settings and here environment variables so here what I want you to do is go over to your environment variables and basically hit enter right so I'm going to hide the screen because I don't want to reveal my key so hit enter now you're inside your environment variables file I want you to select everything with command a and I want you to hit copy okay now once you've hit copy I want you to go back over to your um to this screen right here and I want you to paste okay so you're going to paste here so I'm going to go ahead and paste now so I'm pasting and then what we'll do is I'm going to click on save so it shows me three things environment production so I've actually pasted it in so I pasted those values in there and then it's got production uh preview development and then I'm going to click on Save okay and as you can see now I've got those three things now the only thing I need to change the API URL and the um yeah the API URL so this one I've set it to Local Host by accident right so this one Local Host so here what you want to do you want to edit this because this has to be the actual value that we deploy our graph um our steps in API to so here you want this to become this your API URL so when you start up your steps in it will tell you what it is and this is your live steps and deployed URL and and that automatically gets deployed for you every time you start it up right so we're going to go ahead and click save now I have my steps Zen key I have my open AI key and I have my API URL all set and then what we want to do is we want to re-trigger our build okay so we're going to go back to here and I'm going to go ahead and type in Vel d-r cool and now we'll do that now once that's done I'm going to go ahead and do the following so let that do a thing and what I will do is after this build I will go ahead and cut my uh key so that way it doesn't go crazy on the billing um because obviously it's going to be live afterwards so this will now trigger a build okay and then it will trigger the build and as you can see here it's going to start my build off and start basically preparing everything it needs to get it up and running okay so let that do it okay let's see if it works right I'm guaranteed there's probably going to be an error but if it's not amazing yeah because there's always some error when you're dealing with this stuff that's yeah all right so assigning the domains let's click on it boom it gives me the URL let's go to the country I'm going to go to United Arab Emirates Dubai let's see did it does it crash on me does it work does it you know okay okay I'm not C celebrating yet I'm not celebrating just yet at this point if you're on a hobby plan it will likely fail because it will take longer than 10 seconds so yes You' have to go to the the Pro Plan on Vel all right so Vel create a team make it a Pro Plan you get a 14-day trial so you can try it out but let's see let's go that's what I'm talking about guys it worked that's so sick that is Absol absolutely sick and even on the phone it will load you'll get the nice AI summary everything you see how the power of nextjs 13.2 all that 13.3 all came together the caching the way it all works a it's just beautiful there we have it guys the fourth and final build of this crash course has been complete firstly just give yourself a round of applause for getting to this point in the video and if you're already here and you haven't already yet make sure you subscribe and comment to let us know which build was your favorite don't forget to add this entire build alongside all the others to your digital portfolio because these are going to massively increase your chance of getting a job inside of this software development field and remember if you got stuck at any point you can simply check out the papa GitHub repo to access all the code from today's builds that's going to be linked in the description and if you want to go ahead and sharpen your skill set in case you got stuck at any point or you want to go ahead and just level up your skill set over time in the form of weekly coaching calls module cont content from yours truly myself and more content just like this but at a much higher level and check out my premium Flagship community and cost zero to full stack hero Linked In the description we went ahead and built four incredible apps leveraging the latest and greatest in AI Tech and I taught you how to go ahead and leverage tons of different libraries in the process hopefully by this point you're very comfortable with next year 13 but if you still want more practice there's tons of free videos on the YouTube channel so make sure you sub subscribe for more content just like this and of course if you want to go ahead and Le further 02o first link in the description and guys if you made it to this point in the video drop a little robot Emoji so I know which of you OG's made it to this point in the video with that said guys I hope you enjoyed this video we put a ton of hard work and effort into getting these out to you so you can enjoy them for absolutely free all we ask like comment and subscribe and as always guys it's your boy Papa react AKA sunny and I will see you in the next video peace did you enjoy this video guys well if you did and you want to learn more about next year's 13 check out my 18-hour crash course right now over here on the screen just simply go ahead and click it and you're going to be building another six incredible apps using nextjs 13 for absolutely free see you there peace
Info
Channel: Sonny Sangha
Views: 49,130
Rating: undefined out of 5
Keywords: react, developer, reactjs, html, css, js, javascript, papa, papareact, papa-react, tutorial, frontend, webdev, dev, clone, backend, fullstack, motivation, reactnative, react-native, redux, typescript
Id: 1KPG3LiE4jU
Channel Id: undefined
Length: 763min 39sec (45819 seconds)
Published: Tue Oct 03 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.