Full Stack TikTok Clone with Nuxt 3, Vue 3, Tailwind CSS, Laravel API,, Pinia, Axios, Javascript

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
okay let's go through the setup first what you're going to need installed on your machine so we can start developing you're going to need node.js so you definitely need that composer as well you're going to need a an environment that your laravel application can run on so the easiest one to set up is this zamp you can use it for any machine but if you want to be more specific you can use laravel Valley for Mac or Linux and I did find this package on GitHub for laravel Valley for Windows so if you want to try and set it up and you've got a Windows machine check this out see if you can set it up but if not the easiest option is zamp and if you do have a Mac then install this Homebrew and it's just a package manager it's it's easier to set stuff up basically loads of commands for it have a look what it does you should be good and finally for a code editor I'm going to use Visual Studio code right awesome let's begin right let's open up a terminal let's Zoom that right in I'm going to go into my sites folder and first we're going to start off with the front end so let's go into the browser I'm going to look for veetjs.dev forward slash guide and scroll down and this npm createvit add latest blah blah blah blah copy that line let's go back into our terminal paste that in and my view app I'm going to change for tick tock clone let's press enter and then select the framework we want View and then at the very bottom we have next so we're going to press that awesome that is installed now let's CD into Tick Tock clone and then npm I to install all the dependencies awesome that is done now let's open vs code so I'll type in code there's a little editor and now I'm going to go back into my sites file and I'm going to find Tick Tock clone which is right there drag it in drop it and also there is our front end right let's install all the things we need to like um Tailwind Pina all that stuff so let's start with Tailwind right now let's type in next install Tailwind a top one right there and we want next three Okay so we've done this section three little project let's install Tailwind so let's grab this line copy it go back to vs code let's open a terminal and probably Zoom it in a little bit just so we can see awesome right let's paste that command in enter cool let's get the next command which is this one copy it back to vs code paste it in the terminal awesome there's our Tailwind config go back to the browser now we need to go into the next config.js so let's grab all this copy that back to vs code let's go and do next config and let's drop that in like that just like that beautiful save that see the next command now we have to configure the template paths in Tailwind config.js so let's grab all of this copy it back to vs code Tailwind config and that content section just paste it in over like that so it should look like that save it let's see what else we got scroll down add the Tailwind directives to asset CSS main.js cool let's grab that copy it and we don't have an assets file so let's create one new folder assets and then a new folder inside that CSS and then inside that new file main.css and then let's paste that in save it awesome that is good right next we need to go into the nux config file and add this line so we import our CSS so let's copy that and let's go into next config and just above at the very top I'm going to add that in like so save that and that is Tailwind setup right let's now add in our npm packages so back to the browser and the first one is going to be next icons and let's scroll down I think it's on the next three sites so icon module yeah awesome so in nux.com forward slash modules forward slash icon and we scroll down we'll find this setup let's grab this npm install section copy it back to the editor clear this out and let's install that awesome that is done and if you look at the docs all we have to do is take this section for modules let's copy that and let's just paste that in right there like that beautiful and let's just format it because we're going to have a few more right next is going to be app Enya forward slash nux so this npm repository I'll just click this npmi pina forward slash next let's go back in and let's install that cool that is installed let's add it into this so just underneath add add pin your next and then the last package is going to be the pinia plug-in persisted State forward slash next but I do have a link for this which is a GitHub page so prasdev's github.io pin your plugin persistence date forward slash Frameworks forward slash next three dot HTML and just to help out in the GitHub repository which is going to be John week's Dev Tick Tock hyphen clone this is the front end I've left this file called notes dot text and if you go in this you'll see the URL is right there just copy it and paste it in there and you'll come to this page awesome right let's take the second one the npm one copy that go back to vs code and let's paste that in enter that is done right all we need to do now is add that in like so beautiful now one final thing just at the top of this above the CSS add in pages is true and that should be it save that and now let's go into app.view and we have all this stuff we don't need any of that we need next page like that save it then we also need to make a Pages folder so let's do a new folder pages and inside that Pages we're gonna have a new file and for now we're gonna have index.view awesome right I'm gonna v-base it up this style we don't need I'm going to get rid of that and inside this div I'm going to say testing let's add a class and say BG red 500 to see if Tailwind is working save it and now with a bit of luck we should be ready to go let's clear this terminal out unless for an npm run Dev and let's see what happens it did load but we got a little error with Pina I know what this is so again if you go to the GitHub repository The Tick Tock clone you'll see right there just take this command npm ipinia hyphen f copy that go back to vs code let's open a new terminal and paste that in and press enter and let's go back to our other terminal close this down and this one reopen it so we know it's fresh and then again let's put npm run Dev and there we go looks like it's working let's open this localhost 3000 oh it's beautiful there we go that is exactly what we want to see and just to make sure that all the rest of our packages are working let's just test one more underneath this testing I'm going to add in this icon with a name MDI close and a size 100 let's go and have a look let's save that go back to our browser awesome there it is right there okay we're all set up on the front end we are ready to go actually just before we start so I don't forget quickly just open a new terminal and put in axios so npm I axios just like that awesome done right let's start let's close all these other Pages because we don't need them and I'm going to put that over there that like that close all this up close the list get rid of all these files right first thing we're going to do is get rid of this div and replace it with a main layout now let's go on the side panel we're going to have to create a folder called layouts like that and then in layouts new file mainly a dot view and that's vbc map like so get rid of the style don't need that and just above this div we're going to start off with a component called top nav and we also need to make a folder for that so let's do a new folder components and then inside components we need a new file called popnav.view again vbase it up get rid of the style and let's start right open this top div section up and we're going to add in ID of top nav and the class is going to be fixed BG white z30 Flex item sender with full border B and h61 pixels and let's just save the index and the main layer of the sack just so we can see what we're doing right save that now inside that another div Chuck a class on it with flex item sender justify between widthful px6 and MX Auto and we're also going to have a dynamic class on this so put it on a new line and that is going to look like that so we've got root full path is equal to the base URL then we want a Max width of 1150 pixels or nothing now we need to import this root so let's go down to the script we're going to say cons root equals use root like that actually that's the cool thing about next you don't have to do any Imports for like refs or view router or anything like that it's already done for you which is very nice now inside this div another and we're gonna have another Dynamic class that's going to be root full path again is equal to the base URL if it is that width is 80 else LG W 20 and with 70 let's save that now inside that we're going to use our first nux link and have our first image and we're gonna have to go and get that we might as well get all the assets from GitHub so if I just drop this in there we go next link to base URL and then we go this image which is going to be the tick tock logo so if we go to our browser open our right up new tab go to The Tick Tock clone right in Tick Tock clone go to assets everything in this images folder you are gonna have to download so if we look inside it you need all of this so if we go back to the code editor and open the side panel inside assets you're going to need an images folder that looks like that so images and inside it you've got a mobile case Tick Tock logo small I mean it looks pretty big but it's the little one Tick Tock logo white and just a normal Tick Tock logo awesome okay let's close that side panel and go back to the browser and let's have a look in our application let's refresh we can't see anything yet what is going on we have an error in the terminal what is this main layout if this is in need of custom Element Make sure to exclude it from component resolution via compiler well let's go in index oh I didn't bring it in sorry okay so in the script import main layout from layouts main layout right save that close this terminal and now let's have a look refresh okay there we go nicely Tick Tock logo with our board bottom beautiful let's continue back in top nav and from this next link we want to go down one so one space it div it up open it add a class that is going to be hidden mdflex item sender BG F1 F1 F2 P1 rounded full Max with 300 pixels and width full then inside this you want an input open that up let's format it and you want a class and a placeholder and the class is going to be with full pl3 my2 BG transparent placeholder 83 8383 text 15 pixels Focus outline none and the placeholder is going to be search account if we save that and take a look you can see they're starting to come in at the top very nice and this next section very easy right under the input gonna be a div with a class PX3 py1 Flex item Center border L border L grade 300 and an icon inside and the name is going to be search line color a1a2a7 and the size is 22 and where you get these icons from I'll show you in the browser because this site is very cool this one icons.js.org there is tens of thousands of icons on you it is insane so if I just pull this across a sec and what is this a search if I just go in this and type search you get all these ones what's this search for all icons let's try that yes search look at it there it is just endless load more load more tens of thousands of icons and then you can click on one like this and you find it click that to copy it and then you throw it in your icon awesome just close that down a sec but yeah again this one is RI search line like that nice right save it let's have a look at our Local Host that's hidden now because remember this at a certain size we're hiding it so if we open this up oosh beautiful look at that awesome okay let's continue next section two divs down from the Icon so one two space it divid open it and class it with flex item sender justify end Gap 3 Min width 275 pixels Max width 320 pixels and width full then inside that button it up open it Chuck a class on it that is flex item sender border rounded SM PX3 py6 and hover BG grew 100 now inside this button we have a little icon and a span that's going to look like that so the span is class px2 font medium and text 15 pixels and this icon name is MDI plus so I think that's material design icon and color is black and a size 22. save it let's have a look look at that beautiful upload button right there gorgeous okay next under this button dip it up open it and then class it with flex item sender inside that add a button open it check a class on it with flex item Center bgf02c56 hex wide border rounded MD D dx3 and py6 and inside this button we got a little span that is login got a class of mx4 font medium text 15 pixels beautiful save it let's have a look see a little login button there let's open him up lock in awesome beautiful okay it's continue underneath this button we have a little icon so that's going to look like that MDI dots vertical color 16 17 24 on the size is 25. save it see a little three vertical dots on the side there next underneath this dividend again open it class it with flex and item sender and then we want two icons it's gonna look like that so this icon is carbon dend alt and the second icon is BX message detail save it and you can see there that we got a little paper airplane and a comment message box and just so we don't have all this mashing all over the page but now we're gonna do this on this above section add VF and put that to false like that and then if we go back the login button is gone and we just have upload and our two icons we just added in awesome just continue okay underneath these icons divid open it class it with relative inside that button it open that class this with mt1 and then inside this button we can have a little image and that is going to look like that so class rounded fall with 33 and this source is pick some dot photos with an ID of 83 and honestly this section doesn't really matter put it at like 300 300 whatever it doesn't matter save that and then if we go back to our page we can see there we got a nice little image that's where our profile picture is going to be awesome right let's continue under this button divid open it and open this top bit because we need an ID with pop-up menu and then a class that is going to be absolute BG white rounded LG py 1.5 with 200 pixels Shadow XL border top 43 pixels and minus right two beautiful now we we also need a VF on this and for now I'm just going to say VF and that's going to be equal to true if you just leave it like that for now and we can start to see a little bit of this box coming in nice right inside this div we need another next link close that off and open him up and open this top bit let's add a class of flex item sender just if I start py3 px2 hover BG green 100 and cursor pointer and also on this we're going to put them at click event like that it's going to be show menu equals false and then inside this link we want an icon and a span and that's going to look like that so the name is pH user the size is 20 and then we've got profile in the span and that is pl2 font semibold and text SM save it and if we take a look we can see it right there with a bit of hover on it beautiful now pretty much all we can do for this is take this next link copy it paste it beneath change the link to a div remove the add click this icon becomes IC outline login and the profile becomes log out now there is a slight difference on this px2 becomes PX 1.5 and after the hover we also need to add order T support the top save that let's go and have a look look at that beautiful give it a quick Zoom looks awesome man very nice and now at the bottom in the setup underneath this route just add in let show menu and that's a ref and that is false by default click the show menu scroll up and where it says V if true just change that for show menu save it let's go and have a look we click this oh did I oh I forgot the um click event on the button for the image so if we go up this button check this class on a new line and just underneath add show menu is equal to not show menu so if menu is true it'll turn it to false and if it's false it'll turn into true awesome save that let's go and have a little click there we go beautiful look at that awesome and that is the top nav Styles Done Right Next let's do our side nav section so it's doing the code and Main layout on this div underneath open the top app and we're going to slap on a class that's going to be Flex justify between MX or the widthful LG PX 2.5 and px0 and we also need a dynamic class for this so above we're going to add root full path is equal to the base URL and if that is true max width 1140 pixels else nothing and then inside this div just have another div inside it with side nav main that's going to be a component and we also need to import this root so in script bring in const root use root awesome save that right open the side panel and close this assets and in components let's make a new file and that's going to be sidenav main.view the base setup get rid of that style close this and let's go right open this top div app check an ID of side nav main under that we want a class with fixed z20 BG white PT 70 pixels H4 LG border r0 border R width 75 pixels and overflow Auto and again just above this class a dynamic class almost the same as before where the root full path is equal to the base URL if it is LG width 310 pixels else LG with 220 pixels and let's not forget to import root from use root beautiful okay next inside this div dip it up again open him classic with LG with full width 55 pixels and MX Auto Now inside this we need to make a new component so I'll just drop in what we need and it's going to be that so the component is called menu item and we pass props that is icon string color string and size string and you can see we have different inputs for all of these and on the top one we have a nux link that is going to the base URL awesome right so let's open our side panel we need to make a new component or a new file menu item dot view the base it get rid of the style and this is a very simple component not too much going on so let's start on this div we're going to add a class that is with full Flex item Center hover BG gray 100 P 2.5 and rounded MD inside that div again Chuck a class on it a flex item Center LG MX zero and MX Auto Now inside this div we've got a little icon and that's going to look like that so we got name color and size and these are all the props that we're passing we'll sort that out in a minute and then underneath that a little span section that's going to have a normal class and a dynamic class gonna look like that so the dynamic class is text with this Dynamic string and the normal class is LG block hidden pl9 pixels Mt 0.5 font semi bolt and Tech 17 pixels and inside that span we've got a little icon string awesome right let's define our props that's going to look like that so we're passing in icon string colors string and size string then we need to convert those to refs like so so two refs per props in that and again iconstring color string and size string we then need a little ref that's going to be called icon like that and finally three if statements and these are very simple if I just drop them in like that so if the icon string is equal to this text or this text or this text you assign this icon which is MDI home this one is CI group and this one is RI live line and that is that component done save that and now if we go back into our browser give it a refresh and we can't see anything let's actually open it up no we see nothing what have I done let's inspect and failed to resolve side nav main hmm let's have a look okay I just right clicked up there and I emptied cache and hard reloaded and then it came in so it was probably just cash awesome to close that and if we open this up oh beautiful look at that very nice and let's just open this up a bit more so we can see all of it and I'll just put it to the side like that beautiful and if we got the hover yeah hover's working beautiful right let's continue back inside nav Main and underneath this last menu item we just want a single div with a class border B LG ml2 and mt2 save that you can see now we've got a nice little border underneath that then underneath this section little div with a class LG block hidden text access text Gray 600 font semipole pt4 pb2 and px2 and inside that part suggested accounts save it look at that beautiful so easy now under this a single div just to add a little bit of padding so the class we got LG hidden block and pt3 now under this David and classic with cursor pointer and inside this we're gonna have another component and that is going to be menu item follow and later this will have a prop called user but for now we'll just hard code it all right let's open the side nav components we need a new component so new file menu item follow Dot View vbase set up get rid of this style tags and let's go right in this top div we need to clash this with flex item Center hover BG gray 100 rounded MD whitfall py 1.5 and px2 now inside this we're going to have an image and that's going to look like that so we get a class rounded full LG mx0 and then MX Auto 35 on width and then again this hard-coded URL which will change later in the video Let's just save it let's see if we can see anything nothing yet no worries let's just continue right under this image tag divot class it with LG PL 2.5 and LG block and then hidden inside that divot and class it with flex item Center then again a div and there's a little class with font bold and text 14 pixels and for now we're just going to put user name then underneath that we want to div with an icon inside it that's going to look like that we've got a class ml1 rounded full BG 58 D5 EC so a nice little blue color h14 pixels relative and then the icon put a class on it with relative minus top seven pixels and we've got a name on it that is teeny icons and tick small solid now color is white and the size is 15. let's save that and there we go we can see a nice little picture with our username and this little blue circle with an icon let's see if we can zoom in it no we can't but anyway we can see it awesome right let's finish this up two divs down from the Icon so one two make a space and this is going to be a div of the class font like text 12 pixels text Gray 600 and just check username in there again and that is that component done well I mean we might as well in the script so we don't forget later put in Define props user because we're going to pass a user to this component so just save are like it is for now it doesn't hurt awesome right let's jump back into side nav Main and just after menu follow one div down so this one make a space and we're gonna check a button in this as it's going to be class LG block hidden text f02c56 PT 1.5 pl2 and text 13 pixels just Chuck C all inside that let's save it and beautiful now we can see that little seal right by there awesome okay underneath this button actually we can scroll up and this single div with border B we can copy that and just paste it right under there the same again with this suggested accounts bit copy it paste that beneath and change suggested to following accounts and actually I think we can take all of it after that so this button this div and this single div copy that and go underneath follow account paste it in save yeah awesome and instead of see all that is see more save it and you can see it like that beautiful very nice so so now underneath this button we just need a single div class LG block hidden border B LG ml2 and mt2 and then underneath this I'm just going to drop this in because this is all like the terms and conditions stuff and some text that I stole from Tech talk literally it's just this so just this block of div the class is LG block hidden text 11 pixels and texture A500 and inside all these classes are the same on each div just got all this stuff in there like about Newsroom Tick Tock shop see for the next one developers advertise the terms the privacy policy all that type of stuff and then 2023 Tick Tock beautiful and our last final div underneath this section is check in a div with pb14 and that is it for this side nav save that and you can see it right there let's just bring this bad boy in look at that beautiful absolutely gorgeous we open this full we can see we got the max width that's working as well let's close him down a bit let's have a look at the mobile you nice boom look at that absolutely awesome nice so now we've done the top nav and the side nav we can actually start on this main content section so next let's do that right let's go into our index Dot View and inside main layout we're going to say div class it with pt80 pixels with count 100 minus 90 pixels and Max width 690 pixels now inside this we're going to have a component and that's going to be called host main so the posts for the main page now let's open a side panel in components new file host main.view VB setup get rid of that style and let's start right let's check a class on him Flex border B py6 we also want an ID and that's going to look like that so Post Main then inside that divot class it with cursor pointer then inside this we're going to have an image and that's going to look like that so we got a class rounded for Max height 60 pixels width 60 and then the source is this pixium dot photos so our hard-coded image save that let's have a look right next under that under the div give it up again blast with pl3 with full and PX4 then inside that divot class it with flex item sender justify between a PB 0.5 and inside this we want a little button and then inside this button we want a span and that's going to have a clasp that looks like that so font bold hover underline and cursor pointer and inside this for now just put user name and then under that span do another span open him up and class it with x13 pixels text light text Gray 500 pl1 and cursor pointer and again just take this username copy it and paste it in right save it let's have a look can't see anything yet let's give it a little refresh uh why can't we see that did I forget to put the slot in the main layout let's have a look yeah okay so inside mainlayer.view under beneath this div put in slot like that save it and yeah there we go now we can see it awesome cool let's continue so back in post main.view underneath this button space it and put another button and then class it with border text 15 pixels PX21 pixels py 0.5 border f02c56 and then the text is the same hover BG ffeef2 font semi bold and rounded MD and inside that just add the word follow a save we can see it right there have a little follow button beautiful okay now under this button go one div down so one space It Up divot and add a class to this there's going to be text 15 pixels PB 0.5 break words MD Max width 400 pixels and Max width 300 pixels and for right now I'm just gonna add in this is some text save that let's have a look you can see there this is some text very nice now under that div another div with a last text 14 pixels tax grade 500 PB 0.5 and then a couple of hashtags in here I've got fun cool and super awesome Dave and you can see it right there looking awesome and now underneath that another div with a class text 14 pixels PB 0.5 Flex item sender and font semi bold and inside this we've got an icon the name of this is MDI music then next this div with a class px1 original sound awesome and then the final icon which is MDI heart let's save that let's have a look and there it is right there look at that very nice okay next under this divot and then classic with mt 2.5 and flex then inside that div it and class it with relative Min height 480 pixels maxite 580 pixels Max width 260 pixels Flex item Center BG black rounded XL and cursor pointer right now inside this we're going to have our first video tag like that but we need a video for it so what you can do if you don't have a video go to pixabay.com and instead of all images go to videos or you can actually click this there where it says videos and just get one of these it doesn't matter what it is but I've already got one so I'll use that cool right let's open the side panel and where is the public there it is in public I'm just going to drop a little video in there like that and then go back to our video tag and I'm going to say forward slash warrior.mp4 save it and now you can see we got this little video section we're gonna have to add some tags onto this so let's close this side panel and format this so we can fit some other stuff on it now we also want a ref which is video Loop muted and we're going to check a class on it and that's going to look like that so rounded XL object cover MX Auto and height full right if we save that and go to our script section we're going to add in a variable that is a ref called video so this is referencing this ref video and all we're going to do for right now is just say on mounted video dot value dot play and that is it for now save that and let's take a look and there we go there is our little video of Ultimate Warrior losing his mind awesome right let's continue underneath this video we got an image and that is going to look like that so the source is going to be Tick Tock logo white which you should have already downloaded from GitHub which is in assets which is right there Tick Tock logo white and have a class absolute right two on bottom 14 and a width 90 and if we save this it should overlay the video yeah you can see it right there little Tick Tock logo over the top of the video beautiful uh let me just pull this a little bit like that awesome look at that amazing okay let's continue next under this div another div and add a class relative and Mr 75 pixels inside that another div Placid with absolute bottom zero and pl2 inside that div again plus that with pb4 and text sender then inside that we need a button and we're going to add a class to that that's going to be rounded full BG gray 200 P2 on cursor pointer and inside this button we're going to add an icon and it's going to look like that so the name is MDI heart and the size is 25. save it and you can see there on the side we have a little heart beautiful let's continue okay underneath this button we're going to add a span it's going to look like that so the class text XS X gray 800 Font semi bold and just hard code 34. save it you can see we got a little 34 underneath it and now what we can do for this this div that's surrounding the button and the span copy it paste it beneath you want to change the icon name to BX bxs message rounded dots and then do exactly the same copy that div section paste it beneath and for the name of this you want to change it to RI share 4 forward fill now save that and take a look you can see right there we go all our little icons on the side login beautiful and awesome that is that section Done Right Next let's do the upload page that's doing the code open the side panel and inside Pages want a new folder say upload and then inside upload of a new file index.view and then V base It Up Style get rid of that and let's go okay instead of using the main layout we are going to use a new layout component that we're going to make and that's going to be called upload layout so let's open the side panel go in layouts duplicate this main layout so main becomes upload layout so we have main layout and upload layout and this is very simple this Dynamic class just remove it the top nav you're going to take from the top and put it inside of this first div that is flex now all this class stuff at the top replace it with BG f8 f8 f8 and height 100 VH so so view height now this div with no class we're going to add Flex justify between MX or whitfall px2 and Max width 1140 pixels we're going to take this slot out of there and replace side nav main with slot and that is it okay close that now if we save this page and in our browser we go to forward slash upload we can't see anything why not oh because I forgot to import it in the script so just add that in import upload layout from layout save that now you can see that we've got a full width navigation at the top awesome and if we just remove this outer div if you don't need it remove that awesome okay let's go so divided with widthful mt80 pixels MD 40 pixels BG white shadow LG rounded MD py6 mdpx10 and PX4 let's save it you can see this coming in now beautiful then we have a little div with two divs inside I did we got upload video and post a video to your account first class text 23 pixels font semi bold and second text Gray 400 and mt1 save that and that looks like that beautiful next under that div block another div class it with mt8 MD flex and GAP six now inside this we want a label and for the four we're going to say file input we also want to class on this and there is quite a few Styles so that's going to look like that so MD mx0 MX Auto mt4 mb6 Flex Flex call Item sender just if I send a widthful Max width 260 pixels height 470 pixels tech center P3 border 2 border Dash or degree 300 rounded LG hover BG gray 100 and cursor pointer right save it let's have a look and you can see that little Dash outline and when we go over we get our little hover effect beautiful okay inside this label we're gonna need an icon the name is going to be majesticon Cloud upload size 40 color B3 B3 B1 Dave let's have a look beautiful under that a div with a Class mt4 Tech 17 and select video to upload under that div with the class Mt 1.5 text Gray 500 text 13 pixels and that says or drag and drop a file under that div with a class mt12 text Gray 400 and text SM MP4 then another div with class empty tool tax rate 400 and text 13 pixels up to 30 minutes another div with a class empty tool text great 400 and text 13 same as the top and then less than two gigabytes and the last little div we're going to class PX to py 1.5 mt8 text white text 15 pixels with 80 BG f02c56 unrounded SM and this is Select file right we save that we take a look look at that look how awesome that is man beautiful okay under this div we need an input and on this input we want to add a ref that is file the type is also file just add an ID of file input hidden and accept dot MP4 so that's the only file it accepts save that right if we click on this we can see now that that opens and it only gives us options for MP4 files awesome okay next bit so now we're gonna have to scroll up a sec and on this label quickly just add a VF and set this to false like that so it disappears and underneath this label we're going to add a div and we want to say VLS then we want to add a class there's quite a lot on this and that's going to look like that so MD mx0 MX Auto mt4 MD mb12 mb16 Flex item sender justify center with full Max width 260 pixels height 540 pixels P3 rounded to XL cursor pointer and relative let's just save that second have a look see if there's anything no we just got the height at the moment that's fine okay now inside this div we want to add a single div that is BG black height full and witful save that you should see a black background now yeah just like that perfect now we need an image and this is going to be our mobile case so the phone case and that is going to look like that so class absolute z20 pointer events none and the source is from assets images mobile case and if you remember you should have downloaded it before assets images mobile case so that's awesome now if we save this we should actually see it let's have a look yeah look at that look how awesome that is that is insane man okay let's continue underneath this image we want another image and that's going to look like that so class absolute right for bottom six z20 width 90 and this is The Tick Tock logo white save that take a look see that little Tick Tock logo at the bottom awesome and then underneath this image we need a video and that is going to look like that so we got autoplay Loop muted the class is absolute rounded XL object cover Z 10 p13px with full and height full and the source I've just hard coded as this Warrior MP4 from my public file so save that and then you get something that looks like that how awesome is that man look at it insane right let's continue underneath this video divot class it with absolute minus bottom 12 Flex item Center Justified between Z50 rounded XL border with full P2 and Border gray 300 and then inside this we have a little block of code in a div that looks like that so outer div is flex item Center and truncate and then we got an icon inside it with a name that is Clarity success standard line size 16 class Min width 16 pixels and then a div I've hard-coded video name for now and the class is text 11 pixels PL one truncate and text Ellipsis save that let's take a look you can see it at the bottom very good now we also need to add a button into this under this div we just added in so just space it up and add in button with class text 11 pixels ml2 font semi bold and just put inside change save that let's have a look see right there change looking awesome look at that wild man okay let's continue two divs down from the button so one two space it div it up and we're gonna add a class that is mt4 and mb6 then inside that divot class it with flex bgf8 f8 f8 and py4 and px6 then inside that a div with a little icon inside it glass mr4 size 20 and the name is MDI box cutter off let's save that have a look see it right there a little box cutter okay under that div we have another div that has a couple of things in it it's going to look like that so no class on the outer div and then the first div is text semi-volt x 15 pixels and NB 1.5 just put in there divide videos and edit the second class is exactly the same except we've got text Gray 400 and no margin and inside this the text if I put it on a new line you can see it all I'm just put in this you can quickly divide videos into multiple Parts remove redundant parts and turn landscape videos into portrait videos beautiful save it let's take a look you can see it right there looking awesome okay next under this outer divided with flex justify end Max width 130 pixels width for heightful tech center my auto and inside that we want a button that looks like that so the class px8 py 1.5 text white text 15 pixels BG f02c56 and rounded SM just put edit inside that let's save that take a lock button right there looks awesome okay from this button two divs down so one two divid and add a class that is mt5 and inside that divot class it with flex item Center justify between and then inside this we've got two divs that look like that so the top div is caption that mb1 text 15 pixels and the bottom is going to be how many characters we have in the input and the class for that is text Gray 400 and text 12 pixels let's save that let's take a look yeah you can see it right there caption and how many characters awesome okay underneath that div we need an input and for this we're going to add max length 150 the type is text and the class widthful border P 2.5 rounded MD and focus outline none let's save it let's have a look we can see it right there beautiful now under this div after the input make a space dividup class it with flex and GAP three and then inside this we want a button open this up and add a class that looks like that so px10 py 2.5 mt8 border Tech 16 pixels hover BG grew 100 and rounded SM for inside that just put discard and all we're going to do is take this button copy it and then paste it beneath change discard to post like that and we're going to change this hover BG grew 100 we're just going to replace that with two Styles text white and bgf02c56 save it let's take a look and there we go there's our discard and post button awesome look at that the page looks awesome man okay next because we're here we might as well do all of the upload functionality for this page so yeah let's make this page actually work okay so let's go from the top of the page to the bottom and we'll just go through it like that but first let's add in all the variables we need in our script so just under this we're going to add in this so file file display error caption file data errors and is uploaded like that right let's scroll at the top and the first thing we need to do is the label so this vif becomes if file display is empty let me save that we go back we can see now it's empty awesome and also we want a drag and drop event and how we do this is like that so at drop and put a dot prevent so that's like e prevent default we have on drop function and we have this drag over dot prevent with nothing in it because without it the drag functionality doesn't work so now let's go and make our on drop let's scroll at the bottom and we're going to say const undrop open the map first we're going to say error type value is null so whenever we redrop we clear the error type we want to set the file value to the actual file that we've dropped in and we also want to do this for file data like that and make sure we've got an e for event as a parameter next we want to get the extension of the file so let's say let extension and actually I think that's with an S extension I think and we're going to say file value name substring and then we're going to open that up and then inside this substring we're going to say file value name last index of and what this does it just gets what the extension is from the string after the dot and then we're going to check if the extension is not equal to MP4 we have an error type of file and then we return it so we just exit but if everything is fine we then want to create a URL out of that file add it into the file display.value ref which is there and then we can display it so if we save this and we go to the section where our video is this where it says SRC Warrior change that to that file display now save it and if we go into the browser and we click and we upload a file it should get displayed let's try it oh no sorry we need to drop it because it's on drop so if I just pull up downloads and then take an mp4 and drop it on yes look at that beautiful how awesome is that nice right next we'll do a function called on change and that is from our input so line 46 and just after ID I'll put at input on change and if we scroll down and just above on drop we're going to say const on change open him up and it's the same type of thing as before the file display is going to become a URL and we're going to reference this file which file is ref right there and if we scroll up we can see the input reference is called file so that's how we get that and then after this we're going to say file data is the actual file save that now if we click this and upload it should work let's click beautiful there we go so now we can drag and we can select awesome next we want to make this button work so if we've got things ready to upload we can just press discard and it'll clear everything so underneath on drop just add in a very simple function const discard and then we set all of these back to the original values and this caption if we copy that and we scroll up to the line 130 we're just going to add a v model and we're going to say caption right just to know this is working let's dump this out above so just put caption there save it and now let's type yeah captions working let's upload a file this will do and now if I press discard all of that should be cleared discard must not work it oh no I need to put an ad click event on the button so let's quickly go to the discard button and just format this quick and then we're going to say at click discard just like that beautiful right save that let's go back into this and now if I press discard it should all get cleared beautiful look at that okay next another very simple function to scroll to the bottom underneath discard this is going to be clear video and it's exactly what it sounds like we're clearing the video back to its default state which is nothing so copy that clear video scroll up to this button line 100 where it says change and just put at click clear video save that now let's upload a video this will do and if we press this change down here we should see it go back to the default state beautiful just like that very good also we want to check in our caption length so let's find where that is there line 128 let's get rid of this caption we've got there and this is very simple all we're going to do is caption dot length save that let's go in here and now if we start typing we should see this section increase yeah beautiful you can see it right there 37 awesome and now the last bit we need to go with our change button is where is that change right there where our clear video click event is and just above that when it says video name we replace that with file date the dot name save that let's go back in this select the file let's pick a long name this one and there we go awesome you can see the name of the file in there it's been truncated as well and if we press discard all of it goes away beautiful now at the very top of this file we are going to have a little component so make a space and this is going to be upload error and we're passing one prop which is error type of error type now let's open the side panel and go and make that string components new file upload error Dot View let's the base It Up Get rid of that style and this is very simple on this div add a class with 100 relative flex and justify Center inside that another div open this top up and add a class with absolute top six Z50 MX Auto BG black BG opacity 70 text white px14 py3 and rounded SM we're also going to have a dynamic class on this which is going to look like that so if the error type is not empty then this is visible else it's invisible and inside this div just add error okay awesome now in our script very simple we need to Define props and then pass it to refs and then we have a variable called error which by default is just an empty string and then we're going to have a watcher and in this we are going to watch the error type value and all we're going to do is we're going to say if error type is captioned the error is is this string so maximum 150 characters and then next else if is bio maximum characters is 80. else f is a file we say unsupported file use MP4 instead and then finally a last else error value is nothing awesome save it go back to upload save this page and I've scrolled at the bottom and just underneath this we're going to add another watch and we're going to be watching for the caption and this is super simple so if the caption length is greater than or equal to 150 and let me just pass caption as a parameter nice if caption is greater than or equal to 150 the error type is captioned and then we stop it or if it's not the error type is no save that now if you go back to our page and we just Chuck a load in this and when we get a 150 there we go maximum 150 characters and then we take one away goes away just like that beautiful awesome most of this page is done so next next we might as well move on to the profile page and actually wait a sec let me just check for the mobile view let's put this in the sender let's make this smaller yeah perfect okay roll in lovely okay yes working okay right profile page let's open the side panel and in Pages we need a new folder called profile and on this we need a new file and this is going to be like that so ID dot view now this is how next does it you don't have to um mess about with a router or anything like that it all automatically does it for you which is awesome so save that V base it up dial get rid of it and this page is pretty straightforward so first in our script let's just import main layout from layouts and then add that in let's just update this div to be a main layout save that a sec and then go back to the browser and say upload remove that we're gonna put profile forward slash one and there we go we got our main layout on our profile page already beautiful look at that okay awesome let's begin so div It Up Add a class with PT 90 pixels 2XL PL 185 pixels LG PL 160 pixels LG pr0 PR2 width calc 100 minus 90 pixels Max width 1 800 pixels and 2XL MX Auto next divided with flex width calc 100 view width minus 230 pixels now inside this we're gonna have an image and that's going to look like that so class max width 120 pixels rounded full and then again this dummy URL let's just save it take a quick look beautiful right there okay next under the image divot Placid with ml5 and widthful now inside this we want a div like that so it's got a class text 30 pixels font bold and truncate and for now I've just hard-coded username let's save it see it right there username beautiful and just under that we're gonna have another div like that so text 18 pixels truncate and then hard code username save it and looks like that beautiful okay under this div we got a little button Placid with flex item sender rounded MD py 1.5 PX 3.5 mt3 text 15 pixels font semi bolt border hover BG gray 100 inside this we've got an icon and a little div gonna look like that so the div has the text of edit profile inside it and the icon is class empty 0.5 mr1 the name of the icon is MDI pencil and the size is 18. let's save it let's have a quick Gander beautiful look at that very nice okay under that button we want another button and the class on this is almost the same just slightly different that's going to be Flex item sender rounded MD py115 px8 mt3 text 15 pixels text white font semi bold and bgf02c56 and inside this just put following now if you see save that you go back on the page you'll see that we have two buttons we don't want that so what we'll do for now for this class on the new line this button button is going to have a VLS and this top button is going to have a VF is that the true just for now right let's have a look yeah perfect and if we put that to false we see the other button just like that awesome all that back to True cool awesome next bit so two divs down from this button one two open him up David glass it with flex item Center pt4 and then inside this we've got a surrounding div with two spans inside it that looks like that so out of div mr4 and then this top span we've got font bold with 10K and then the bottom span text Gray 500 font like text 15 pixels and pl 1.5 and just for following in there now this is super simple copy it paste it change follow into followers and I don't put 10K to 44 something like that and then copy this again paste it beneath and then change this to 3K and change followers to like save it and there we go our little section is looking good next we got our little Bio Section very simple from this span go two divs down one two space it up and that's gonna look like that so inside I've just put this is the Bio Section and the class is pt4 mr4 text Gray 500 font like text 15 pixels PL 1.5 and Max width 500 pixels save it let's have a look there it is this is the Bio Section awesome right let's continue underneath this Bio Section divided with widthful flex item Center PT form border B then inside this we're going to div with a class with 60 tech center py2 Tech 17 pixels font semi bold border B2 and Border B black and inside that just for videos and then under that a div with an icon inside it class with 60 text Gray 500 tech center py2 text 17 pixels and font semi bold and this icon is material symbols lock open and dug a class on it as well of margin bottom 0.5 and liked right there awesome save it let's have a look cool you can see that coming in there beautiful right now we're gonna have to do a grid and a component so underneath this div dip it up again and class this with mt4 grid 2XL grid call 6 XL grid calls 5 LG grid calls 4 MD grid calls 3 and grid calls 2 and then a gap three so basically what this does if the screen is larger than 2XL you fit six columns in there and then if it's larger than XL five columns LG four medium three and the default is two so if we just make our little component you'll see better how this works when it's all up and running so inside this we're going to have a component called post user so let's open the side panel and in components new file post user dot view vbase it dial get rid of and let's go so let's add a class to this div it'll be relative brightness 90 hover brightness 1.1 and then cursor pointer now we also want a mouse enter and a mouse leave on this and we might as well put it in now because we're going to make the function in a minute anyway let's pull on this mouse enter is hover is true else if Mouse leaves hover is false and then inside that div it and open this up first We'll add a class of absolute Flex item sender just if I send a top zero left zero aspect three-fourths with full object cover rounded MD and BG black and just for now put V if and set that to true and inside this we want a little icon that's going to look like that so class we've got animate Spin and ml1 the name is Ming cute loading line size 100 and color white now if we save this and make sure we save our profile page as well save that let's go and have a look you can see we've got this little loading thing going on which is perfect very nice okay let's go back into post user.view right now we'll set this via too false so that goes away and under this div we'll add another div glass it with px1 then inside this another div with a class text Gray 700 text 15 pixels pt1 and break words so if there's any long words and overflow it just breaks it and inside this just put this is some text under that div it again add a class of flex item Center minus ml1 text Gray 600 font bold and text Xs and inside this very simple we've got two icons and in the center is just three percent but this first icon name is GG load bar sound and the second one is tableer alert Circle and let's save that let's take a look and we got that there and actually I forgot the video so let's put the video in underneath this icon with the animate spin go to the div and make a new div in the middle of that we're going to add in video open him up and we're gonna have to put on this we're gonna have a ref which is going to be video it'll be muted Loop IT classes aspect three fourths with an object cover and rounded MD and the source is the one that I've dropped in my public file warrior.mp4 save that let's go and have a look okay we need to start playing the video so let's do some functionality for that we scroll down to our script and we're going to add in Define props post we're not going to pass anything yet but it doesn't hurt to add it in now so we don't forget like that also now I'm going to bring in root and router from use root and use router we need two variables and that's going to be video and is loaded so remember this video ref is actually this so ref video now after this we're going to say on mounted so when we Mount this component we're going to say if video value so if it's not empty video.value dot add event listener loaded data and then open them up like that we're gonna have e for event and then just say if e Target open that up so if it exists we're gonna have a little set timeout of 200 milliseconds and we're gonna put is loaded to true and now if we scroll up to this the VF this false just change it to if it is not loaded so save that let's go and have a look let's refresh you can see now that we've got this loading like that okay cool let's continue now next what we want to do we want to have on before unmount and whenever we unmount this component we want to pause the video set the current time back to zero and put the SRC to nothing so let's just stop the video also we need to do our is hover go under that it's very simple we're just going to have onto this hover we're gonna have a ball pass to it if it's true play the video else pause let's save that and let's go and have a look right let's refresh this still loading like that why is that doing that okay there we go awesome I just hard reloaded so if you just press inspect and then right click empty cache and hard reload like that and then we hover awesome look at that now if we come off this video Mouse leave it stops so you can see the bright this goes up a little bit as well and then we come off and it stops that's stops starts stops beautiful and now just to see the grid working if we go back into our profile page so id.view and scroll at the bottom and we duplicate this quite a lot so let's do it like that loads of times save that you can see now we got loads and if we hover beautiful come off it let's just make this full screen yeah that is awesome man we're going to mobile view you can see no overflow still fits in the screen beautiful look at that amazing awesome man right then now that this page is done we might as well do the single post page right so let's jump back into our code and let's go in pages and we need a new folder I'm going to call this page and then new file and inside this the same as profile ID dot view vbase it get rid of style let's quickly jump back into our browser and do 4 forward slash post one and 404 not for oh because I've called it page yeah sorry that should be post so rename that to post and there we go we got a blank page perfect okay let's start so on this div we want ID post page and a class that is fixed LG Flex justify between Z50 top zero left zero with full height full BG black LG overflow hidden and overflow Auto Now inside that div class with LG width calc 100 minus 540 pixels height full and relative then inside that we're gonna have a next link with an icon inside it and that's gonna look like that so the class is absolute z20 M5 rounded full BG gray 700p 1.5 and hover BG gray 800 and the icon name is material symbols close color white and size 27. save that let's go and have a look there we go nice black background and a little close button at the top right by there beautiful okay under this next link we want a button and we want to class on this of absolute z20 right for top four Flex item Center just if I send a rounded fold BG gray 700 P 1.5 and hover BG gray 800. now inside this we've got an icon and that's going to be MDI Chevron app size 30 and color white and we also want to add an ad click event and a disabled like that so if loaded is false disable the button and we've got a click event as well that is Loop through posts up now we won't worry about that for now we'll sort that out when we've done all of our markup now next just take this button copy it Go below paste it change the add click function to down instead of up so Loop through posts down and one small change on this class is going to be top four becomes top 20 and the icon name becomes Chevron down like that well let's say save it let's take a look we can see it right there beautiful awesome and just so I don't get confused for later I take these two buttons copy it and do another div drop them inside and on this outer div put V if and for now just put it equal to true so it does show let's have a look yeah right there perfect because later on we'll base it on how many posts there actually are available so if there's more than one then we'll show the buttons else we don't okay awesome so one div down from this button so one make a space and we want an image under this so that's going to look like that we've got a class of absolute top 18 pixels left 70 pixels rounded full LG mx0 and MX Auto with 45 and the image is going to be Tick Tock logo small awesome save it let's have a look right there you can see it beautiful okay next we want a video tag under this image and that's going to look like that so for now put VF to true then we're going to class absolute object have a widthful my auto Z minus 1 and height screen and the source is the MP4 from the public folder let's save it let's have a look why can't we oh because the intro is dark so in this case let me get a different video let me go into public I'm just going to drop in another MP4 this atoms one put it in public and now if I go back to the post page and change Warrior for atoms save that let's take a look yeah you can see now that is the background awesome right under this video divot class it with flex item sender just if I send a BG black BG opacity 70 height screen LG Min width 480 pixels and again a VF that the true like that now inside this we want an icon and that's going to look like that so it's pretty much exactly the same as we've used before so the classes animate spin ml1 the name is mincute loading line size 100 and color white save it let's have a look you can see that loading now awesome right now under this div another one class it with BG black BG opacity 70 LG Min with 480 pixels and inside this we have another video and that's going to look like that so VF to true the ref is video Loop it mute it the class is height screen and MX Auto and the source is atoms save it let's have a look let's refresh the page oh actually no we haven't played it so on Mount we'll play it but we'll do that when we finish the marker so let's just continue okay from this end video tag two divs down one two open it up divot and then on this div add that so ID is called info section A vif set to true and then a class LG Max width 550 pixels relative widthful heightful and BG white you could see it already down the side looking awesome and then inside this just a single div with a bit of padding so class cy7 then under that div last with flex item sender justify between a px8 inside that divot classic Flex item Center and then inside this div we're gonna have a next link with an image inside it and that's going to look like that so the href just at the base URL right now the image has got a class rounded full LG mx0 and MX Auto with 40 and the source is the dummy URL let's save that let's have a look see it right there the little image awesome okay under this next link divot classic with ml3 PT 0.5 and then in that a div with a Class Tech 17 pixels font semi bold and inside just by username next another div class it with text 13 pixels minus mt5 and font light and then for this bit just put username then we've got a span with a dot in it and that's going to look like that so full stop period and the class is relative minus top two pixels hex 30 pixels and PR 0.5 and then another span underneath it's going to look like that we got font medium and just put date here save that let's have a look beautiful look at that awesome okay now from this span three divs down one two three make a space and we're gonna have an icon in here and that's gonna look like that so A VF set to True a click which is a delete post class cursor pointer the name is material symbols delete outline sharp and the size is 25. save it you can see it right there a little bin beautiful okay now under this so one div after so this one we're gonna add another div like that so class px8 mt4 and text SM and just put in this is the post text save it there we go there's the post text okay under this div another one that's going to look like that so class px8 mt4 text SM and font bold we've got an icon inside it which is MDI music and the size is 17 and just put original sound username save it and there you go you can see it right there beautiful okay under this div it up again lasted with flex item sender px8 and 28 again divot class with pb4 text sender flex and item Center and then inside this we've got a little button we're going to clash that with rounded full BG gray 200 P2 and cursor pointer and inside this we just want a little icon that's going to look like that so size 25 and the name is MDI heart beautiful there it is right there now under this button a little span gonna look like that so class text XS pl2 pr4 text Gray 800 and font semi bold save it got it right there 123. now what we can do with this this div that is surrounding the span and the button copy it paste it beneath and everything exactly the same except the name which is going to be BX bxs message rounded dots save that and there it is you can see it right there and this isn't actually going to be active so just change the button to a div just like that awesome right next the comment section for so from this span intuitives down one two space It Up divot for an ID in a class that looks like that so the ideas comments and the class BG f8f8f8 zero widthful height calc one hundred percent minus 273 pixels bought a T2 and overflow Auto and now you can see we got this little border at the top and this little section then inside this add a single div that is class pt2 now under that we want a div that looks like that so VF is true just for now and the Class Tech Center mt6 text XL and text Gray 500 just put no comments inside that and if we save it we can see there no comments awesome now under this div we're going to have another divot open it and add them to the top this so we've got a VLS and class Flex item sender justify between px8 and mt4 now inside this div another Placid with flex item Center relative and with full now inside this div we have a nux link with an image inside it and that's going to look like that so the next link is going back to the default for now and the image has got a class of absolute top zero rounded full LG mx0 and MX Auto with 40 and the source is the default URL again save it and we can't actually see anything because we need to change this VF to false because we have on this the VLS so if this is false this section will show so now if we save that we'll see that instead awesome right under this next link div it and class it with ml14 PT 0.5 and with full then inside this div class with text 18 pixels font semi bold Flex item Center and justify between now here just put user name and under that we're going to have an icon that's going to look like that so put a VF to true for now and at click which is going to be delete comment last cursor pointer the name is material symbols delete outline sharp and the size is 25 save it you can see that right there awesome right one div down from the Icon just inside yeah another div that's going to look like that so all this text is just Laura mipsum so you can put in whatever you want and the class is text 15 pixels and font light if I save that you can see now this little comment awesome okay last little section which is going to be the create comment box and we might as well bring this over a bit because my face will be in the way otherwise bring that up actually I could just do that yeah that'll do and before I forget four divs down from this comment so one two three four just add a single div with a class of mb28 awesome right one div down from that so they make a space divid up and open the top for this we're going to add an ID of create comment VF said the true and a class is going to be absolute Flex item sender justify between bottom zero BG white height 85 pixels LG Max width 550 pixels with full py5 px8 and Border T2 save it and you can see there that's coming in at the bottom awesome right inside that divot and open this top bit up because we're going to add a class and a dynamic class and that's going to look like that so input focused we have made that let's just quickly add that in just slap in input Focus which is a ref that is false so if that is true we got a border two and Border gray 400 else a border 2 and Border F1 F1 F2 and then the normal class is BG F1 F1 F2 Flex item Center rounded LG with full and LG Max width 420 pixels save it and you can see this little line over there we need to put an input in it so let's do that so if we add in the input that is going to look like that so we've got a v model which is comment and we might as well add that in because it's right there so just add that in as a ref of null the focus is inputs Focus to true and when it's blur input focus is false the class BG F1 F1 F2 takes 14 pixels Focus outline none with full LG Max with 420 pixels P2 and rounded LG the type is text and the placeholder is ADD comment save it and you can see it right there look at that so when we click the Border comes when we click out goes away awesome right finally under this input go one div down and we just have a little button that looks like that so if the comment is null disable it at click add the comment and then this Dynamic class if there is a comment we want this button to be text fo2c56 and cursor pointer else we wanted text Gray 400 and the default class is font Samuel text SM ml5 and pr1 and inside this button just put post save it and you can see there we got the word post so now if we fill this up that changes to red and if we take it away it goes back to gray awesome okay let's add some of our script stuff in now so we basically have less work to do later so what we're going to add at the top is use root and use router and let's add in two more variables so we want video and is loaded next we're going to have an on mounted and in this we're pretty much going to have exactly the same as we did in the profile so no sorry it was in the post user component yeah so this section the event listener so copy that go back to the post page and just drop that in and I'm going to put this to 500 just to give it a bit of time to think and let's go back in our profile page uh let's go back on that post user component we also need the on before on Mount copy that go back to the post page underneath paste that in now underneath this we're gonna have a watch and we are going to watch the is loaded value so very simple if is loaded value is true play the video awesome and now what we can do if we scroll to the top and we go all these is loaded let's just find the bits we need to add it in so this line 44 we can change that to if it's not loaded let's save that now let's go and have a look and our video is playing awesome let me just make this bigger okay awesome I didn't know actually just for now take this video value in the mountain just comment that out a sec and this video.value.play added into the unmounded like that because we're not actually loading anything from a database yet so we don't really need to check anything let's just have a look refresh and it's loading oh actually take this is loaded value and just set it to True save that and there we go so we can refresh this and it'll load up just like that beautiful let's make it wide awesome look at that man and then if you make this smaller we should go into mobile view yeah let's have a scroll beautiful look at that awesome right the rest of it we can pretty much just leave until we actually have data coming through from the back end so this page is done so now let's go back to the main page this and let's do our login and register page so the authentication overlay so let's go back in the code over the side panel in components and new file auth overlay Dot View vbase setup get rid of this style close the side panel and let's start this div open the top up and we're going to have an ID in a class it's going to look like that so ID auth overlay and the class is fixed Flex item sender justify sender Z50 top zero left zero with full height full BG black and BG opacity 50. now inside that we got a div gonna class it up with relative BG white with full Max width 470 pixels height 70 D4 and rounded LG now inside that divot class it with widthful flex and justify end now inside this we're going to have a button and that's going to look like that so class P 1.5 rounded full and BG crew 100 and then we got an icon that's size 26 and the name is MDI close let's save that a sec and this auth overlay we need to go into the main app.view and under this next page we're going to bring in auth overlay close that off save it and there you can see our overlay awesome let's continue back in North overlay.view one div down from this button so one make a space divot and class it with absolute Flex item sender justify Center py5 left zero bottom zero border T and width full and then inside this we need a little span with a class text 14 pixels text Gray 600 and then just say don't have an account now just under this span we're gonna have a little button and that's going to look like that so we've got a click where is register is equal to not is register we're going to make that now actually I mean the script is right there let's just put it in so register is a ref equal to True by default and then on this button we've got a class text 14 pixels text fo2c56 font semibold and pl one now just if is register is true sign up else login cool save that let's go and have a look you can see right on the bottom keep going like that sign up log in sign up log in awesome right now we need another component to go on the side panel on components say new file this is going to be login.view vbase it get rid of the style tags and this div video get rid of that and replace it with a div with class text sender text 28 pixels md4 and font bold just say login then under that another div with a class of px6 PB 1.5 and text 15 pixels put email address for there now underneath divot placit with px6 and pb2 and inside this we want another component for a text input and that is going to look like that so we have text input and then the placeholder which is email address in this case the V model with an input I'll show you how that works in a minute also an input type this is a prop autofocus is also a prop error is a prop as well so now let's open the side panel component new file text input Dot View vbase and then get rid of this style file and this is pretty straightforward so inside this div let's have an input and we're going to add a class to this and that's going to be block widthful BG F1 F1 F2 text grade Android border border Greek 300 rounded MD py 2.5 PX3 and focus outline none we also want a ID which is going to be input placeholder that's going to be a prop and just get rid of this type for now next a placeholder which the placeholder is a prop again now underneath this class We'll add a type and that's going to be input type the V model on this is going to be input computed autocomplete is going to be off and then max length is Max right so maybe if so we can see what we're doing let's just go to this login save it a sec and go to the auth overlay and just in the middle after this button after the div let's bring in login like that save it let's have a look and we can start to see it like that beautiful let's go back to text input now also under this input we're going to have a plan that looks like that so VF error show it and the class is text red 500 text 14 of font semibold and display the error inside the span now in our script we want to emit this is where we're updating the input and if you remember if we go and log in this the input this V model right now there's quite a few props on this so that's going to look like that so Define props you've got input placeholder input type Max autofocus and error and the same for the two refs now under this we're going to say on mounted open him up and inside this very simple if auto focus value is set to true so this auto focus being passed into prop get the input and focus it awesome now finally our little computed and that's going to look like that so we have a get and a set so we're getting the input value which is being passed in this as a prop input and if we go back to login this V model input is the email and then this input computed is in this V model here which is the input and then once it changes you set the value to be emitted out so you update input and that is what comes out right there so you get the updated value for this text input awesome and that is that component done save that and it's going to have a look refresh very nice now just to show you on this login if I put an error this is an error save that you can see a little error message underneath but we don't need that for now just remove it and underneath this diff we have another one with a text input that's going to look like that so the class is the same as the top we got placeholder password viewmodel input is password and the input type is password awesome no underneath that div another which is going to look like that glass px6 text 12 pixels text Gray 600 and forgot password now underneath that divot class it with pxx pb2 and MP6 and then inside there's we got a little button with a few things on it and that is going to look like that so if there's no email or no password disable the button the class if there's no email or no password BG gray 200 or bgf02c56 we're gonna add click event which is login and then the class with full text 17 pixels font semi bolt x y py3 and rounded SM and inside the button just say login and that is it for the markup let's just add the stuff into our script so in this we need three variables email password and errors and we're just going to leave it like that for now because this login function will come and make later when we actually have a back end to be able to log into so save that let's go and have a look look at that beautiful so if I type there nothing type there nothing but if I put both in then the login button gets activated and if I press this sign up oh we haven't for any functionality on those components yet so let's go back to auth Overlay and this login we want to add on to this a VF is registered and the next one is going to be registered with a VL so if I save that and then go in this and I press sign up you can see that we toggle back and for the components awesome right so now let's go and make this register component and I might as well just pull this over there like that so we can actually see something probably a good idea and honestly to make life easy I'm going to take this login component so let's open the side panel log in I'm going to duplicate it call it register.view close that side panel and all I'm going to do is change a couple of things so this email address section get rid of that this login becomes sign up this placeholder becomes full name email becomes name input type is text autofocus true and errors we don't need that yet right now this text input is going to become this so placeholder email address input is email input type email errors nothing the next one under this make a space under the div going to be very similar that's going to look like that so the div on the outside is the same we got password password and nothing and then the next one is similar to that it's going to look like that so this time it's just a confirm password section so we've got confirm password confirm password password and nothing and then this forgot password section just leave that let's just give that a save a sec let's see what's happening refresh and let's go to the register page can't see anything yet it's okay let's just continue finish this up okay now this disabled section in the button is going to become that so name email password confirm password exactly the same for this Dynamic class name email password and confirm password login becomes register and login becomes sign up and also we need to change these variables at the bottom so just replace them with name email password confirm password and errors now save that and let's go sign up we can't see anything why what have I done let me just open this and inspect see if I've broken something console if this is a negative custom element maybe just hard refresh ah what is going on let me just move something in there save it and then put it back save that see if it updates it yeah there we go okay awesome so log in and sign up and sign up now let's just put in some stuff awesome and there we go sign up beautiful close that and there's our login and sign up page awesome right that is all the front-end stuff done well I mean most of the markup for the front end anyway so at this point we can move on to creating our API so we might as well start with the login stuff oh no actually why don't we set up all of our opinion stores first yeah let's do that first we'll do the Pina stores because there's also um some plugins that I need to set up as well so yeah next let's do the pinia stuff right let's jump back into our code and open the side panel we now need to make a folder called stores and we'll start off with a new file and we're going to call this one user.js like that and just to make this easy for ourselves let's go and do the browser and we're going to go search for pina pina.viewjs.org what's this let's go to guide and let's scroll down this section this will do we'll take this copy that go back and paste that in and at the top just above export we also need to Define store so import Define store from pinia now let's just modify this slightly change counter to user this kind of the user this state just empty this out a sec get us get rid of it and everything in actions just get rid of like that now inside State we're going to have all things which is going to be ID name bio and image and for now that should be good just save that next we're gonna duplicate this user.js duplicate rename it to profile.js and our inside profile let's just update what we need though so user store becomes profile store and the same this user becomes profile and we need three extra things in our state and that is going to be post posts and all like save that right now one more take this profile.js duplicate it and call it general.js so a general store and all of this stuff in the state we're going to remove and we're gonna add in this so is login open is edit profile open selected post IDs is back URL posts and suggested and actually I did forget one at the bottom that is following like that and let's just take this profile store and update it to General profile becomes General and that is it for now save that awesome and we've already brought in Pina and pin your plugin persisted State we can see this if you go into the next config we brought it in right there when we set up this project okay right next what we're going to do do is we'll make some plugins because what I've done so we don't need to import all of these stores all the time I've put them in a plug-in so then all we have to do is say use next app and then take whatever store it is we need it saves time from importing all the time into every component so close this stores and let's make a new folder called plugins like that now inside plugins new file we're going to say stores.js and this is very simple we're going to import all our stores which is going to look like that so use a store profile store and general store and then we need to export default Define next plugin let's open him up and I'll just check in this next app and all we're going to do is say return open an object inside this we want to say provide make that an object and very simple this is going to look like that so now in our pages and components all we have to do instead of import in the store and then converting it to refs and all that type of stuff all we have to do is say can't use a store equals use next app and that is all we have to do then we can use this store everywhere awesome man but now let's just get rid of that so this store is done and we're going to make another one so let's duplicate this stores.js and this one is going to be axios and this is also very simple remove these stores and at the top import axios from axios everything inside provide remove it and first what we want to do is before we use axios we need to add with credentials because we're using laravel sanctum stateful we want to add in the credentials with each request and that is how you do that and then secondly I'm just going to set our base URL and in my case it's going to be localhost 8000. you change this to whatever Port you're on and then inside provide we just say axios is axios save it and there is our axios plugin awesome right so I'll give you a quick demo of how this works so if we go into app.view and you can see we have our auth overlay and that is just constantly showing so if you go back to the browser get rid of this and you can see it's always there we click close it doesn't go away so what we can do is now if we add a script with a setup and we are going to import store the refs from pinia and then we're going to say const General Store equals use next app we now have access to this General store and then under this just convert some of these stores to refs like this so we go the General Store we put it to refs and then we get out of it is login open and if we go back into doors General we go there is login open that is by default false go back into app.view and all we're going to do on this is say V if is login open and because that's false now this is going to disappear so save it that has gone away amazing and if we want to open that let's jump into our components go into top Nav Now in our script let's add in our use next app with user store and General Store now we're going to scroll up a bit to this section line 33 where it says VF false we're going to change that with user store ID and if that is a negative like a null or empty then we're going to show it because that is the login now if we save that and you can see we get everything so we just need to make some more modifications this button right beneath let's just put all this on a new line and let's do a click event and we're going to add in general store is login open is equal to True when we click that save that and just below this section on this div we're going to add V else like that so if we save that you can see now what we've got we've just got upload and log in so if you press it you can see that opens and then and then now we have to close it so next we have to go to the login component so login.view and this is no sorry in the um author overlay.view yeah that's the one there's the button and we're going to add the same thing onto this button just put it all on a new line and this paste it on so it looks like that save it and we also need to bring that in so in our script just above can't General Store equals use next app save it now if we click this it should disappear beautiful so log in log out so log in and then close it just like that beautiful and now what we're also going to do is because we need to persist the state so let's go in our side panel and in all of our stores general.js go to the bottom and under actions we're going to say persist is true and we're going to do this for all of them because this persists the state and how it does this is it uses this package that we installed this pina plug-in persisted state that one so next let's go to profile under actions persist is true and then user assist to True save it and there we go let's see can reach the login yeah all work and still awesome and actually I did forget one section which is the uh edit profile section that has the image Cropper and we can edit information in it so we'll have to finish that first and then we can move on to the back end so let's do the edit profile overlay we can that by going into app.view and if we duplicate this and rename this to edit profile overlay and inside our general store we've got is edit profile open we can just take this copy it paste it into there and now let's go into components and make a new file edit profile overlay dot view vbase it up this style get rid of that and right let's go right in this top div open the top section and we're going to add an ID and a class and that's going to look like that so ID edit profile overlay and the class is fixed Flex just if I send a pt14 mdp 105 pixels Z50 top zero left zero with full hype full BG black BG opacity 50 and overflow Auto and I saved that and we can't see anything oh because in our app.view yeah we've got this VF just take that off for now remove that save it and you can see we've got that overlay now it's gone darker awesome and let's just open this a little bit right okay cool let's continue in edit profile overlay next inside this div another one open this top section up we're gonna have a class that is relative BG white width for Max with 700 pixels SM height 580 pixels height 655 pixels MX3 P4 rounded LG and mb10 we're also going to have a dynamic class on this and that's going to look like that so if uploaded image is now height 655 pixels else the height is 580 pixels and let's just add in uploaded image ref is null and if we save it there we go we can see that starting to come in now and if we open this change its position like that awesome them okay next inside this div another classic with absolute Flex item Center just about between widthful P5 left zero top zero border B and Border B grade 300 see that border at the top right there now inside this div we have another with edit profile inside the class is text 22 pixels and font medium looks like that and under this we have a button that's going to look like that so we've got an app click event which is our general store and this is how we close this edit profile overlay so edit profile open is equal to false and the icon is MDI close save that and we need to import this General Store so let's just go down here and we're going to say const General Store equals use next app save it cool let's continue next underneath this div block we have another div add a class with height count 500 pixels minus 200 pixels and also we want a dynamic class and that's going to look like that so same again if uploaded image doesn't exist mt16 else mt58 pixels now inside this div add a little VF say if uploaded image is empty and then again divot open this topic we got an ID in a class and that looks like that so profile photo section and the class Flex Flex call border B SMH 118 pixels height 145 pixels PX 1.5 py2 and widthful next inside this we have a div like that so this is going to be profile photo and the class is font semi bolt text 15 pixels SM mb0 mb1 text Gray 700 SM width 160 pixels SM text left and text Center save it you can see we've got a little border bottom and our profile photo right there now under this div slap another one in glass it with flex item sender adjuster by sender an SM minus mt6 now inside this we need a little label the four is going to be image and let's open this up a bit and the class is going to be relative live and cursor pointer now inside this label we're going to have a little image and that's going to look like that so class rounded fall width 95 and the source is just this dummy picture again save it we can see it right there looking beautiful right under this image a div with an icon in it and that's going to look like that so class absolute bottoms your right zero rounded fold BG white shadow XL border P1 border degree 300 inline block and width 32 pixels and the icon name is pH pencil simple line bold size 17 class minus mt1 and ml 0.5 save it and you can see right there we got our little rounded background with our icon inside it awesome and under this label we're going to add our input and that is going to look like that so class hidden type file ID image and that needs to be the same as the four so that is image as well the input get uploaded image we haven't made that function we'll make that in a minute and this only accepts a PNG a JPEG and a a JPEG Dave it now if we click this we should open some options let's click it beautiful just like that awesome we know that's working close that okay next two divs down from the input so one two space it David open this top section and add in ID username section and the class is flex Flex call border B SMH 118 pixels PX 1.5 py2 Mt 1.5 and widthful inside that divot with a class of font semi bold text 15 pixels SM mb0 mb1 tax grade 700 SM width 160 pixels SM text left and text Center just put in this username save that we can see username right there and actually just to show you if we open this it changes to desktop view just like that you can see awesome cool right underneath username div blast it with flex item sender justify sender an SM minus mt6 then another div blast it with SM width 60 which full and MX width MD and for this we're going to use our text input component it's very simple it's going to look like that so placeholder username V model input is username input type is text and the max is 30. let's have a look beautiful look at that and all of these things like username and I know we got uploaded image down there when we finish the markup we'll put all those in the script later right underneath this text input we just have a little div with some text and that's going to look like that the class text 11 pixels text Gray 500 mt4 and the text says usernames can only contain letters numbers underscores and periods changing your username will also change your profile link I just I took that from The Tick Tock site save it and you can see that right there awesome next section from this div let's go three down so one two three make a space divot open this top section and add an ID in a class that looks like that so this is the Bio Section and the class is flex Flex call SMH 120 pixels px1 0.5 py2 empty tune with fall inside that divot like this inside we've got bio and the class is on semibold text 15 pixels SM mb0 mb1 text Gray 700 SM with 160 pixels SM text left and text Center under this bio div class it with flex item sender justify Center and SM minus mt6 inside that another div flash it with SM width 60 width full and Max width MD Now inside this we have a little text area and let's just get rid of all this for now open this up and I'm gonna add calls 30 rows for v-model is user bio and max length is 80. we're also going to add a class and that is going to look like that so resize none with full BG F1 F1 F2 text Gray 800 border border gray 300 rounded MD py 2.5 PX3 and focus outline none let's save it have a look look at that beautiful and just under this text area we want to add a div that looks like that so if user bio is not empty display it and the class is text 11 pixels text Gray 500 and we can have user bio.length so again we don't have that in there yet but we'll just finish all the markup and then we'll figure all that out later save it now from this user bio Dave we're going to go down four so one two three four open it and we are going to add in this so a div with a VLS class widthful and height 430 pixels and this is our Cropper component and actually we need to import now with npm because I forgot at the beginning so open a terminal and all we're going to do is say npm I view Advanced Cropper enter awesome that is installed and now we actually have to bring that in so how we do that is very simple just at the top of the script we're gonna have two Imports and that's going to look like that we've got from view Advanced Cropper the circle stencil and Cropper and import the styles.css from Advanced Cropper and also while we're here we might as well import all of our variables and that's going to look like that so we've got file Cropper uploaded image user image username user bio and is updated save that and so we can actually test if this Cropper Works we're going to add a little function in we're going to say const get uploaded image open him up add an e for event and this get uploaded image is coming from there our hidden input on line 41. let's just go back down and this is kind of the same process as the video upload it's kind of the same thing so I'm going to get e.target.files zero index assign that to file.value and then convert that into a URL so we can read it so save that and now let's just open this up a little bit if we click this image and we choose a file that is a PNG let's try Netflix let's open oh look at that awesome and there is our Cropper look how awesome that is Works beautiful right let's refresh and now we know that works let's continue okay so next after this Cropper let's go two dips down one two base it and div it open this top section and we're gonna add an ID of button section and a class is absolute P5 left zero bottom zero border T border T great 300 and wet fall inside that divot open the top section and add in that so ID update info buttons a VF if uploaded image doesn't exist then show this section and we've got a class Flex item sender and justify end so the buttons go this side right inside that let's add a little button open this top section up and first we're going to add a class and that's going to look like that so Flex item sender border rounded SM PX3 py6 pixels and hover BG gray 100 and then we're gonna add click event on this and that is going to look like that so General Store is edit profile open equal to 5 also this is the cancel button and then inside this button a little span with cancel inside it and the class is px2 font medium and text 15 pixels right let's save that and let's take a look that looks good but my face is in the way so if I move that over you can see it right there beautiful I'm not going to click this yet because it's not going to work let's just leave that by there for now and let's just do one more button this is the final one so button open that top section we're gonna have a class that looks like that so Flex item sender bgf02c56 text wide border rounded MD ml3 EX3 a py6 pixels also this button we're gonna have an at click event and that is going to be crop and update image function and again inside this button a little span with class mx4 font medium and text 15 and just put apply right save that let's take a look awesome look how beautiful that is right let's do all the functionality that we need to in there so if I just move this back over here and we go into our script section and if we bring in most of the stuff we need though so first let's say import store the refs from pinia and this use next app we're going to get all of the stores so like that the user store the general store and the profile store and then we're going to convert the user store to refs and get the name Bion image like that and then we're going to say on mounted so when we spin this component up we want to assign name to username bio to user bio and image to user image so these three refs right here now all of the upload functions and the crop function we might as well not do it now we'll just do two watch functions so we'll do watch open that up in this put username.value and then open this build up and this is very simple so this watch when the username value changes we want to watch if there's no username or the username is equal equal to the username so it hasn't been changed or it's reverted back to the original is updated is false else is updated is true and we're going to do exactly the same with bio so we can take this watch copy and paste it below username becomes user bio copy that name there username is bio username is bio this name becomes bio and actually no this we don't need we're actually checking for length so length less than one false else true awesome right save it and we should be good for now this this should be enough for the moment now that is actually all of the front end Styles done so we can actually move on to the back end now let's um quickly jump into app.view and just put this back on this if is any profile open put that back on and now we can see that that is disappeared so if we go to Old slash profile forward slash one awesome and then we click edit profile we need the hook that up so let's go into the side panel and look for Pages profile let's go in that and let's scroll up what is it edit profile right there and this is very simple all we're going to do is add on to this and that click like that that is General Store is edit profile open is equal to true now we need to import that so let's go to the bottom and let's just say const General Store equals use next app save it now let's go back to this browser page and we press edit profile and it opens up beautiful just like that can we close it yes look at that beautiful edit close that work in like a dream beautiful right so now we can set up our back end to our API so let's open up a terminal and I'm going to keep this in my sites folder so CD sites and depending on how you've set your machine up if you're using Zam you're going to do this in htdocs folder I think but if you're using valet you would have packed a folder so then you would do it in that folder that you've setup so anyway where am I actually inside LS oh no it's a lowercase C so CD sites okay now I'm inside so because I have the larval installer I'm gonna say laravel new tick tock clone API and if you don't have the laravel installer you're gonna have to do this with composer and you go to laravel.com go to documentation and then installation scroll down and there it is you can see it right there composer create project laravel forward slash laravel example app and you would change example app for tick tock hyphen clone hyphen API awesome right you're gonna press enter cool that is installed let me just clear this out okay right now let's see the end of that file so Tick Tock clone API it's just LS yeah perfect next we want to install laravel breeze so we would use this command composer require laravel forward slash Breeze let me just make this a bit bigger hyphen hyphen Dev and uh awesome then me just clear that and now finally we want to install our package so we do that with PHP Artisan Breeze colon install so we press enter which stack would you like to install we are going to choose number three which is API so three would you like to install Dark mode support no I would not HP unit nope okay Breeze scaffolding installed successfully awesome right and all I'm going to do now is say PHP Artisan serve enter and we are on Port localhost awesome right minimize this and now I'm going to open a new window in vs code let's bring that up like that let's go into the sites folder or wherever you've saved it tick tock clone API I'm going to drag that in and drop it and there is our laravel API awesome okay and if we want to test that this is actually working open a browser and go localhost 8000 and there we go localhost 8000 laravel 10.3.3 very nice okay right let's go into our DOT end file and let's take a look this database Tick Tock underscore clone underscore API is perfect all my credentials are perfect as well because I have no password on it or anything and now what we can do is HP Addison migrate just for now so we can test it because later on we're gonna update the user migration and add a load more stuff into it but for now this will be fine so PHP ads are migrate nothing to migrate oh it's probably because I already have a database called this because I mean I pre-built the project for this video so I'm just going to put on the end of this API 2 just so it's different and we get a new database so I'll save that and then I'll PHP address and migrate again okay now it says the database Tick Tock clone API does not exist would you like to create that yes I would enter okay that has been migrated let's open SQL Pro that is the database I'm using uh let's choose the database there it is Tick Tock clone API 2 and there is all our migrations users awesome right the next thing I'm going to do is just create a user so when we get to the point of trying to log in we can actually test it with a user in the database so go back to this terminal clear it out and say PHP Artisan Tinker enter and now I want to create a user and how to do this is like this so because Lana Valley comes bundled with the user model and we can see here if we go in app models we have a user.php and if we also go into our migrations this first table is create user table and we can see and now we've got name email and password so what I'm going to do is say user create the name is going to be John week's Dev you put in whatever your name is email John m.com and password bcrypt and then one two three one two three one two three like that so we're making a name right there and email and a password let's press enter and there we go a user has been created let's just go into our SQL Pro refresh and there is a user awesome and this little Tinker I'm just gonna exit and clear that out and close this migration right now we're going to set up laravel sanctum so if you go on our side panel let's close our list now and it's going through app HTTP controllers and we have author already so we've got our register our register and login stuff and all that when we installed laravel breeze so that's fine and laravel sanctum is already installed in a laravel application so you don't need to install anything so the first thing we're going to do is close app go into config and go to cores.php and you can see there we go paths and it's all and I do actually like to change this to be a bit more specific so I'm going to take that out open this and we're going to add in this so API all the login and point the register endpoint log out endpoint and the sanctum crossout request forgery cookie so save that and we have to scroll to the bottom support credentials is actually true so make sure that it is true awesome and actually just to help out a bit I'm going to put the sanctum documentation on the screen so we can go through it just so I don't forget anything okay right so now we need to go into app HTTP kernel.php so let's open the side panel and app HTTP kernel.php and what is this API let's scroll down to API and that's actually already set up fine let's actually scroll up and find Spa authentication right there so configuration yeah same place okay and this we did earlier with axios we added with credentials equals to true in that plugin that we created the axios one and now we need to set our domain and I have done this like let's open the end file let's scroll down and under session lifetime we're going to put in session domain is localhost so this is for the back end and this one sanctum stateful domains localhost Port 3000 that is the front end and we also can't forget the session driver needs to be cookie like that so save that and now that should be sanctum ready so if we jump back into the front end and go to componentslogin.view and we scroll to the bottom we've already got this button with a Clicks in login so what we're going to do is say can't log in open that up and then we're gonna import axios from use next app because remember it's a plugin and make sure this login is async and now the first thing we're going to do well let's put it in a try catch just in case we have any errors because we want to see what they are like that so the first thing we're going to do is get the cross state request forgery token the cookie then after that we're going to log in so axis post login and my email that's I put into the database was John m.com and the password was one two three one two three one two three if you remember let's go to the database there's John m.com and the password has been hashed but it was one two three one three one two three and then finally we're going to say user and we want to get the result and dump it out in the console so we can see that it's actually working right so let's give this a try let's go back to our browser and let's open this inspect and I'm going to go into this application and storage I'm going to clear site data so clear everything out of it and then click here and empty cache and hard reload okay now let's go into console no actually let's go into Network okay and make sure it's on fetch forward slash xhr and just clear this out for now and I'm going to go into login and this login button is deactivated let's just take off the disable and class so I'll just copy this remove it and just put it above and comment it out like that save and I'm just going to take this custom color and put it onto this class save it so we can see the button so now when we try and log in let's see if this works so let's Press login oh 200 let's have a look look out there it is right there awesome we just logged in successfully very nice and we can check this by going into application cookies and then this localhost 3000 and you can see there lateral session crossover request forgery cookie we got them all there beautiful look at all those very nice that is working perfectly and if you go in console you can see our data right there data email email John at m.com name John week's Dev awesome so now just a quick warning so if you try and log in again know that that has been successful let's just go in the network you're gonna get an error so let's try it again login yeah you'll get this Arrow because you're already logged in so it'll it'll throw an error so what you do is go back into application storage clear site data and then empty cash and hard reload and then if you go into cookies again localhost there's nothing in there let's try log in again login beautiful look at that let's go back to console yes it's definitely working and if we just jump back into the back end and we go into root API that is where we're getting our user so we can see all sanctum we need to be logged in to be able to get to this user so get user and then once we've entered we return the logged in user awesome man right now we know that that works in our Pina store we can make all of our functions the login register and log out and also do whatever we need to do on the back end for all the registration stuff so we'll make an end points and all that and we also need to use axios interceptors to figure out when the session has expired our front end the axios Interceptor intercepts the error so if it's like a 500 error or I think it's a 4 a 419 or 429 or something like that I'll show you when we do it but so it intercepts the error it then automatically logs us out because we've been logged out on the back end so that is why I used axios because we have the axios interceptors anyway awesome yeah so next let's do all the stuff that is required for the login registration and logout right let's clear this so let's go into application storage and just clear site data clear all that out and go to console just refresh and now back in our front end let's revert all of this let's let's put this back to where it was like so let's just open this right up save that like that for a sec let's open the side panel and go into stores user.js and I'm going to close the rest of it because all these other ones we don't need right now all we have left is user.js and login so I'm going to make this split left like that so we got the store the user store on this side and the login page on this side right first function in actions is going to be get tokens and we also can't forget we need to import axios into this store so under this just import axios from plugins axios and then to get it we say const axios equals axios provider Axia save that right in login.view we want to say this use next app get rid of axios and import user store and General Store next we want to put in this the errors dot value equal to null so anytime there is an error and next time we make a request we clear it and then if I just make a space and I drop this in this is what we need to do from the user store we need to get the tokens login in and then get the user and after all that close the login page so now in our actions next function is going to be login and that's going to be like that so you can see we've got email and password we're passing that as parameters so email and password axios post to the login with email and password and then finally we have get user right there so after login we want get user like that and we're taking the result and we're storing it in the state so ID name bio image ID name bio image awesome okay so now we can get rid of this in there so all we have is that get rid of this console as well and actually this API user I'm going to rename to logged in user like that so save that right now we jump back into the back end code so our API and we're going to make some modifications to this so This get user we're going to change get to group get rid of user just have the function and this request we can also get rid of that and this return get rid of it now it's say this we're going to have root get logged in user from the user controller and the function is going to be called logged in user so let's open a terminal and say PHP artisan make controller and we're going to call this API forward slash user controller hyphen hyphen resource like that so let's press enter go on the side panel and then we can see in controllers API usercontroller.php awesome and this is going to be very simple just take this index rename it to logged in user and how we're going to do this is say try catch exception and then all we want to do is return the exception if there is an exception with a 400 at the end and now first we want to say get user and make sure you import that so user right there where the ID is equal to off user ID so the logged in user because remember it's stateful and get and then after this we want to return a Json response which is going to be a user collection and we're going to pass the user and that's going to be 200 response so let's make this user collection let's say HP artisan make resource user collection enter open the side panel and then go into resources right there user collection and this is very straightforward let's get rid of that take this array off and we're going to say this collection and then map it function open it up and we want to say user now inside this we want to return an array and all we're going to do is say user IDs ID name is name bio is bio and then this image we have the user image and we're going to put the URL in front of it for the API itself so we don't have to mess around with it in the front end and then we got the created ad and the updated ad and that is it for that so save it go to user controller bring that in and what's that uses user collection oh actually just rename this to users collection let's just jump in and rename that users collection okay save that now back in user controller users collection import that at the top save that and now we also want to go back to the GitHub repository so John week's Dev Tick Tock clone API and then go into public and this userplaceholder.png download that and then once you've got it drop it into public like that so good use a placeholder.png and now next open the terminal we're gonna PHP Artisan migrate reset so we clear all the database out then go into the database file on the side right there migrations create users table and we are going to add two lines and that is going to be bring bio which is nullable and text image which is also nullable save that now go back on the side panel go to app HTTP controllers off and then this registered user controller we want to add a line into this and that is going to be image forward slash user placeholder.png okay now open the side panel again now we want to go into providers next to models right there and this root service provider where it says dashboard just take that out and save it like that and now go back into the terminal and we want to say PHP Addison migrate let's go and have a look at our database let's refresh now we can see we got bio and image in there as well which is perfect okay so now let's jump back onto the front end we're also going to do the register user stuff as well so under login very simple function register so we're passing a name email password and confirm password and the same like that it's pretty much exactly the same as login except it's post register let's just save that and now open the side panel get the register component right there scroll to the bottom and this is almost the same as the login function we go right there so if I just drop it in so this is the register function very simple pretty much exact exactly the same as this this login function except we're passing name email password and confirmed password which are these variables right there and we also can't forget to bring in our stores so if we do cons user store and General Store and you can see at the bottom we've got errors.value equals error response data errors and I'm going to make sure in login I put that in there as well I don't want to forget that errors value equals error response data errors save that and now back in our userstore.js underneath this get user we're going to add log out very simple axios post log out and we've got a function that is reset user also very simple just looks like that so we're resetting all the states back to default or nothing so save it okay right that should be most of it so if I just close this two screens and now we quickly jump into the top nav.view there's a couple of modifications we need to make so let's scroll down under the root we're going to add router so use router we're also going to add a function called is logged in very simple we just take the user store dot ID if it is an empty or null then we can go to the upload page else we open the login section the overlay and then just under that another function very simple again called log out so I mean it does exactly what it says so when we click this we log out and we go back to the home page and that's it so let's scroll up to the top and where is it on this upload button let's make a space and all we want to do is say at click is logged in and this image on line 54 we want to update the source to that userstore.image also on this next link on line 66 we want to add the path to this user's profile so userstore.id and then finally at the bottom this section where it says log out on this div all we want to do is say at click log out and while we're here we might well finished up this component because there's one section left and this is going to be an unmounted so on mounted open him up and we're going to say document dot add event listener Mouse app function open that up and E for the event we want to get document by ID so pop-up menu and if we search for that right there you can see line 63 we've got ID pop-up menu so let's go back down and all we want to do is say if pop-up menu does not contain e-tag it close the menu and that's it so save that and let's go and try this see if it's actually working so let's go back to our browser localhost 3000 and let's open this right up and let's just go back to the home page okay let's see if we can register so let's go to sign up if I just put anything in this for now if I press sign up access error 422 that's good at least that's working what does this say response data errors the email field must be valid the password field must be at least eight characters awesome okay so let's go back into our code because we need to include that so we know we have an error so let's go to register.view and you can see here we've got our little error prop which we haven't filled and this is very straightforward we're going to change this for if errors so if it's not null and errors.name is not null display what the error is else nothing and this is pretty much the same or email so we display email and the same for password display password and also confirm password just like that save it right let's go back to the login page and it's also do it for that there's just one error on this and that is going to be email and that's it save it let's go back to the browser and you can see it they're already beautiful look at that so we take this off and let's put John Wick's Dev John m.com and this I'm going to put one two three one two three one two three and then this bottom one I'll put one one one let's see what happens and sign up awesome the password field confirmation does not match so if I actually make this correct one two three one two three one two three sign up and what is this at the bottom this is a 500 on response data uh target class user controller does not exist okay let's jump back into our API and let's have a look API did we no we didn't import user controller so make sure we import that right there use app HTTP controllers API user controller awesome okay let's jump back in the browser and we might as well clear this out now because we might have the tokens so let's do an application cookies yeah we did log in so go in storage clear site data MD cache and hard reload and now let's go back into Network clear all this out and let's try it again so let's go and log in and wait a minute I just thought let's go into a prosec if we refresh this yeah we did actually register but because the user controller wasn't registered so okay our red register does work so now that this registers working let's just double check it let me delete this delete the row delete and then sign up again I've just put in exactly the same credentials John week's Dev janamill.com and then one two three one two three one three for the password so sign up awesome and look at this all this has changed at the top amazing we got our cookie we registered we got a logged in user and why is that image not showing hmm well that doesn't matter for now let's just open this and see if we can log out yes we can there it is log out and now let's log in again and see if we can log in with the user we just registered so John m.com one two three one two three one two three actually you know let's do it wrong first so let's just do one login these credentials do not match our records fantastic for about if I delete this login email field must be a valid email awesome okay let's do it correct one two three one three one and three log in yes amazing we are now logged in I'm just wondering why this image is not showing let's have a look you want a database refresh and image is coming up as null why is that let me go back into the back end of the API open the side panel and let's go into controllers auth register user controller it is right there image user placeholder huh and actually I'm just wondering did I let me just check in models user no in the fillable so we need to add two new ones image and bio like that save it and now let's jump back in the front end and log out refresh and clear that store let's log back in and actually let's clear our user from the database delete row and let's re-register so go to sign up and let's sign up yeah there we go there's our little image awesome then we click profile yeah and then we go to profile number three I mean nothing's Dynamic yet so it all looks the same but we know it's definitely working and and then we click this log out and get sent back to the main page and we're logged out amazing okay close this and let's make this a bit smaller minimize the API you want to SEC and we're going to go back into the front end now why don't we do our axios Interceptor for when our cookie is expired it'll log us out on the front end so in the side panel let's go to stores and general.js let's import all of our axios stuff so the plugins axios and then the same thing as we did in user.js now in this actions we're going to say async has session expired opening and this is going to be a weight axios interceptor's response use and then open that up and put in the response and then open that up and then after this end bit we're going to say a function open that put in this error and in this top bit we're going to put this so return response so whenever we make a call all with axios the Interceptor will check for an error if there is none it'll just return the response but if there is an error we're going to specify we're going to say switch error response status open that up and then we're gonna have three cases which is going to be a 401 so not logged in 419 session expired and a 503 down for maintenance and let's just scroll up to the top of that because we also need to import our user store from user let's go back down and after this case we're going to say use user store reset user and that is this function right here inside user and once we've done that just hard refresh back to the main page and then break and then we've got another case which if we get a 500 we're just going to alert say oops something went wrong and then finally a default which is going to look like that so allow individual requests to handle other errors and we just got return promise reject error and that is our Interceptor so what we do with this over the side panel go in the main app.view and under this we can have unmounted and let's make this an async let's Chuck a fry catch in there console.log the error and then inside this say a weight General Store dot has session expired and we do it in the app.view so whenever this application is mounted this has session expired it's always running awesome so now what happens is if we go to the back end and we go into dot end you can see the session lifetime is 120 minutes so after two hours of non-activity if we then come back and try to go into a page that is making a request from this API the axios and the axios Interceptor will intercept what we've specified so a 401 a 419 and a 503 if it's that we'll get logged out or if it's a case we'll just have an alert and the rest is handled by us so awesome that is how that works and later on by the end of the application we'll test this anyway but for now this should be good save it right I'm going to add one more function into this because it's very simple and I've just called this body switch and it is this so body switch and we're going to document body style overflow and if value is true then it's hidden else overflow is visible and I'll show you how this works now so save that and let's go back into app.view and at the very bottom of this we're going to have two watches and again they're very simple they are just like this so we're getting the body switch from General Store and we have is login open being watched so anytime we open or close it we pass the value into the body switch and the same with is edit profile open because they're both overlays so if we save that and we also unmounted add three things to the top of this that's going to be like that so when we load the application we want all this to be false save it and underneath this has sessions inspired we're going to say if the user ID is there get the user and we're just going to pull that in at the top in there like that okay right I'll show you what this body switch does so over the side panel and inside Pages index.view we have this post main now if I make this a duplicate like eight times save it let me go back into this we can see we can scroll it and then when we open login we can't scroll anymore so if I take that off if I go back into app.view and I just remove these watches like that save it and I do log in again you can see the background Scrolls and that is horrible so when we put that in we save it we then disable overflow so that is what that is for beautiful and then we get rid of it and it Scrolls again very nice okay now let's jump into our back end and so we don't have to keep messing about jumping back and forth because that will be really annoying why don't we just do all of the functions we need to do in the back end for the Post controller there's a general controller comments likes and all that type of stuff and we set that up ready so then we can jump into this front end and hook it all up so let's open our API and we started the user controller so we might as well finish it off because we need it so we got this logged in user this create I'm just going to get rid of and this store I'm going to change to update user image and this request that we need and now because this is an image we need to validate that an image is being passed and it's a PNG or a JPEG and then we got a little bit of validation we're going to say if request height equals empty string because this update user image is going to be a cropped image because we have a Cropper on the front end remember so we need to make sure we have all the dimensions for it that's going to be height width top and left like that and let's open it up and all we're going to do in this is just a return response Json error the dimensions are incomplete and a 400 and now after this we're going to do a try catch with our response and that is a 400 and inside this try section what we're going to start with is this so we have a new file service which we're going to go and create because that's going to be a service update image an auth user because remember will be logged in to the back because it's stateful and we're going to pass the request to it so if we open the side panel an inside app we're going to add a new folder called services and then in Services we're going to say new file file service.php and we need to add that so PHP Tag namespace Services this use image is going to be intervention image so we're going to go and get that now and install it and the class is file service so let's go and do the intervention image package on the browser and look for image Dot intervention.io and then what is this read about Lana Valley integration uh let's have a look up where is it there we go we need that so require intervention forward slash image copy that go back to this close this side panel a sec clear that out and just say composer require intervention image and uh okay that is installed next go to integration in laravel we need to go into a config app provide us we need to grab this so open the side panel go into config app and let's scroll down to Providers right there and package service providers just add it in there put a comma at the end and then next one is the aliases copy that scroll down a bit more there's class aliases add that into that save that next configuration we need all of this PHP arts and line so grab all of it copy let's go back let's paste that in and enter and config.image PHP that has been published and example of course all that means we're ready to go okay so let's close that and now let's go back and file service.php and this first function is going to be public function update image and we're passing the model and the request and now first line image is image so this use image make request file image so we're getting the image passed in and then we're going to say if model image so in this case the model will be user so if the user image is not empty get the current image from where it is and then we need to check and see if current image file exists and also and current image is not equal to user placeholder because that's the default we don't want to delete that then we unlink that image and unlink means delete so we're deleting the file and then after that we get in the file image and putting it into this file variable then we want to get the file original extension and now after this because was this image is being cropped we're going to use this we're going to say image crop and remember this image is coming from this so we're using intervention image we pass in the width height left and top so that's how that crops that and then we're going to assign a new name plus the extension we're going to save that file so whatever it needs to be in this case it's going to be in files and before I forget let's go to public and we're going to make a folder called files just like that and then finally we're going to say model image so user image equals files and then the name so that is what we save and then we're going to return the model OKAY save it let's go back and use the controller and import file service and all we want to do after this is just save it like that save what we return out of the file service and then just in case so we know that it's successful return response Json success okay and a 200 response so everything is very good right save it next this show I'm going to replace with get user and this type in string just get rid of that again we want a try catch like that and this is super easy all we're going to say is find user by ID and it's a find or fail so if it fails then we return this error and all we're going to do for this is just say return success okay and return the user that's it 200 response right there save that nice and easy and now finally this edit just get rid of that same as destroy remove it this update we're going to change to update user and the ID we don't need that get rid of it now this update user first we want to validate because name is required but bio isn't required because it can be empty so if you remember if we go into profile and we click edit profile we can see there this is what I'm talking about so using name is required but bio isn't so we're going to say name required and then under that try catch and again this is super simple we're getting a user finder fail and then the logged in user ID like that and then all we're going to do is just get the input the name and the bio and then save it and then after we've done that just return a success okay and a 200 so we know everything is good and that is user controller done awesome now what can we do next a nice easy one let's do one called HP artisan make controller and we don't need a model or migration for this all this is going to be is API forward slash Global controller and let's just check a resource in him enter now let's open the side panel Global controllers and this is super easy just change index to get random users and actually the rest of these functions we can just delete so just get rid of it there's only one function in this and again we're going to have a try and a catch and all we're going to see for this is get users in random order so the limit for this one is five and that get is iterate so it's like a collection and make sure we bring in users and that is for the suggested section and then the following section is limit 10 and all we're going to do is return suggested and following as a collection so we just need to import our user collection as simple as that beautiful let's just make sure it's in there yeah user collection and app models user beautiful and that is that controller done save it okay next let's do post so we're going to need a Model A migration and a controller so HP Artisan Mig model post hyphen MC for migration and controller and then hyphen hyphen resource enter open the side panel and you can see our post controller is outside of the API just drop it in there move yeah go into post controller and on the namespace but backslash API and then controller import that so make sure you do app HTTP controllers controller and that is referencing this controller by here now let's jump into our database migrations and it's open create post table and this is very simple I'm going to drop this in this is where we need unsigned big integer so a user ID and then we need the reference of foreign key which is a user ID which references ID on the users table and Cascade it we're also going to have text and video and if you've seen previous tutorials that I've done like the Facebook clone and Instagram cologne this is all practically the same I mean once you've done one social media you've done it all because it all has posts comments likes and it's it's all the same type of thing so this is all very similar so let's save that and let's go to our host controller in controllers API and let's start printing our methods so index and create just get rid of that we don't need it and this store we're going to use so first we need to validate we need the video and text and we need to make sure the video is only an mp4 and then under this we can have a try catch so we can catch any errors if there is now we need to create a new post and next we need to import our file service and we need to make a new function called add video so if we import file service and you can see it right there use app Services file service now if we jump into that file we've got upload image there and underneath that we're going to make a function that's going to be add video we pass the model and the request so in this case the model will be post and this is very straightforward first we need to get the video and put it into this video's variable then get the video extension rename it with that original extension move that file where it needs to go and then add that file path through our database and then we're just going to return the model like that save that now let's go back into post controller and then then after this underneath we're going to say get the logged in user so off user ID is user ID and the text is the text we're passing through and then finally we save it and then return a success with the 200. beautiful that is that function done okay next is show right there I'm just going to replace that with ID and again we can have a try and a catch and this method is going to be four if I just jump to the front end and I close this and I go to the Post page this is going to be for this page so what we need is the actual post by ID and we need to return all the post IDs associated with the user that owns this post so then if there is multiple posts we can click these buttons and we can go through them so let's go back to our code and the first line is going to be get all the posts where the post ID is equal to ID now you can say first or or find or fail but because I'm going to use the all post collection which we haven't made yet then we need to use get so I'll show you in a minute let's just continue and under this we also need all the posts where user ID is equal to user ID and then we get all of those so that could be a single one or multiple now next we're going to map the post and this is very simple take the posts and make an array of all the IDS and then you put it into a variable that is IDs and then we want to return the individual posts and all of the IDS of the post that that user has and then a 200 response so let's go and make this all post collection so let's open this terminal let me just clear it out say PHP artisan make resource all post collection enter let's go on the side panel and go in resources and right there we have all post collection now instead of this parent to array we're going to get rid of that and we're going to say this collection map and then function open it up and we want to Loop through each post and then what we need from the actual post is let's just do a return open an array we're going to need the the ID text video and created act and again I've got this URL added into this section so we don't have to mess about with it in the front end and now next we want to get all the comments associated with that post so that's going to look like that so comments post comments and then we're going to map it and this post comments is a one-to-many relationship which we're going to add in later when we finished all of our controllers we'll go into each model and then connect them so let's say function comment open it up and then inside this return open that and I just noticed this array just take that off yeah remove that awesome right inside this return or the comment we just want the comment ID and the text so the actual account comment and then inside this we need the user that is the creator of this comment so ID name and image and again I've just put the URL into this awesome so after comments we have all the likes associated with it so post likes and then map it function like open it and inside this we want to return the ID the user ID and the post ID and finally we want to return the user that made the post just like that awesome right nice and simple let's save that go back to the post controller and let's bring that in so all posts collection scroll to the top now we have app HTTP resources all post collection and that is why we needed to do this this way because it needs to be a collection and we're just getting a single post so then we can just pass it into this because otherwise it'll error it won't work awesome right finally this edit and update get rid of it we don't need that and this destroy in this I'm just going to put ID and I'm going to try catch again we'll catch our errors and this very straightforward this time it is a find or fail for the post and under this we have a little if statement that is going to say if the post video is not null and the file exists and then we pass it the path if both of those are true we want to unlink so delete the video and then finally we delete the video from the database so again unlink is delete the file and this is deleted from the database and lastly we just return a response success okay with a 200 response awesome right that is post controller done next we're going to do one called profile controller so if I just press up and we got mid controller so I'm going to change this Global controller to profile controller so PHP Artisan me controller API forward slash profile controller hyphen hyphen resource enter let's open the side panel Channel there we have profile controller and there's not much going on in here just one function so index create and store we can delete the show we're going to keep just get rid of that type hint and the rest of the methods delete so we just want to show now again try catch and this profile controller let's go to our page if we go to profile whenever we land on this page this is what this function is for so we're going to get the profile by ID so profile forward slash ID so if we go back into this code we pass the ID and then first line will be post where user ID is the past ID order it in descending order and get so it's a collection because again we're going to return this with our collections that we've made in our resources so all post collection and users collection so let's make sure we import the post model right there app models post and the next line is going to be user so get user where ID is equal to the ID and again we need to get the user model so app models user and all we're going to do for this is return our posts and user and make sure we import our collections like that so there we go all post collection and user collection if we scroll up all post collection and user collection from resources just like that awesome save that okay next another simple controller let's do the home controller so this will be API forward slash home controller let's press enter open the side panel let's find home controller right there and we only need the index method for this so all the rest of it just get rid of it like that so just index and again try catch now again we want to get all posts in descending order and make sure we import this post model and all we're going to do is return all post collection just like that make sure we import that us right there resources all post collection and this controller is done awesome right where else um okay next let's do comments so we're gonna need to make a model so PHP artisan make model comment and we need hyphen MC for model and controller and a resource let's press enter go into the side panel drag this comment controller into API move yes let's go into comment controller and the namespace again we need to make sure we do backslash API and import our controller like that so controllers controller again this one right here and this one is pretty straightforward this index and create we're gonna delete we're going to keep destroy and update edit and show we're going to delete so All That Remains is store and Destroy again try catch then we need to validate in our request that we have a post ID and a comment so that cannot be empty and then in the try we're going to say new comment is comment and we're gonna have three lines we need to get the post ID user ID and the text which is the comment and that is going to look like that and then all we do on this last bit is save it and there we go save and now let's do the destroy just going to change this to ID but in this try and catch and this is very simple all we have to do is say get comment by ID and then delete that is it beautiful save that okay last controller let me clear this out let's press up and there model we need that so HP answer make model like so this is going to be the like model and likes controller also need a migration let's press enter open the side panel light controller drag that into API and again make sure we do the namespace backslash API then import the controller and this is going to be the same as comment we just need the store method and the destroy so all of the rest we can actually get rid it off so that's all we have is store and Destroy right now first off in this store we need to say validate so we need to have the post ID because we need to associate a like with a post and then under this just add our little try patch just like that and then we're going to say like is new like then we're going to say user ID is the logged in user and the post ID is the post ID that we're passing and then we just save it like that and for this response we are going to return the like like that so like we need the ID the post ID and the user ID and the reason we return this back is because we need to do some stuff in the front end to actually update the like in our local storage so it stays synchronized so that is how we do this store method and it'll finally destroy just going to change this to ID and then we say try and catch and in this we have find like by ID and then we want to count if this like is greater than zero so if it exists we want to delete it and then exactly the same as before our return response is going to be this so a like with the ID post ID and user ID in like that okay let's jump into the side panel and we need to do our migrations so post we've already done let's jump into comments and let's make a space in the middle of this we're going to say we've got two unsigned big integers so user ID and post ID and they are both foreign keys and then one more column which is going to be text which is going to be the actual comment very good save that and then finally our likes migration this is almost exactly the same as comments except there's no text columns so again unsigned big integer for a user ID and a post ID and they are foreign keys and that is it save that very nice now what we can do is do our eloquent relationships and this is going to be pretty straightforward let's go to the side panel and go to models and let's start from top to bottom so comment okay first we have a post so a comment belongs to a post you can see it right there because when you make a comment it's a comment for a post and also we have user so a comment belongs to a user because a user makes a comment awesome save that next is like and there's only one in this very simple this is going to be a like belongs to a post beautiful save it next post okay first we're gonna say a post belongs to a user makes sense second a post has many comments so a post can have multiple comments so that is a one-to-many relationship and we want to get the order of these comments in descending order so the one that was created latest first very good now finally we want like so a post as many like just like that very simple save it now last one user.php let's scroll down first one is going to be posts so this class is user so a user has many posts because a user can make multiple posts and finally a user has many comments because a user can also make multiple comments awesome right that is literally all of the back end done so what we can do now if we open our terminal let me just clear this out I'm going to say PHP Artisan migrate enter beautiful let's go and look at our database let's refresh and there we go comments likes posts users awesome that is everything that we need amazing right that is our back end done oh wait no we need to um yeah nearly forgot we need to create our endpoint so let's jump into Roots API dot PHP let's just close this terminal plan close this side panel and this is nice and easy there's quite a few end points in here so first outside of this sanctum middle way we want to get this so get random users which is the global controller let's make sure we import it so at the top Global controller and next we have our home route so that's the home controller let's import that and just so you can see let's go into home controller there we've got index and our little method we made earlier awesome now inside the sanctum middleware we can add the rest of the things we need so underneath this logged in user we also need update user image which is a post and finally for user we need this patch which is update user which is like the information it's not the image awesome next is all the post stuff so I'll just put those in together there's three routes that looks like that so we're gonna get a post and a delete we get in post by ID from the post controller and let's import that controller scroll up there it is post controller right there and then this posts one we've got a store method which is posts and delete delete by ID awesome next for the profile page this is just one route which is going to look like that so we just want to show the profile by ID and this is profile controller let's import that so there it is profile controller now finally we have comments and let's import the common controller let's have a look calming controller right there which is going to be post we want to create the new comment for this line and delete we want to delete a comment by ID and can't forget our likes and that is going to be likes just like that so post and delete we want to post a like and then when we unlike it we want to delete it so import light controller roll at the top there's light controller right there save that and that is all of our endpoints right now our back end is officially done so all we have to do is hook this baby up awesome let's jump back into the front end and make this application work okay let's go back into our front end and first we might as well do the upload page so we can actually create a post and then we can display it so let's do that first so let's go to upload ah we're gonna have to log in first so I'll put in the user that I registered with login and what is going on there why is that not logging in let's have a look let's go to the terminal see if there's an error no ah yes what's this api.php ah I think I forgot the semicolon so let's go back in the back end yeah right there forgot that semicolon don't want to forget that save it right let's try again login beautiful there we go now we're logged in let's do upload very good okay so first let's go into user.js in our store and let's do create post and this is very easy we've got an async function called create post and it's just oh wait axios post API posts and we're passing day data and this data as a parameter right save it and now let's open the side panel go into upload index and let's scroll to the Bottom now underneath this discard I'm going to say const create post async opening up first if there's an error we want to reset that to null and then we want to have a new form data object like that and the two things we need is the video and the text so file data.value and caption.value and then we're just gonna have a little check that's going to say if file data value exists and caption exists we're going to put this is uploading to true and let's just go and check if we've made that no we haven't so underneath this upload error we're going to put a little div open the top up and we're going to add a vif is uploading so if it's true we show it and then the class is fixed Flex item sender justify sender top zero left zero widthful height screen BG black Z50 and BG opacity 50. so this is an overlay for when we upload it comes up it spins a little bit to show its loading and then we get redirected and inside is a little icon that looks like that so we got class animate spin ml1 the name is Ming cute loading line size 100 and color is white save it okay let's go back down to our function where is it create post right there right after this if we're going to say try catch Chuck an error in it and we're going to add in the bottom errors dot value equals error response data errors and we also want to say is uploading value to false just in case there's an error so we remove the overlay and these errors actually come from the back end because we validate and remember so if I open up the API and I open the side panel and I go into host controller with store you can see it right there validate so video and text if this doesn't exist it sends back an error message and then if I close this we just display it there we add it to the errors.value and errors is right here as a ref and where we're going to display this is from this post button if we go down one div so one open it divid and we're going to add if errors and then a class mt4 and inside this we're going to display two dibs like that so class text red 600 and if errors and errors video and on this one is errors text we display the video error or the text error awesome save it right let's go back down and next we're going to get our function we made in our user.js store so this create post and we're going to say awaituserstore.createpost and we're passing this data so this data that we've appended coming from the form data and all we're going to do is say if res status is 200 so success I put in a little set timeout or one second um once that is done we redirect through the user's profile page and we close the overlay and that is it so technically we should be able to upload something now so let's actually try it let's try our errors first let's open this up give it a quick refresh right so if I press post oh no I forgot to add the function name so go to create post and just go up to the button the post button right there button and let's just put this on a new line like that and we're going to add an at click event which is going to be create post awesome save that now if I go into the browser and I click post nope still nothing let's have a look what did I miss this user store did I bring that in and this router as well did I bring that in let's have a look no I didn't so underneath this import just bring in the user store from use next app and router from use router save it all right let's give it another click yes and there we go there's our validation video field is required and the text field is required so if I put in something in this and I press post only the video revealed is required now so let's select the video and this first one will do Randy Savage now if I remove the text and I press Post Yeah the text field is required so now let's say this is a post and then post it oh awesome I think that was successful let's go into our database let's go in posts yes there it is beautiful this is a post a file and let's just go and check in our API in our public files to see if that's in there yes there it is awesome okay so the upload post page is done right let's close that okay now we're on this profile page Why Don't We display the user so just make this a bit smaller let's go back in our code and let's go to the side panel open pages profile id.view and let's scroll to the bottom okay there's a couple of things we need to add into this so first and the main layout let's get the pinia store the refs and we are gonna import all of our stores from use next app so user store profile store and general store and then convert the profile store to refs like this and we want to get the post very good then under that get the rule root so use root we also need a little variable called show so when our videos uploaded we then set that to true so we show it now underneath this we're going to say on mounted open it up make this an async and then we can have a little try catch inside this with an error console log that out and this next function is going to be called get profile and we're getting this from root params ID so whenever we land on this page we're getting this ID in the URL so in this case it'll be three and then we'll get in the profile based on that so if it closes back up and this show we also want a little watch and we're going to watch the post dot value open it up and very simple I've got a little set timeout didn't you so whenever the post value changes we say set timeout and then show value is equal to True after 300 milliseconds nice and simple save it now let's go create our get profile function let's go in the side panel into profile.js and in actions we're going to say async get profile and we pass an ID as a parameter and then we want to use axios to get the profiles by ID and ID is being passed there remember we also need to make sure we import axios we don't have it in there so we can actually open the side panel go into user and just steal this from the top copy that go to the profile and paste it in like that so we import axios and then put it into a cons now if I go back and use a.js and I scroll to the bottom this reset user I'm going to steal it so copy that go back to profile.js and underneath this actions underneath this get profile I'm going to say reset user and email I'm going to get rid of and I'm going to duplicate this last image one and I'm going to say post like so save that now take reset user copy and just before we call our API we're going to say this dot reset user just so we don't have any funny business so we clear this user out and now we want to say this dot state DOT ID equals res dot data dot user zero index in the array dot ID and we want to do that for all of them and that is going to look like that so also we got name bio and image and we go on the side there as well and I almost forgot posts and that's going to look like that awesome but we save that now and if you want to just double check with us coming from if I open the back end and I go back into Roots api.php we get profile there let's go to the profile controller you can see there we got post and user and now if I go back to the front end there's our post and there's our user awesome okay let's open the side panel and jump back into profileid.view and now let's hook this up right let's scroll to the top and this Top Line just make some space and we're going to add VF profile store.name to make sure that it's loaded before we display anything because we don't want an error the next bit on this image this is hard coded we do all now we want to have profile image and then this username is going to be the profile store.name and I've made a little function for this so it's all lowercase and it removes spaces so this is going to look like that so General Store all lowercase no caps now if I open the side panel and jump into doorsgeneral.js and this function is very simple I'll just drop it in all lowercase no caps we're passing the string and we just say string split it where there's a space join it so there's no space and then put it all to lowercase very simple save that and let's go back into our profile page and then next this username this needs to be changed so that's going to be profile store.name also on this button we got VF is equal to true that is wrong we want to say if the profile store ID is equal to the logged in user ID then we want to be able to show the edit profile button else we don't awesome right let's scroll down let's take a look this is the Bio Section that needs to be changed so that's going to be profile store.bio and this section so get rid of all these components apart from one and make a space above add a div open it and we're going to say if show equals true and then we're going to Loop through profile store dot post and we're going to get each individual post so take this now the post user component copy it and drop it inside this Loop and all we're going to do is add one prop that's going to be post like that and we're going to pass the post so now if we go into the side panel and go into components host user.view we can now set this up so let's scroll to the bottom and we've already got the fine props there called post awesome now if we scroll up and then on this main div we're going to say at click display post and we're going to pass the post object like that now let's scroll down and underneath this on before unmount we're going to say constant display Post open that up and remember we're passing posts right first we're gonna have to go and make this function it's very simple we're going to say General Store setback URL and in this case it's going to be profile and then the URL parameter ID so this when we go to view an individual post when we click close it goes back to this profile and before I forget let's make sure we import the General Store at the top so General Store from use next app now let's open the side panel and go into General Store and this function is very easy all it is is that setback URL you pass in the URL and then you say this is back URL and that is right there so default is nothing awesome save it let's go back to the profile page oh no sorry post user component and next the selected post we're going to reset back to null so there's nothing in it and then we are going to actually go to to the post that we've selected to the post page so set timeout router push post and then post ID beautiful save it and let's scroll up um what else have we got the change this source is hard coded so we need to change this to host dot video we also have this this is some text that is post dot text and that is it I think save that and then go back to the profile page and I think this is all set up if I press save oh look at that yeah there's all Randy beautiful look at that man that is awesome hover over him we can see him sick okay next let's do this edit profile section oh username's already in there awesome so let's do the image stuff and the Cropper so let's go back on our code and actually let's just put this over like that so we can see it a bit better awesome right let's open the side panel um what is this off overlay no it's not author it's actually edit profile overlay because I'm an idiot right let's close that side panel okay let's scroll to the bottom and what have we got in here we've got most of it we just need to make a crop and update image function so let's do that so underneath get uploaded image can't crop an update image open him up and say async and now first we need to get the Cropper coordinates so we're going to do cropper.value.getresults and Cropper is there as a variable and if we scroll up to our Cropper component you can see the ref is Cropper and we're getting the coordinates out of that and then very similar to the upload page we need to get the form data and then append everything we need so that's going to be the image height width left and top that's from all the coordinates and then the file dot value and if you remember file is that and in this get uploaded image we are getting the file and adding it that way okay now after that we need a try catch error and we've got a console log the error right and then first inside this tray we're going to say user store update user image and we're passing the form data all the stuff we've appended and this user store I think we've brought it in already yeah it's right there make sure you got that in there and now we need to go and make that so open the side panel go into doors user.js and this is also very simple this is an async function called update user image and we're posting to the endpoint update user image and passing the data object save it that is it for that let's go back to edit profile overlay now once we've done that we want to get user so we want to get all of the updated information and also we want to get profile so we want to update the profile page at the same time now after this there's another function in here that I've got called update side menu image and let's go and make that first so this is in Js General Store so open the side panel go into general.js and under this has session expired let's just go beneath and we're going to say update side menu image open that up I'm going to add a four Loop just call that I we've got the array being passed through we're going to check the length we're just going to change this element to Res and then we're going to Loop through and say if res ID is equal to user ID update the user image and this is for this side section so we might as well do this as well because it all intertwines together when you update this page everything else updates simultaneously so it's all connected so save that and let's go back to edit profile overlay and we also want to have another one of these underneath which is going to be that so this one is for suggested users and this one is for following and all we're going to do to finish this up is say userimage.value equals image.value and uploaded image value value we set back to null awesome right save that now let's see if we can update this image so edit profile let's go and click our profile photo actually this is still hard coded so let's scroll up and we need to find yeah there it is that hard-coded value we need to change for user image save you can see it now it's changed awesome so let's go into the Cropper let's pick an image I'll just pick this Instagram one spread him right open like that and actually the buttons are not displaying at the bottom so maybe I've missed something let's take a look uh actually I've forgotten to put in the Cropper buttons so this is pretty straightforward this update info buttons this entire div section take it copy it and paste that beneath change update info buttons to Cropper buttons this VF becomes V else this button this at click you change for uploaded image equals null so we just clear it and this crop and update image is correct in the Cropper buttons but if we scroll up this crop and update image shouldn't be there that should actually be update user info and we're going to go and make this in a minute so let's just add the rest onto it there's also going to be a disabled because we don't want to press it if nothing has changed and also a dynamic class that is going to look like that so if it's not updated the background is gray else it's red awesome save that right and now we can see our buttons right there so if we've done this right let's click apply nothing happened let's inspect console root is not defined oh did I forget to bring root in let's take a look yes I did so underneath store the refs const root equals use root save that and where is that root right there that root.pram.id okay so let's close this and ah yeah it does work okay let's refresh yeah it is updated amazing so let's do it again let's edit profile update this image choose this Netflix one and just put whatever in it apply yes that has worked we didn't go back to the main edit section let's just shut this a sec but you can see that the image has changed because we've updated it very good let's go back and edit profile and go to the Cropper again let's just pick anything open right let's just figure out why it's not redirecting um it should be okay we can't really see anything at the moment why don't we do this update user info function just to get it in there now and we can finish we can fix whatever bugs there are when it's all in there so if we scroll down and we take this crop and update Image Grab It All copy and paste it beneath all of this data and phone data and the coordinates remove so we just have the try catch update the name to update user info now this function update user image we're going to change to update user and we want the pass username and user bio and then this update side menu image is not necessary we can get rid of that and we're going to put in this username dot value his name and user bio.value is bio and then to finish it off remove these two at the bottom and just for a little set timeout at 100 milliseconds and say General Store dot is edit profile open equals false so we close it and now let's go and make this update user function inside of user store so user.js and this is also quite simple underneath this we're just going to say async update user we pass the name and the bio and this is async await axios.patch because this is an update the end point is called update user and we're passing the name and the bio that's it save that and let's give it a try let's just give this a refresh to make sure it's all good now edit profile let's say bio let's say this is a cool bio man and we can see this is working so we've got 23 out of 80. let's just double check that that is actually limited to 80 let's paste this in yeah so I'm clicking I can't go any further awesome right let's try and apply this apply oh look at that there it is beautiful amazing right let's go back in our edit profile let's do the image again prop something let's get this Netflix do it the other side apply and it did update I can see the little image in the side that has updated but I don't know why it hasn't gone back to the main edit section let's go in the code effect let's go and edit profile over lay on actually I just noticed a little error there on this last watch this user bio shouldn't be user bio that should be user name save that a sec let's just double check let's go back can we update this update apply yes all that changes so that's working edit or if I remove all this now we can't apply okay and what is this little error in here so we got cannot read properties of null reading length update side menu image oh it's this it's this okay let's just go and have a look in there ah because yeah it's null it's not an array okay so let's just add those in so we don't break this all the time so in general.js we want to say uh just above this update side menu image async get random users and open that up and then we've already made an endpoint in the back end called get random users and there's two if statements in this the first one is if type equals suggested then you get all the suggested users and you put it into the suggested variable and exactly the same with following just get all the following and put it into the following variable save it all right let's make sure we put a comma at the end save that and now all we do is jump into the side panel go into our main app Dot View and inside this on mounted after has session expired all we want to do is say general.store get random users and this one is suggested and this one is following awesome right save that let's go back into our code and let's try it again edit profile let's update an image choose Instagram and just apply that yes beautiful look at that awesome and actually now I think that is this page done so if we cancel that all this has been updated and considering we've just done this get random users we might as well pull them in because we can put all the users down the side so if we close this in Spec we'll go and get some random users I mean we only have one which is us but if we do it now don't have to do it later which is always good so let's go into the code open the side panel and we go into side nav Main and then where is it right there menu item follow line 23. okay we need to import some things for this so let's scroll to the bottom we need to import General Store and user store we also need router so use router so we go root there so we go root on the top and router at the bottom and in this we're also going to do a little function called cons is logged in open that up and just put through this fall for follow now again very simple if the user ID doesn't exist we want to open the login and then return so we stop that function and if that is not the case then I've just put this little set timeout with inside router.push go to the profile that we're clicking so save that and then is logged in we're going to go up and I am going to take this I'm going to copy it remove it put a new div and drop that inside it like that and then the outer div open that up and we're going to add two things we're going to add a VF and a V4 like that so if suggested isn't no so if it's if it exists show and then we want to Loop through and then in menu item follow we want to pass a prop that is user and I put surge for suggested and also this is where we add our is login is logged in function as well so just on this div they add click is logged in and we pass the suggested user if we just scroll down quickly there we go follow suggest it's the same thing awesome right let's jump into menu item follow so let's go into components menu item follow and this is all hard coded so let's update it this is nice and simple we've already gone over the fine props which is user just above it let's import General store and now let's scroll up and on the image we're going to say if user image show it and we are showing the user image we want to change this username to the username but all lower case no caps and then in this username section we just want a normal username just like that beautiful now if we save that and then in this side nav we have one more just below which we need to update so we can literally just take what we've done copy it go down replace this like that and instead of suggested we rename it to following this is following I'm going to call this fall and they fall and this fall as well awesome right let's save it and let's take a look there we go I know that it's us and we can't really follow ourselves but there's only one user so this is now working perfectly awesome okay so I think all we have left to do is the main page so if you go back to the home view yeah this and the post page and that is it we are then done so if we do this one first because this should be nice and easy so let's go back in our code open the side panel and let's go and do pages and this main index.view let's get rid of all of these host main components apart from one and we're gonna have to Loop through this so we're gonna have to div it and in this we're going to add a V4 and we're going to take this post Main and we're going to drop it in like that that's just indent and on this post meme we're going to say if post exists show it and we're going to pass a prop called post which is going to be the post now let's bring that in so in the script we're going to say use next app and we're going the General Store and then let's say on mounted open him up put it as async and this is very simple it's going to be that a try catch with get all users and posts now we need to go and make that so let's save this for the moment this is probably gonna break well there's nothing there okay so let's open our side panel the general.js and let's scroll to the bottom of this and underneath this function update side menu image we are going to just add in this so get all users and posts so we get in from the end point which is home and we're adding all of that to the post which is this post and now if we save that we have one which is correct we have one in our database now all we have to do is make all this Dynamic so let's go back into our side panel go into components and post main.view and in the script section let's bring in what we need to so just about this video variable we're going to bring in use next app with user a store and general store to find props which is post and then we need to put that to ref then under that we need our router from use router now in this unmounted I'm just going to take this out a sec and let's open it up and what we need to use in this is something called intersectional Observer I mean this is the first time I've used it so first we're gonna have to instantiate a new intersectional Observer and then say function and then entries let's open them up and then we're going to say if entries zero index is intersecting open this up we want to play the video and I'm going to leave this console.log in there just so we know which video is active and then when this Scrolls out of view we want to say else pause the video so when we scroll into the view the video starts playing and then we scroll slightly out the view the video pauses awesome and just at the end of this we are going to add another little object that is the threshold and I've put 0.6 you can change this to where however you want but um I found this is probably the best setting now under that we're going to call this Observer variable right here and we're going to say observer.observe and then we want to get element by ID which is Post Main and we want to get it by the actual post ID and what we're going to do we're going to take this copy it scroll to the very top and this post main just take it out a sec do some little back text add a colon before the ID and add that in like that so then we are getting each post by its ID awesome right save it and that is broken what has happened let's refresh cannot read properties of undefined reading ID oh yeah because in this value we don't need it in the template let's save it and then refresh there we go beautiful right let's make this Dynamic on this div below it we have an at click function which is is logged in and we're passing the post start user so let's go make that function and I I think this is the same as menu item follow or side nav menu I think it's that one yeah is logged in there let's just grab that pop here go back into Post Main scroll down let's drop that in and that is that done except I'm just going to take this file and just change it for user and user there save that okay we also need after on mounted on unmounted and this is the same as we've done before this is just on unmanned we pause the video and stop it awesome right let's scroll back up next on this image we want to make this Dynamic so let's add in post user image if we save that and we go and take a look we can see now we got a little Instagram logo up there perfect and then next this button that also needs to be an at click is logged in then inside this span the username needs to be all lowercase no caps post user name and then this bottom one is just a normal one post username then when what else have we got this is some text so this is going to be post dot text right let's keep going okay so on this div that surrounds the video open this up and we're going to add in at click display post so let's go and make that function and actually this is almost the same as is logged in so we can copy that and paste that beneath let's change it to display post and we're passing a post and all we do for this this is correct this if so we can't see a post unless we're logged in and we change the set timeout just get rid of it and we're going to add this so we set the back URL to the default page we clear the selected post and then we want to go to the Post Page by post ID just like that save that beautiful right let's scroll back up to this display post let's continue okay now this video we need a VF host dot video exist we want to show the video just like that a save let's take a look and there is Randy Savage very nice now this is the like section so it's also possible from this page if we're logged in to like and unlike a post so line 55 this button let's put this class on a new line and we're going to say at click and is liked is a computed so if is like this true we want to unlike the post else if it's false we want to like the post so we need to go and make three functions so let's scroll down and under this on before Mount let's say const is like computed and then open that up and then we want to say host.value.likes dot find like that and then say like and then we're going to say like dot user ID if that is equal to userstore.id we want to return it and we're going to say if res is true return true or return false just like that I save that then we've got like post which is going to be something like that so like post async we're passing the post and then we have the same as is logged in copy this bit paste that in there because we don't want to like if we're not logged in because we'll throw an error and all we're going to add into this is a try catch with a single function that is like post and we're passing the post so we're gonna have to go and make this in our store because we also use this function in post view as well so we can like from two places so let's open the side panel go to stores user.js and where will we do this let's do this under create post so we're going to say async like post and we want to pass a post and it is post page so we need that is post page for when we're on the post page so we can send through something that says it is the post Page open that up and there's quite a bit going on in this so first we're going to say post to the likes end point and we need the post ID and we're getting posts from there and I'm just going to check a console.log in this to make sure that it does work and then we need a local variable inside this that's going to be single post is equal to null by default now what we're going to do if is post page so if it's true we're going to say post is single post because we're only assigning one else we need to get all of our posts from the Genet from the general store which we need to import in the top so let's bring that in import use General Store from General let's scroll back down so we need to find that post by ID by looping through the post and I'm just going to dump that out underneath as well just so I know I haven't messed up and all we're going to do after that is say single post dot likes dot push and then we're going to push the updated like so let's quickly go through it again when you like it your post goes through to the database and then we check if that has come from the post page or not if it does come from the post page we we already have the single post else if it comes from the main page we have to Loop through all of the posts and find that post by ID and then update the likes on that post so if we save that and now we jump back into our main index page no sorry in our components the post main page there's a lot going on now it's pretty confusing and we scroll up where this is this unlike unlike right just under this this span where it says 34 delete that and put in host dot likes dot length save it you can see now that this has zero like so now I'm hoping if I've done this right if I click this it's going to go red and we'll have one like so let's try it there is one like did I forget something yes I did on this icon let me just put this stuff on a new line and under this I'm just going to say color is liked if that is true it is fo2c56 else nothing so now if we save that and go back you can see that it is red beautiful and if we go into the database and I go to likes there is our like by user ID3 post id1 beautiful look at that right let's do the unlike so we have our unlike function there let's scroll down to the like because this is exactly the same process in this one just paste that beneath let's say unlike post and this is also unlike post and now we need to go and make this in our user store so let's go to stores user.js and we have kind of the same thing again but it's a little bit different so let's go under this like post and we're going to say unlike post pass in the same parameters post and is post page now we need two local variables so delete like is null and single post is null then we can scroll up and we can take this little bit so copy that paste that into here and then under this we're going to Loop through so single post dot likes dot four each and we want to say like and inside this Loop we say if like dot user is equal to this ID so this is referring to this ID in the state the logged in user a scroll back down we want to add that like through the delete like local variable right there and now under this we want to say a weight access delete and then we delete by ID so that delete like ID and then finally at the end of this we've got a for loop we're going to Loop through let's just say I we want to Loop through the single post dot likes and get the length how many likes are in there and let's update this array to single post dot likes dot iterate and then finally if like ID is equal to the ID we just deleted we want to say single post likes dot splice I for the index and then one to remove it so splice is remove the object from within this array so delete and that is it for that function this is pretty this function is pretty heavy so if you don't understand it just take your time with it because it did take me a while to figure this out but anyway now we have that if it's saved let's go back to this page let's refresh and now we should be able to just click this and it goes away click oh look at that let's click again yes beautiful now we have all of our like stuff working and if we click off that and we go back to our SQL Pro and we refresh the like has been deleted let's just like it again refresh there's our like in there beautiful right so that is the main page done all we have left to do now is the post page so for that we just need to be able to go through a certain user's post like and unlike on that make a comment delete the comment delete the post if it belongs to us and that is it then we're done we can just make loads of users and enjoy our work so let's do it right let's do the post page let's open him up go forward slash post and forward slash one that'll do for now okay let's make this Dynamic so close this as much as we can to about there let's go back in our code and let's open the side panel and go into post dot ID and let's just quickly let's just quickly scroll to the bottom and see what we have right we've got a couple of things in here so first off at the top let's bring in all of our stores like that and now let's scroll back to the top and first off on this div we're gonna say if General Store dot selected post is not null show it also we have a link on this nux link that is going to be 2 and that is the is back URL and we should probably actually go into our main page and click this so we actually select a post to display because at the moment it's going to be null so if we click this post it takes us to post okay and it's a bit messed up at the moment so let's just continue next we got this VF equal to true we need to change that for General store.ids.length if that's greater than one display it then we got this Loop through posts up so we're not actually going to see that because we've only got one post so we'll leave that for now and we're going to make a new post when we're ready to do that now let's keep scrolling down we got this image and video section right there we need to change that to General Store selected post dot video and the same with the source selected post dot video and let's have a look why is that not loading let's just scroll down a sec to the yeah okay this online did let's just take this remove that and uncomment this save it and let's give it a refresh nope still nothing we'll just ignore it for now let's just get all of our template stuff done so where was we video okay now next this video we need to say VF selected post video and again the same on the source selected post dot video if we save that and now our info section this V if true selected post and then we got this nux link which is actually going to be two profile and then General store.selected post dot user.id then we want to display the user image so selected post user.image then we have the username and this is with the uh no caps thing or lowercase no caps with selectpost user.name and then the name normally and we've also got this date here that is going to be selected post created at now we got this icon which is Default true we need to say if the user ID is equal equal to the selected post user ID then we display this icon which is the delete icon next we got this is the post text we want to replace that with the actual post text then we got this original sound username username is replaced with all lowercase no caps then we got this button new line it and this is going to be an at click with is liked unlike post like post so we're going to go and copy and paste those from the section we just did that in which is the main page and our little icon we need to add is light for the color as well same thing as we did earlier what else we got this like section one two three we need to put in like start length to see how many people have liked this let's keep having a look we got this if false that is wrong that needs to be if comments dot length is less than one so is zero we display no comments else we want to Loop through all of the comments in this post and I took the key on it called comment and then this next link is going to become profile comment user ID the source is going to be common user image so the user that made the comment then we got this username that is going to become the actual user name who made the comment and then we got this VF set to true that is going to become if the logged in user is the same as the user that made the comment we show this icon and this is going to be the delete comment icon and we need to pass two parameters in this delete comment function and that is going to be the current post and the comment ID and then under this we have all this lorem ipsum stuff we need to change that for comment text like that and now finally the last section create comment this needs to be if the user is logged in if user ID is a null and all the rest of this is good I think so we save it and we go to our page refresh right we've got a couple of Errors let's inspect and let's console what is this unhandled error execution of mounted Hawk we have root undefined and execution of before and mount Hawk okay let's have a look right yeah so when we Mount this so let's add in an async just to be sure we clear this out we're going to say selected post is null and then we want to add a try catch with an error and if the error.response status is 400 we push back to the main page and what we're going to do in this try section is a single function called get post by user ID like that now we're gonna have to go and make that so let's go into the side panel and then general.js and this function is very simple let's do it just above get random users we're just going to say get post by ID we're passing in the ID as a parameter and then we're saying post ID get and then we add that to the selected post and we get all of the IDS associated with the user as well so all the posts IDs and if you don't remember I'll show you so it's in post controller and it should be show and there it is so we get the post and all of the IDS and we're mapping them right there awesome right make sure we save that now let's go back into our browser what does this say let's hard refresh okay let's go back into our main page the home and now let's click on this post we have another execution of mounted hook let's go in this back into our post page oh I didn't save it save that let's refresh and there we go open it yes look at it look how beautiful that is let's close him down oh look at that beautiful man there's a single like we can't actually like anything yet because we haven't done that so let's do all of the functions that we need to do so the is like like post and unlike post we can go back to the main page no sorry it was in components and that was host main so the idea is liked like post and unlike let's grab all of this copy it let's go back to the post page and I'm just gonna drop this in under this watch just Chuck it under there and we need to make some small modifications so this is liked we're going to change post value for General Store selected post dot likes dot find and then this works exactly the same because that is a single post and then in like post we're gonna remove this if statement because we don't need it in there and if you remember in like post we have a variable that says is post page right there so if we go back in the post page and we add in selected post and is post Pages true we also need to do that for unlike post so get rid of the if statement and post becomes selected post and true save that now can we actually we've got a red heart that looks good if we click it oh look at it beautiful freaking awesome man okay last not done next is create a comment and delete a comment so let's jump back into this and now I just see it this post in the like post get rid of that and now we don't need that save it so let's go to the bottom after unlike post and we're going to say const add comment async open him up and we're gonna say try catch and our first function is going to be from the user store and that is ADD comment and we need to pass the current post and the comment then we need to clear the comment once that has been added and for mobile I'm just going to add in this which is going to be comments scroll to the top so if there's about 50 comments and you're at the bottom you make a new comment and it'll scroll to the top so you can see your comment awesome if I save that let's go into user store user.js and we're going to add in add comment let's do that under create post let's just say add comment and we wanna we're past passing the post in the comments let's open that up and this is very simple our end point for this is API comments and it's a post and we need to post the post ID and the comment and what we're going to do for this is say afterwards if status is 200 so it's successful we call another function called update comment and this is going to look like this so we're going to say async update comments open it up we're gonna pull our profile by ID endpoint then we're going to have to Loop through it so I've used a for Loop to say I and then we need to get this res and instead of array we're going to say res dot data dot post and then length to see how many posts there actually are associated with this user now let's just update this element to that res Dot data.post and then we iterate through and then finally all we do is say inside the for Loop if the post ID so this post that we're passing which is coming from this ad call comment is equal to one of these updated post IDs which comes from there we use General store.selectpost.coment and we update all the comments just like that so save that and now let's see if we can make a comment so let's go into our application let's bring this over and let's make a comment let's say this is the first comment and let's post it oh my God beautiful look at that like a charm okay so now we need to delete that comment so let's put this back over here Randy Savage smashing people with a tree awesome right back in our code we need the delete comment functionality so above update comments let's just put in delete comment open that up and this time we call the end point that is the delete end point for the comments like that so APA comments and the comment ID we want to delete and we pass the post ID and very simple at the end of this we say if status is 200 update comments just like that beautiful save it now let's go back into our post page we now need to make the delete comment functionality and that is going to be let's do it under add comment that's going to be constantly comment it's in async and we pass the post and the comment ID and let's open him up and first off we're going to put a confirm on there so we're going to say are you sure you want to delete this comment and let's put a little try catch inside it and if this comes back as true you want to delete it all we do is say if true user store delete comment and let's just double check let's find delete comment there it is and we are passing what we need to so the selected post and the comment ID so technically now this should work so let's go back to our application just give it a refresh just in case and now let's say delete are you sure you want to delete this comment oh okay and it's gone beautiful look at that amazing so fast awesome so now we should probably go and make if we close this we go back to the front page awesome we should upload some more videos because we need multiple to be able to um toggle through so let's do upload caption cool video and then I'm going to drop a video into this drop it in cool there's a little party and now I'm going to say post beautiful we got two posts now let me just make another one just so we got three let's just put anything for this doesn't matter select a file atoms that'll do and now let's say post there we go look at that this is working amazing let's go back to our main page oh look at it that is amazing and we like on this page yeah yes go back to our post Page look at that insane now we can see we've got these buttons for toggling through all of us single users posts so let's do those right let's scroll down right the first one is going to be const Loop through post down and let's open it up and I'm just going to put this in a little set timeout of 300 now we're going to say ID array reversed because we need to get all of the IDS associated with this user so all the post IDs associated with the user reverse them because we need to Loop through it and the only reason we're reversing it because this is down for the up one we don't reverse it but we'll get to that now so after that is break is equal to false by default and then I'm going to say four loop I and then this ID array reverse we're going to get the length of it then we want to iterate through so id id array reverse and then we're going to say if ID is less than root.params.id so the ID from there from the URL we want to say router push post ID so we go down to the one previous is break is true and return so I mean we stop it and if none of that is successful all we do is say if is break is false we want to go to the very first of the array yeah awesome save it right this is the what's this this is the down one let's just check make sure it is in there let's look for it yes it is in there Loop through post down so let's give it a try let's press down oh my God look at that try again oh yes down again back to three yes so that is a looping forever now let's do the loop through posts up right there let's go down and this is quite similar but let's just go through it let's open him up again a little set timeout inside 300 milliseconds and and for this we only have one local variable which is is break equal to false and then we're going to say four four Loop it index is I array becomes General store ids.length and then replace this array with const ID General Store IDs and the iteration and again this bit is pretty much exactly the same except if ID is greater than root dot params.id then we enter this and if we do not enter that at all we just say if is break is false we go to General store.ids.zero index of that array because remember this isn't reverse so save it and let's press up we should go to post number one oh yes look at it beautiful press up again yes up again one more time beautiful awesome man right so all we have left to do is this delete post and I did forget the authentication so we need to make a middleware as well so with Max this is super easy to do so let's do the delete post make the middle way and then we'll check to make sure we've done everything we'll make some users we'll make sure there's no errors and then that's it we're done so let's go delete post go in the code and we're just above add comment that'll do check it in delete Post async open him up and first we want to confirm are you sure you want to delete this post and then we're going to drop a try catch inside that and if res is true we want to say this we want to say delete post which we're going to have to go and make get the profile and then push back to our own profile so we can confirm that it's been deleted so let's save that and let's check to see if we put the lead post onto a button yes right there awesome so now let's go into our stores user.js and a scroll up this create post just underneath we're going to say delete post very simple endpoint is posts and we get the post ID we want to delete so axios dot delete save that and now we should be able to delete the post so let's try it let's delete number two this party one and let's click delete are you sure you want to delete this post okay uh yes done beautiful let's just go into our back end so our API and check to see if that's been deleted out of the files yeah it must have been because there's only two mp3s and if you look in the front we only have two MP3s so that's been deleted awesome right last bit and this is going to be the middle way so get rid of this API and in the front end open the side panel close all this we want a new folder called middleware like that and then we're going to say new file auth.js and for this we can just say export default Define next root middleware open them up we want two and from and then open that up now for this we need to import our user store so just above of to say import use user store from store user and then duck that into a const inside the middleware and this is super simple all we're going to do is say if 2 is not equal to the base URL and user store dot ID doesn't exist so there's a user is not logged in we want to get sent back to the main page and that is it so save it and then to use this next has made it nice and simple all we're going to do is go on pages and go through each page so post we want to put this on there so let's scroll up and all we do is say Define page meta and the middle way is off save it next page profile same again let's do it under show Define page matter middleware auth save it and finally upload and let's do it underneath all these variables paste that in Define page meta middleware off save it and now if we want to test this let's go into our page let's open it right up let's log out so go in this log out beautiful see we've still got two posts and if we try to like no we can't like because we need to log in the same as if we try to go to a post nope we need to log in if we click on these nope need to log in beautiful if we press upload need to log in as well and if you press login we definitely need to log in now if I go to the URL and I say forward slash profile one redirects us back to the front page which is perfect that is the authentication we just made kicking in the middleware so forward slash post slash one should yep we get redirected back this is working perfectly let's log back in one two three one two three one two three log in there is our login right there let's go to profile and now let's open one of these let's open this atoms one let's pull this over a bit let's make a little comment and post it let's do another one post it let's delete okay now let's see if we can delete this post so let's press delete okay that is awesome this like yeah I think this is all good we might as well make some new users so why don't we log out so log out and then go to login sign up let's do frankfrankitan.com and then any password sign up okay we signed up now we can see Frank let's go to profile edit profile bio this is Frank let's apply it awesome edit profile let's update an image what can we add that Netflix thing will do open and let's crop it apply yeah awesome okay let's close that we can see all that's working I have noticed that on this side bit we haven't included Frank so let's go and take a look let's quickly jump into the code and go to components register.view drill to the bottom and yes I didn't include it so underneath this get user we want to update all the random users save that and I think it's the same thing in login as well so let's go to the login let's go down yeah in there as well add those in right there get random users like that save that and now let's try it again let's log out and create another user let's log in just anyone just Fred Fred atm.com and again any password doesn't matter sign up and what happens let's inspect oh we've got an error let's give this a bit of a refresh let's look at our database I'm logging users so we've got two okay let's quickly trying to sign up again just put in anything again let's have a look sign up okay watch this in network cause error okay so let's clear this storage out so clear site data empty caching hard reload make sure that's cleared right out now let's try it again let's sign up and let's try yeah there we go awesome and you can see it on the side it's been updated we click on this we go to our profile thread awesome edit profile let's check any image in there let's get a bit of warrior in there way awesome apply and then let's just say and now let's just put awesome apply very nice updated down the side updated everywhere now let's upload a video Let's close this side panel let's say video One select the file let's get this little video that'll do post it yes this is working very good let's go to the main page there's our post let's like it we got one like on this let's link not as well because we're a different user let's like it let's go to this Randy Savage post because that's from another user and you can see we've got two likes unlike like it beautiful and now let's make a comment let's say cool bro post awesome we got Ultimate Warriors image we can't delete this post because it is in ours let's go to the next one number three amazing there's a comment on there let's make one let's put anything in post yeah look at that that is awesome and if I make loads of posts if I just keep going and go in like this and now if I scroll you can see we can scroll inside that which is awesome and if I scroll to the bottom and I just say new post and then I press post it Scrolls to the top awesome let's have a look in mobile view let's have a look roll at the bottom I'll just put awesome post throws to the top amazing we can see that's working let's exit all these down the side got a profile through yeah let's open this because he only has one post these buttons at the top are hidden drill down make a post yeah this is insane man let's exit this let's go to this Netflix one there's nothing in this and oh there's one little bit that I forgot this likes I've actually made that dynamic as well so let's quickly go and do that that's like five seconds going through the post page no sorry the profile page and in this store the refs we're gonna say all likes and then if you scroll up to line 36 this 10K no 44 the 3K we're gonna replace with all likes save it now you can see we have zero likes let's go to Fred zero John week's Dev zero okay let's hook that up let's go into stores profile.js let's close this side panel and we're going to make a quick function called all likes count open it up we start off by saying this all likes is zero so we set it back to default which is zero and then say four Loop it I we get all of the posts so post there we can replace this const with post equals this posts and iterate and then inside of this we need to Loop through the likes like that Loop follow the likes and then say plus plus and all we do is take this all likes count function and drop it in the bottom of this get profile function save it and let's go oh wait what happened door profile oh I forgot a comma or a comma on that let's go back and there we go four likes beautiful let's go to Frank zero likes thread one like that's it I think we're done we're finished and it looks amazing let's open this uh look at it insane let's delete that yeah that's it we're done we have officially finished Tick Tock and my God building this took me ages
Info
Channel: John Weeks Dev
Views: 35,600
Rating: undefined out of 5
Keywords: nuxt, nuxt js, nuxt 3, vue, vue js, vue 3, laravel, laravel sanctum, laravel spa authentication, laravel authentication, laravel api, laravel api tutorial, tailwind css, tailwind css tutorial, axios, axios interceptors, pinia nuxt 3, pinia vue 3, pinia vue 3 authentication, php, javascript, intervention image, intervention image laravel, tiktok, tiktok clone, tiktok clone app, file upload in php, file upload in javascript, john weeks dev, nuxt pinia, build a tiktok clone
Id: CHSL0Btbj_o
Channel Id: undefined
Length: 227min 39sec (13659 seconds)
Published: Mon Mar 20 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.