Transcript for:
Building a Web3 Crowdfunding Platform

web3 has the potential to change the internet as we know it forever you're still early in catching the trend right now and building your first blockchain application hi there and welcome to a project video where you'll build and deploy a web 3 crowd funding platform and let me tell you I haven't been this excited about a project for a long time with a stunning design connected to the blockchain metamask pairing interaction with smart contracts sending ethereum through the blockchain network writing solidity code and most importantly the ability to create View and donate to crowdfunding campaigns directly through the blockchain this video is perfect to fully understand how web3 blockchain solidity and smart contracts truly work behind the scenes on top of learning the web three side of things I'll also teach you how to create a fantastic user interface using tailwind and follow the best UI ux practices for responsive design there are many tutorials out there that are hard to understand they jump between many Technologies and are almost impossible to follow today you'll learn how to develop a professional and fully functional crowdfunding application using the most in-demand Technologies and even deployed to the Internet so you can share it with your friends employers and put it on your portfolio you might be wondering what are the prerequisites for building such a fantastic website don't worry this course is entirely beginner friendly besides a little reactionist knowledge no web3 blockchain or solidity knowledge is required think of this as your first real blockchain application we're going to start easy and then move to more complex topics I will explain every step of the way in this video you'll learn how to connect a regular reactions application to the blockchain and pair it to your ethereum wallet using metamask you'll also learn how to write smart contracts on the ethereum network using the solidity programming language essentially in this single video you'll learn how to create a full-fledged web 3.0 application that allows users to send transactions through the blockchain each transaction will belong to a specific crowdfunding campaign and it will be forever stored on the blockchain and all of this is made possible by Third web third web is a web 3 development framework that allows you to create release or deploy your smart contracts with a single command they are free open source and from a personal experience their main benefit is Simplicity as web 3 is relatively new the developer experience in most cases just isn't good and third web fixes that today I'll teach you how to write a smart contract and deploy to the blockchain with a single command using third web in just a couple of seconds you'll be able to explore your smart contract inside of thirdweb's intuitive dashboard you can see all of your write and read commands code examples and you can even copy the deployed smart contract address directly from the dashboard I'm fascinated with the developer experience third web provides and I hope you'll start sharing that same enthusiasm that I have by the end of this video If this video reaches 20 000 likes I'm recording more web 3 dab videos so smash that like button with that said there's just one more important announcement I want to share with you before we dive into the project since this is a web 3 heavy project-based video I've also prepared for you to entirely free web 3 resources one is a comprehensive web 3 roadmap and the other is a solidity cheat sheet the link to download these resources entirely for free is in the description with that said let's Dive Right into today's video [Music] before we begin please allow me to give you a quick demo of the application that you'll build so you have better idea of all the great functionalities you'll build a crowdfunding platform to help bring creative projects to life people can decide to build a car from scratch save nature build a Hope Village or a restaurant business and then other people can fund these campaigns in cryptocurrency to support the project currently we're looking at the home page where you can see all campaigns you can click on create a campaign button to start creating your own campaign once you create it you can click on your profile icon to see all your active campaigns finally if you want to see more campaign details you can click on a specific campaign here you can see the number of days left until the end of the campaign the currently raised amount and the number of people that supported the campaign a bit below you can see the creator that created the campaign a story behind the project and a list of donators most importantly you have a fun field where you can enter the amount of Eid that you would like to contribute to the cause and as soon as you click the fund button a metamask notification will appear and you can make your contribution with that said let's dive straight into the development of her great application we can start from the bare Beginnings by creating a new empty folder on our desktop let's call it crowdfunding it only makes sense right once you create it simply drag and drop it into your empty Visual Studio code window Visual Studio code is the most popular and most widely used editor out there once you open up your empty folder we can immediately dive into creating the file and folder structure of our application we're technically building a full stack web3 application which means that we're going to have two different sides of our application the first side is going to be the client side where our react code will reside and then we're gonna also have our web3 side of things so to initialize our blockchain environment we can go to view and then terminal inside of here we can run a simple command MPX third web add latest create dash dash contract this is going to start a command line interface that's going to ask us questions and then it's going to set up the environment for us in here we have to choose the name of our project so let's simply say web3 then we can press enter to choose hard hat and then we can choose the name of our smart contract in this case it's going to be crowd funding and we want to start with a completely empty contract because as you know here in JavaScript Mastery I always teach you how to do everything from scratch so you can do things by yourself so let's press enter while the packages are being installed let me quickly share with you a new third web platform called explore it's a place where you can discover and deploy smart contracts from the best web3 developers out there this effectively expands your capabilities as a developer and gives you access to the full power of web3 once you find a smart contract that you want to work on and that fits your needs you can deploy it to any blockchain with just one click and third web will automatically generate an SDK for you to interact with your contract from within the application and they will also generate an intuitive dashboard for you to manage your smart contract it is as easy as opening the contract and clicking deploy now third web Explorer is an amazing platform for every web3 developer there we go inside of our directory now we can run several commands we can run build deploy and release we're going to explore these later on for now let's simply CD into web3 and let's clear our terminal now we can start exploring what do we have inside of there you can see that we have a contracts folder with our smart contract and then we also have a hard hat Dot config.js finally we have our package.json where we can see the scripts for those commands and our Dev dependencies we want to make our app as secure as possible which means that we're going to use environment variables so we can simply run npm install and we're going to install a simple package called dot EnV this took just a second and we can instantly see it appear right here this means that we are ready to start developing our smart contract so let's go into the contract.soul file meaning a solidity file and let's rename it to crowd funding dot Sol we can also rename our contract to crowdfunding there we go and believe it or not this early in the video we're actually diving right into code I'm gonna teach you how to build this smart contract from scratch so to get started we're first going to create something known as a struct think of it as an object in JavaScript we can give it a name in this case it's going to be called a campaign a crowdfunding campaign inside of there we can specify the types that this campaign object will have it's going to have an address and that address is going to be called owner it's also going to have a title but we have to specify a type of the title so we can say string title solidity is a strictly type language meaning that you have to specify a type for each specific property then we're going to have a string of description we're going to also have a uint 256 which simply means a number that's going to be called a target the target amount we want to achieve we're going to also have a un256 for the deadline we're also going to have a un256 for the amount collected finally we're going to have a string for image the reason why our image is a string is because we're going to put a URL of the image right here finally we can have an address but it's going to be an array of addresses of donators and we also want to keep track so you went 256 but again an array of the actual number amounts of our donations there we go and this is all that we need to create our campaign now in solidity there is something known as a mapping so we have the same mapping you end 256 and then an arrow meaning equal sign and then greater than sign that's going to point to a campaign and we're going to denote that as a public campaigns essentially in here we created a mapping that now we can use campaigns zero this is something that we can natively use in JavaScript but in solidity you have to create a mapping to be able to access it this way finally we're going to create a global variable uint 256 public number of campaigns and at the start it's going to be set to zero we want to be able to keep track of the number of campaigns we have created to be able to give them IDs finally we can dive straight into the functionality of our program we can first create the structure of all of the functions our smart contract will have that's going to be function create campaign we need to have a way for us to create a campaign right then we're going to have another one function donate to campaign there we go looks like this our third function is going to be function get donators this is going to give us a list of all the people that donated to a campaign and finally we can have a function to get a list of all campaigns we're going to call it get campaigns there we go we have a structure and we have a mapping a public variable and finally four different functions that are going to contain the entirety of all the logic of our smart contract so with that said let's start with the development of our first create campaign function to start creating our create campaign function we can first specify what parameters is it going to take in so we're going to take in the address which is going to be the owner but just to know that this is a parameter only for this specific function we're going to give all parameters an underscore before so that's going to be the address of the owner then we're going to have a string memory equal to underscore title like this that's going to be the second parameter then we can dive into our third one string memory underscore description we're also going to have a uint 256 underscore Target another one you win 256 underscore deadline string memory underscore image you can notice that we need this memory keyword with every single string and these are all the parameters that we need as you can see it's mostly what we already defined right here needed to create a campaign now in solidity you have to specify if this function is only internal or if you can use it from our front end so since this one will be public we can add a public keyword right here and then we even have to specify what is it going to return so we can say returns inside of parentheses you and 256. once we create a campaign we want to return the ID of that specific campaign you can see this might be a lot of code but it's actually going to save us a lot in the future because we have specific rules on what needs to happen we need to accept all of these parameters and then return a number with that said let's create a new campaign by saying campaign storage campaign is equal to campaigns and then the number of campaigns as you can see at the start it's going to be zero which means that we'll be populating the first element in our campaigns array later on we're going to increment that number so that's going to be the way in which we're going to fill up our campaigns array after that we're going to put a require statement and a require statement in solidity is like a check it is a test to see if everything is good so let's write here is everything okay so inside of here we can write campaign the deadline is lower than block dot timestamp that's going to be the current time and then if that is the case if the date of the deadline is before meaning in the past then we can provide an error message saying something like the deadline should be a date in the future there we go now our code is not going to proceed further if this is not satisfied but now if we are okay with that then we can say campaign that owner is equal to underscore owner we can also say campaign dot title is equal to underscore title notice how we started filling up our campaign we can say campaign dot description is equal to underscore description campaign dot Target is equal to underscore Target campaign dot deadline is equal to underscore deadline campaign dot amount collected is equal to zero at the start and campaign dot image is equal to underscore image finally once we set that up we can increment the number of campaigns so that's simply going to be number of campaigns plus plus and then finally if everything went right we can return number of campaigns minus one this is going to be the index of the most newly created campaign great now in this case it looks like we have a warning saying that the member deadline is not found or not visible after argument dependent lookup in the struct crowdfunding so let's go here to destruct and it looks like we have an error this right here was supposed to be that line great and also for the blog.timestamp it looks like I misspelled it so that's going to be time stamp this is what I liked about statically typed languages they save you in so many cases which is exactly why typescript became so much more popular great with that said our first function create campaign is now done so we can click right here to collapse it and we can move to our second function donate to campaign or donate to campaign is going to be be a bit simpler at least when it comes to the parameters it takes in it's going to take just one single parameter U and 256 that's going to be called underscore ID we need to get the ID of the campaign we want to donate the money to and it's going to be public and it's going to be payable this is a special keyword that signifies that we're going to send some cryptocurrency throughout this function instead of here we can create a new variable un256 called amount and we're going to set it equal to message MSG dot value this is what we're trying to send from our front end we're then going to get the campaign we want to donate to that's going to be campaign storage campaign equal to campaigns and then like in JavaScript we put the square brackets and then the underscore ID to access it keep in mind this campaigns right here is the mapping we created at the top now that we have our campaign we want to donate to we can say campaign dot donators dot push MSG dot sender so we want to push the address of the person that donated and we also want to say campaigns that donations dot push and want to push the amount let's fix this little arrow right here that's supposed to be campaign and finally let's make the transaction inside of parentheses we can say bull sent this is going to be a variable that's going to let us know if the transaction has been sent or not is equal to payable campaign dot owner we're sending it to the owner of the campaign dot call and then in curly braces value is going to be equal to amount and then we can call it like this that's going to be parentheses and then inside of there simply an empty string finally at the bottom we can say if sent campaign dot amount collected is equal to campaign that amount collected and we're going to increment the amount that just came in great it looks like we have a warning right here different number of components on the left side than on the right side this is because payable returns two different things and right now we're accessing just one so we have to add a comma to Let's solidity know that something else might come afterward as well and with that said our second function is done as well we can now create campaigns and we can donate to campaigns but what good would that be for if we cannot fetch the donators to see who donated on a specific campaign and also we cannot yet fetch the campaigns so let's get started with the get donators function our get donators function is going to be similar to the donate to campaign function at least when it comes to the parameters it takes in to be able to get donators we need to know of which campaign do we want to get the donators from so we also need to pass in the U.N 256 underscore ID in this case this is going to be a view function meaning it's only going to return some data to be able to view it it's also going to be public function and it's going to return this time an address rather an array of addresses in memory so something that we stored before and the second parameter is going to return is going to be an array of numbers also stored in memory you already know what this is in this case this is the array of addresses of donators and then the array of the numbers of the Nations great so how will that look like well you simply type return inside of parentheses campaigns square brackets underscore ID Dot donators and then comma campaigns ID dot donations make sure to put the underscore ID right here and that's going to be it we simply return something from our campaigns mapping and with that said we are ready to move to our last function which is the get campaigns function this function takes no parameters because we want to return all campaigns it's going to be a public view returns and what do we want to return from this one well I think you can guess it we want to return an array of campaigns so that looks like this and we're gonna get them from memory instead of here we need to get all campaigns so we can say campaign array in memory all campaigns is equal to new campaign array and then instead of parentheses number of campaigns now let's quickly fix this return to return to the top and let's go over by explaining what this is you can see this part of syntax was a bit weird I'm not gonna lie so what we're doing is we're creating a new variable called all campaigns which is of a type array of multiple campaign structures so in this case we're not actually getting the campaigns rather we're just creating an empty array with as many empty elements as there are actual campaigns that's why we have this variable number of campaigns at the top so for now we simply have an empty array of that many empty structs as we have actual campaigns created now is our time to Loop through all of the campaigns and populate that variable so we can say for U and I is equal to zero while I is less than number of campaigns I plus plus then we want to get a campaign from storage and let's call it item and we're going to Simply populate that to the campaigns I finally we can set the all campaigns I to be equal to that item in this case we're fetching that specific campaign from storage and we're populating it straight to our all campaigns finally the only thing we have to do is return all campaigns now the function is not going to complain as it is returning exactly what we specified right here and believe it or not with that said we are done with our smart contract this one took about 70 lines but trust me while I was developing it the original version of the smart contract contained about 150 lines it is just with a bit of refactoring and making sure that we only have what is needed for our application to work that I was able to bring it down to 70. with that said hopefully now everything makes sense and we are ready to deploy this smart contract so that we can use it on the front end usually the deployment is the toughest part of web3 development everything is so slow nothing works you have to use a lot of additional tools websites and programs to be able to deploy your smart contract to the web but third web has covered every single part from development to deployment so now we can close our solidity contract and we can go to our folder and we can look into our hardhat.config.js we just have to ensure we have a couple of lines of code here so that we can properly deploy our contract before all we have to have our own metamask wallet to download metamask which is currently the most widely used crypto wallet simply go to metamask.io and click the download button that's going to redirect you to the Chrome web store and click add to Chrome after you do that this cute Fox is going to appear and you're ready to start with installation so let's click get started let's click I agree in this case we're going to create a new wallet and you have to choose a password simply type it two times and agree to the terms of use finally I would strongly recommend you to watch this video it's a one and a half minute video where metamask teaches you how to save your private Keys essentially in just a moment you'll be given your secret recovery phrase which is a set of 12 words that are a password to your account now in my case I'm gonna use my wallet simply for education purposes and no real funds will be stored there but if in the future you plan to store some real cryptocurrencies there make sure to write this down and save it securely with that said we can click next in this case I'm going to share my secret recovery phrase with you by copying these words and clicking next you can write them down on a piece of paper once you do so I'm gonna paste them right here and now we have to select words in order so in my case I have word area heavy envelope summer intact Timber Brown trade Frame Book and second and we can click confirm there we go finally you can see your wallet appear right here what you have to do is click this ethereum mainnet click show and hide test Networks and then toggle that on after you do so you can open up your extensions and then you can pin metamask that way it's going to always appear right here so now if you click right there you can close this and you can switch from ethereum mainnet to girly test Network finally we have to get some funds so simply copy your account address to clipboard and go to girlyfosset.com there you can paste your address and they're going to immediately send you some test ethereum isn't that great if we now close this open up our wallet and wait a couple of seconds you should be able to see your girly eat appear right in front of you and there we go while I was talking it just popped up that means that now we have our wallet address and we are ready to go but we have to get our private key so go to these three dots Account Details and click export private key type in your password and then you can copy your private key from here you can click done go back to your code and now we can store that key inside of our environment variables so simply right click on the web3 folder and create a new DOT EnV file there you can say private underscore key is equal to and then you can paste your key right here inside of her getting nor make sure that the dot EnV is there that means that it won't be pushed to GitHub great that means that now we can use our private key to connect to the girly Network back in the browser just a simple search for girly RPC immediately takes you to this page where you can get your girly test net endpoint you need this to interact with the blockchain so you can copy that from here and then back in the code we can start connecting to our Network above our settings we can say default network is going to be set to a string of girly then we can say Networks is equal to an object inside of there we can say hard hat and then put it as an empty config but then we can say girly is equal to an object where the URL is equal to this RPC we just copied if you didn't find it on the web you can simply copy it from me it's https colon forward slash forward slash RPC dot a n k r.com forward slash eth underscore curly and then you can add accounts that is going to be an array of accounts that starts with a template string of 0x and then process.env dot private underscore key this is the account which we're going to use to deploy our smart contract and that's all that we have to do inside of our hard hat config with that said we can go to our package.json and run a single command third web deploy so right here we can clear our terminal make sure that you're in the web3 folder and run npm run deploy this is going to run the MPX third web latest deploy script there we go detected project type hard hat it is immediately compiling it and it even created the artifacts finally it has been processed and it's now uploading contract data straight to their dashboard and there we go upload successful open this link to deploy your contracts so let's control click it and now in the browser you can now connect your newly created wallet using metamask by clicking next and connect you can see that it picked up that we have 0.5 girly eth and we want to add it to the dashboard so make sure that this is sticked and click deploy now another metamask notification will appear and we can click confirm our deployment is now loading and as you can see this action will trigger two transactions which means that we're now waiting for that second transaction while the first one is pending there we go a second transaction appeared if it didn't automatically pop up simply click right here and then click confirm let's wait a couple more moments and our contract will be deployed and there we go success successfully deployed smart contract and as you can see we are immediately on this beautiful and intuitive third web dashboard I think that now you can see what I meant when I said Simplicity and everything simply works this is not something we're used to When developing on web3 because everything is new and unpolished but this right here simply looks so polished you have a graphical user interface and you can see all of the write and read functions that we have created in the smart contract more importantly we can go to code and this immediately tells us how we can start using this contract from within our code don't worry I'm gonna teach you how to do all of this so with that said the first part of our great application build has been completed our smart contract is developed deployed and live on the internet with an address right here that we can copy to clipboard and and use to connect it to a react application so let's go ahead and create that react application to get started we can get back to our Visual Studio code CD dot dot to get back to the root and then CD into our client repository we can close our currently open files and we can run MPX third web create Dash Dash app and press enter we need to install the following packages so press Y and then enter now the CLI is asking us what is our project name I'm just going to type dot slash to create it in the current repository we can use nextgs create react app or even veed so let's go for weed we can create a nextgs app a create react app or even a Vita app so let's go with Veet we're going to do it in JavaScript and that's it our react application is getting initialized you can pause this video wait until your installation is complete and then you can continue and there we go our application has been initialized now we can go into the package.json to see the commands and scripts and dependencies that have been installed as you can see we can run our application by running MPN run Dev which is going to run the Veet command and also we have third web dev react third web dev SDK the ethers package and finally react and react Dom now in this case we're gonna need just one more package which is react router Dom to enable routing so let's open up the terminal one more time and let's just type npm installed react Dash router Dash Dom that installed in just a second and we are ready to run npm run Dev to see what's gonna happen our application is up and running and we can control click this URL and there we go in just a couple of seconds we can see welcome to third web get started by configuring your desired Network and source main.jsx great we can also immediately connect our wallet which is a really handy feature that third web provides out of the box with that said we're going to do things just a bit differently you're here watching this video right now and you want to know how can you build this from scratch without all of these Styles app.js main.js and so on so what we're going to do is I'm going to delete the entire Source folder and then we're going to create it from scratch by creating a new SRC folder inside of the client folder there we're going to create a new index.js file that is the starting point of every single react application to get started we can import react from react we can also import react Dom from react Dash Dom forward slash client we can also import browser router as router coming from react Dash router Dash Dom let's spell that properly and finally we can import chain ID as well as third web provider coming from at thirdweb Dash Dev forward slash react then we can create our react root by saying const root is equal to react Dom dot create root document dot get element by ID root and then finally we can say root dot render and there we can pass the third web provider that's going to be a wrapper for our entire application there we have to pass a desired chain ID which is going to be a chain ID dot Gurley if you control click into this you can see that this is nothing more than a number five but it's really handy that third web provides us this great utility called chain ID to immediately just put it like this and not just put 5 as a magic number which is not a good practice in coding finally we can wrap everything with a router as well and inside of there we can have our app so of course let's go ahead and create that app inside of the source that's going to be app.js inside of our app for now we can simply run rafce rafce is a command coming from Snippets one of the extensions right here es7 plus react Redux react native Snippets so install that run refc and it's going to immediately generate this code this is all that we need in here so far and we can import that app inside of our index simply by saying import app from dot slash app and finally we are rendering it right here now if we go back to our app we can see that it simply says app so if we go back and reload but we cannot seem to see anything here back in our code switching the main to main.jsx and app.jsx as well might make things work if I'm not mistaken we had that jsx there before we deleted the source folder in the first place so now if we go back we can see the app keyword right on the top left of our browser that means that we have successfully set up the most basic structure of our application now I almost forgot we also have to add Tailwind to our application as we'll use it to simplify the process of writing rcss the process of installing Tailwind with veed is quite simple you can go to tailwindcss.com forward slash docs forward slash guides forward slash wheat and then right here we can copy this command npm install Dash D Tailwind CSS post CSS and auto prefixer so back in your code we can open up our terminal stop it from running and then we can run this command great that was completed in nine seconds and now we can copy the second command MPX Tailwind CSS init Dash p this is going to create a tailwind.config file back here we can configure our template pads by copying the content part of our Tailwind config so we can override an empty content part right here finally we have to add detailing directives to our CSS so let's copy these three lines and we're going to add them in a new file that we're going to create inside of the source folder called index.css there you can paste those three lines as a matter of fact Down Below in the description you can find the entire index.css file for this application and you can copy and paste it as you can see the finished file is nothing more than those three lines but we also created some linear gradients so we can utilize them later on as well as imported the font great that's going to be it for our Tailwind installation now we can set up the rest of the file and folder structure for our react application down in the description as well you can find a link to the assets folder simply download it and then paste it right here inside of there you can find a lot of different loaders logos svgs different icons and everything exported from a single file I wanted to ensure that you have everything needed to focus on what matters which is coding the logic of our application then we can create a new folder called constants inside of there you can create a new index.js file this file can also be found in the GitHub just down below you can copy and paste it right here this file contains no logic simply some navigation links which we can map over later on with the image URLs included then we can create a new folder called context this one is important inside of here we're going to create a react context API that's going to allow us to use the third web logic from within our entire application then we're going to need the components folder we're going to also need the pages folder and finally we're going to need the utils folder inside of the utos folder we're going to have one file called index.js utils is short for utility functions some functions that we reuse often across our page this file is also going to be down in the description in here we mostly have some simple logic such as calculating the days left from the date calculating the bar percentage depending on how much money was donated and finally checking if the image is all right the URL of the image that we add to our campaign as you can see nothing major just about 20 lines of code with that said now we have everything we need to start developing our great application and of course everything is going to start from app.jsx from within here we're going to create our basic application layout to get started creating our layout we can import react from react we can also import the route and routes coming from react Dash router Dash Dom then we can create our wrapper div this div is going to have a class name equal to relative on small devices padding Dash 8 meaning p-8 usually p-4 BG Dash inside of square brackets we can put hash one three one three one a it's going to have a Min Dash H dash screen property for 100 VH and it's going to be flex and flex row now if you are unaware of what these properties are doing these are Tailwind utility classes so you can go to Tailwind CSS go to docs and then use this quick search to search any single property you're interested in for example we use the Min Dash H dash screen and you can see that this is going to be for minimum height you can also go to spacing and then padding and see that we can use p x p y or other utility classes to specify padding essentially everything you can do with regular CSS you can do with Tailwind shorter and more quickly so while watching this video if you're unaware of what some of these classes do such as Flex or Flex row simply go to Tailwind CSS docs and then search for them right here and you'll get a detailed explanation with that said we can go back and now it'd be a good time to put our browser side by side buyer editor so we can see the changes we make live and there we go my browser is on the right side now and and let's try typing app inside of here if you save the file and reload the application we should of course get an error because we forgot to rerun our application trust me it happens so let's simply run npm run Dev to rerun it on the same port immediately you can reload and we can see app right here with that said let's continue creating the layout of our application by creating an inner div which is going to be a wrapper for our sidebar so let's give it a class name on small devices Flex usually hidden margin right of 10 and then relative inside of here we're going to have our sidebar component now below that we're going to have a new div and this div is going to have a class name equal to flex-1 on Max Dash SM devices we're going to have a w Dash full meaning with full and then usually Max Dash W is going to be 1280 pixels margin X is going to be set to Auto and then on small devices padding right is going to be set to 5. inside of here we can show our navbar component now it seems to me that these classes are not being applied so maybe our feed configuration is not properly reading our Tailwind config so if we go to our tailwind.config.js we can verify that our content is all right and also from within down in the description you'll be able to find a theme setting so right here you can override that theme and that's going to give us access to this special epilog font and the Box Shadow we're going to use later on but that's not going to fix our issue with Tailwind so before we dive into further debugging let's do a test to see if Tailwind is really not working let's create an H1 and let's say test we can see it right here and if we give it a class name and if we transform it to just a regular P you can see it becomes smaller but now if we give it a class name of font XL and also Fawn Dash bold it should become extra large and bolded but it Remains the Same which means that these Styles indeed are not working and I just remember we forgot to import the actual index CSS file within our index.js file so below the app simply say import dot slash index.css and there we go immediately you can see that the background change to dark which means that Tailwind is working great now we have our sidebar we have our nav bar but we have to specify the routes So Below the nav bar we can say routes and we can specify each individual page that we're gonna have on our application in new react router Dom you have to say path forward slash to specify the root route and then say element in this case it's going to be a home component of course we're going to get an error because we haven't yet created this home page we also don't have the nav bar or the sidebar pages so now might be the best time to create all of the files all the pages and components so that we can simply import them whenever we need them let's start with Pages we can create a new file called home.jsx and there you can run rafce inside of it then you can create another one called profile.jsx and again run rafce inside of it finally there are two more pages campaign details dot jsx you can run rafce and the last one is create campaign .jsx where you can also run rafce with that said the last missing piece of the puzzle is an index.js file that's going to export all of these components so let's say export default as home from dot slash home like this and now we can duplicate this three more times the second time we want to export the profile the third time we want to export the create campaign and finally we want to export the campaign details now if we close all of those files go back in the app we can now freely import those pages so let's say import campaign details create campaign home and profile all coming from dot slash pages and the error is gone and we can see a piece of text that says home which is exactly what we want to see because that's the only thing that the home component currently has great now we can also repeat the procedure by creating two new components one called sidebar.jsx we can again run rafce and the last one called sidebar Dot jsx and another one called navbar dot jsx where we can also run rafce remember we also need to export them so let's say index.js from within we can say export default as sidebar from dot slash sidebar and we can repeat that for the nav bar now back inside of our app above the pages we can import sidebar and nav bar from dot slash components and we can turn these two pieces of text into actual usable components of course we have to close it right here there we go we have the nav bar we have the home and just to verify we can change something in the nav bar to see if the changes are reflected and they indeed are with that said our basic structure is now done and we can start focusing on the sidebar navbar and our home page component sidebar and nav bar are the simplest possible components but they usually take the most time because you have to make them responsive you have to have that hamburger menu on the mobile and everything has to look great but we immediately want to see something on the screen let's start by creating the sidebar component first so we can control click into it and we can start developing it to start developing our sidebar we can first import react as well as use State coming from react then we can also import the link component as well as the use navigate coming from react Dash router Dash Dom finally we can import the logo as well as the sun icons coming from assets and finally we can import the nav links coming from dot slash constants this is all a part of the code that we provided for you before starting with this video again mostly assets and some constants great with that said we can start developing our nav bar first we can initialize the cons navigate is equal to use navigate and we call that as a hook that's going to allow us to Traverse the different pages later on and we can immediately create a new use State field by typing use State selecting the snippet and let's call it is active set is active and at the start the dashboard field is going to be set to active just to show you what we are building I opened up our finished version of the application and as you can see we're going to have this logo on top left which might be a part of the nav bar but then when it comes to the sidebar we're going to have all of these icons and links that we'll be able to click so let's continue developing it first we're going to have a div that's going to wrap our entire sidebar that div is going to have a class name equal to flex justify Dash between items Dash Center Flex Dash coal sticky top Dash 5 and then h-93 v h immediately inside of there we can create a new link this is going to be a link component that's going to have a two property going to forward slash meaning home and inside of there we can render a new icon component this icon component is going to be used just here within the sidebar so we can immediately create it right here by saying const icon and that's going to be a basic react functional component it's going to have an instant return so we can simply put parentheses right here it's going to be a div and before we start adding anything to it we need to know what props can we pass to that icon so if we go right here we're going to pass some styles for example W Dash 52 pixels and h-52 pixels as well we can also give it a BG Dash hash 2c2f32 and finally we can give it an IMG URL which is going to be set to logo later on we're gonna also pass the is active state to our icon so we know should we highlight it or not with that said we can now accept those props at the top so let's accept the Styles the name imgurl is active disabled and handle click all of these are properties that we're going to later on pass to our icon component now we can start focusing on the class name so let's do class name is going to be a template string where W is going to be set to 48 BX H is going to be set to 48px as well for the height rounded dash 10 pixels and now we have to know is it active or not and we can say is active and end is active is triple equal to name and then we want to show the BG Dash hash 2C to f 3 2. and we can close the string there we go so now if we are active we're going to give this special background color which we can see right here around this icon there perfect moving on it's also going to have a property of flex justify Dash Center item slash Center and also Dynamic string of if not disabled then cursor Dash pointer like this and finally we want to also give it all these styles that we passed later on through props for example right here now if we save this nothing's going to happen because we have nothing inside of that div so let's say like this if not is active then we want to show something that looks like this a self-closing image stack that image tag is going to have a source equal to IMG URL it's going to have an ALT tag equal to fund underscore logo and it's going to have a class name equal to W dash 1 over 2 and H dash 1 over 2 as well that's going to be it for our image now we can copy it and we can create the or Clause right here below finally to this one we're going to give some additional class names so let's make this dynamic a template string there we go and then we can say dollar Center Graces if is active is not equal to name then we can give it a gray scale color there we go so now if we save this we cannot seem to see anything yet I think that's because the sidebar is not showing on this screen but if we extend it just a bit you can see it is there so right now we're working on the desktop version of the sidebar which means that we do have to have some width that's fine so we can collapse our Visual Studio code but then it's going to be hard to code that way so let's keep the visual studio code right here but then we can click to see what we have done great and also we have to provide an on click to our div and that on click is going to be handle click now we have created this special icon component that we can reuse later down the line below our link we want to create something that looks like this where we're going to have a sidebar so if we go back we can go below our link and create a div component this div is going to have a class name equal to flex-1 flex Flex Dash cold for the elements to appear in a column justify Dash between items Dash Center BG Dash hash 1c1c24 rounded Dash 20 pixels and W Dash 76 pixels padding y p y 4 and then Mt 12 for margin top inside of which we're going to map over all the links so this div is going to have a class name equal to flex Flex Dash call justify Dash center items Dash Center and gap-3 inside of there we can finally create a dynamic block of code and say navlinx dot map we're going to get each individual link and we want to have an instant return meaning simply parentheses we want to render a self-closing icon component since we're mapping overhead we need to give it a key equal to link.name and we're going to also spread all of the link properties like this we can also pass the is active State and we need to pass the handle click handle click in this case is going to be a callback function where we have to check if not link.disabled only then do we want to set is active link that name and we also want to navigate to link dot link there we go all of this is inside of the nav links you can see each link has a link and then we also have disabled on some of the links because we can only move between the first few great and if we now go back to our browser you can see our beautiful sidebar appear right here we are a bit too much zoomed in so I just figured out that we might be able to see it right here as well if we just zoom out to the normal width great so now we have our beautiful sidebar and it is looking close to this one but as you can see there's one icon on the bottom of the finished application so let's finalize that below this inner div we can create one more icon that's going to be a self-closing icon that's going to have styles equal to BG dash one hash one c one C two four and a Shadow Dash secondary finally it's going to have an IMG URL equal to Sun if we save this you can see this appear right here and there we go you can see that some icons you can hover over and then it means you're clickable and they actually change the page which is perfect and the other ones you cannot click on so in this case we have the dashboard we have the create a campaign and we have our profile perfect with that said we not only have the sidebar but we also have the navigation of our application done because as you can see we're in the home if we switch we cannot see that home anymore and we cannot see the profile trade with that said we can close our sidebar and we can move to our nav bar the only other component that's going to be visible across all pages so let's control click the nav bar and let's start developing it to start developing our navbar we can also import use state coming from react and then we can import the same link and use navigate components coming from react-router Dash Dom because navbar will also be used to Traverse our application with that said we will need one custom component and that's going to be a custom button so let's create a new component called custom button.jsx inside of there we can create rafce and for now we can let it be but let's not forget to export it so inside of the index.js you can export the custom button there we go so now inside of our nav bar we can say import custom button and that's going to be coming from dot slash as we are already inside of components then we can import the logo menu search and third web icons coming from that slash assets and finally we can import nav links coming from dot slash constants great now inside of the nav bar we can initialize our navigate function by calling the use navigate hook and inside of here we're gonna also have that same is active state so let's create a new state let's set it to is active set is active and at the start it's going to be set to dashboard we're going to have another one called toggle drawer so let's create a new use state and let's call it toggle drawer and at the start it's going to be set to false there we go now we can immediately dive into the layout of our navbar just to remind you this is how it looks like it has a search page it has a connect button and a profile icon logo great so we're gonna have a wrapper div that's going to have a class name equal to flex on medium devices Flex Dash row usually Flex Dash called Dash reverse this ensures that on mobile devices we show the connect on top if we do it like this you can see we have this drawer if we open it then we have the connect and all of the other properties there we go and if we go back this is looking great finally let's give it a Justified Dash between property margin bottom of 35 pixels to divide it a bit from the content and gap-6 to divide the elements of course we cannot see anything There Yet now inside of this Dev we're going to have one more div this div is going to have a class name equal to on large devices flex-1 usually Flex Dash row and we want to give it a Max Dash W Dash 458 pixels this is for the maximum width of the nav bar we can give it a padding y meaning padding on top and bottom two and padding Left 4 and also padding right two to divide it a bit from the content height of the nav bar can be 52 pixels so we can specify that right here and then the background can be hash 1 c 1 c 2 4. now if we save this you can see this small rectangle appear right here but no content as of yet now inside of there we can create a wrapper for the search so let's give it a class name equal to W Dash 72 pixels H dash full rounded Dash 20 pixels BG Dash that's going to be hash for a CD 8D Flex justify Dash Center items Dash Center and cursor Dash pointer we're creating this button that's going to appear right here and inside of that Dev we can show the self-closing image tag that's going to have a source equal to search alt is going to be set to search as well and finally the class name is going to be like this w-15 pixels h-15 pixels for the height and object Dash contain if we save that you can see this button appear right here now above that div that contains this image we can also create an input tag that's going to be a self-closing input of a type is equal to text it's going to have a placeholder equal to search for campaigns there we go it's ugly now but if we give it a class name of flex W Dash fool font Dash epilogue font Dash normal text Dash 14 pixels placeholder colon text Dash hash 4b5264 for the caller text Dash White BG Dash transparent and outline Dash none and press save you can see that now it's looking much closer to this one right here but it still doesn't seem to be rounded so to this div outside after the background color we can give it a property rounded Dash 100 pixels and if we do that and go back you can see that this is looking great now now we can go below this div containing the image and Below one more div and then create another div for our button that's going to appear on the right side we can give that div a class name equal to on small devices Flex hidden Flex Dash row justify Dash end and gap-4 the smallflex means that this is only going to be visible on small devices and usually it's going to be hidden inside of there we can render that custom button component that we have created it's going to be a self-closing component to which we can pass the button type equal to Button as later on we're going to have the anchor type buttons we can also pass it a title and that title is going to depend on if we currently have an active address or not so for now we can only hard code that address right here cost address is equal to 0x and then something so we can simply put it here now we can say title if there is an address then the title is create a campaign because we have a connected wallet otherwise it's going to be simply connect there we go let's also expand their code just a bit more to have more space and let's see if the sidebar is going to still be visible and it will great now we have a custom button but we can also give it some Styles so we can say Styles if there is an address then we can give it a BG of hash 1dc071 and then else we can give it a BG off hash 8C 6D FD there we go finally this button is only going to have one function and we can Define that function by giving it the handle click property which is going to be a callback function and that callback function is going to have an if statement if there is an active address in that case we can navigate to create campaign if there isn't an active address we can say else we want to connect the wallet and we can do that by using the connect function right now you can see that we don't have that function defined so it's giving me something else so for now we can simply put a string right here of connect and then later on once we implement this function we're going to Simply remove the string signs great now of course nothing happened here and we can just see custom button because we are just sending props but we now need to go into that component and utilize the props we just sent so right here we can now get that BTN type we can also get the title the handle click and these styles and we can create a new button that button is going to be a button component it's going to have a type equal to BTN type it's going to have a class name equal to a template string it's going to be dynamic and it's going to render these tasks that we send into it I forgot to add a comma here and finally on click it's going to Simply call the handle click function and it's going to render the title that we sent through it so now we can see this create a campaign on top right but it still doesn't look like R button so let's apply some more class names right here we can start typing classes such as font Dash epilogue if we save that it already makes it look a bit more custom font semi-bold that makes it look better text-16 pixels leading Dash 26 pixels text Dash White Min Dash h-52 pixels to give it some height let's give it some space PX of 4 and most importantly rounded dash 10 pixels to make it look like a real button there we go we have our create a campaign button now we can go back into the nav bar and below this custom button we can create one last final link this link is going to not be a self-closing component but it's going to point to forward slash profile inside of there we want to show a div and inside of that div we can immediately create a self-closing image tag with a source of third web that's going to be our static profile picture there we go let's make it just a bit smaller by giving it an ALT tag of user and then most importantly a class name equal to w-60 percent H dash 60 as well and object Dash contain and of course we have to properly end that string there we go it's still huge and that's because we haven't defined the proportions of the outside div of that image so let's give it a class name equal to w-40 pixels that's already going to make it much smaller h-40 pixels rounded dash 10 pixels BG hash 2C 2f32 Flex justify Dash center items Dash Center and cursor Dash pointer and with that we have our real profile icon great now of course this doesn't look that good because we're technically on a tablet or a Mobile screen but if we expand it you can see that it looks great although there seems to be a small inconsistency with this icon right here you can notice how it is next to this connect button it doesn't seem to be centered and it doesn't seem to be circled so let's see why that is the case we have a div that's wrapping our custom button and also a link to profile that link is going to have a div and instead of 40 pixels this was supposed to be 52 for both cases there we go and also it doesn't seem to be rounded enough and instead of rounded 10 pixels it's going to be rounded Dash full there we go this is looking more like it great now we can start focusing on the mobile version of our navigation bar so right below this link and Below one more div we can create a comment saying small screen navigation there we go and below that we can develop it so let's also convert our browser to something like a tablet or a Mobile screen there we go you can do that by zooming in and then instantly you'll be able to see just the snap bar inside of here we can create a div and that div is going to have a class name on small devices hidden usually Flex justify Dash between items Dash Center and relative now still nothing is going to happen but bear with me we can give it a div another one which is going to be a container for our image we can give it a class name almost equal to to the one for this image right here so let's simply copy this entire div inside of this link and let's paste it instead of the new one we just created instead of 5252 this time it's going to be 40 and then 40 right here it's not going to be rounded full it's going to be rounded 10 pixels BG can remain the same Flex just if I centered and item Center can remain and the cursor pointer now if we save that we can see it right here below that we want to show our hamburger menu so let's go below this div right here of the image and there we can show a self-closing image tag with a source equal to menu alt tag equal to menu class name is going to be w-34 pixels h-34 pixels object Dash contain and cursor Dash pointer finally we can give it an on click property that's going to have a callback function and there we want to set the toggle drawer to not toggle drawer meaning we want to toggle it on and off currently that's not going to do anything but will make use of that information to show our mobile door so right below that image we can create a div this div is going to have a dynamic class name meaning a template string it's going to be absolute it's going to be top-60 pixels write Dash 0 and left-0 BG Dash Hash 1c1c24 A Z index of 10 to appear on top Shadow Dash secondary padding y 4 and then we want to check if not toggle drawer then we want to translate it we want to show it so what we can do is we can say a string of minus Translate minus Dash Y dash 100 VH like this otherwise we can end that string and say translate Dash Y dash zero we're also going to give it a transition of all and duration of 700 milliseconds bear with me you're gonna see how that's gonna work really soon for now you can just see this appear right there if you clicked on the toggle drawer finally inside of this div we can create a UL with a class name equal to mb-4 and there we can map over our nav links so we can say nav links dot map we get a link and then for each link we return something that's an instant return meaning simply parenthesis here we're going to return An Li that Li is going to have a key equal to link dot name it's going to have a class name equal to a template string of flex p-4 then we will need to check if is active is equal to link.name and then we can show the BG off hash 3A 3a43 and that's going to be it for the class names but finally we can give it an on click that's going to be a callback function where we can set is active to be equal to link dot name or rather we can call it with a link.name then we want to set the toggle drawer to false to close it and then finally we want to use the navigate function to navigate to the link dot link similar to what we have done on our sidebar finally we need to show our icons and if I'm not mistaken we can copy that from our sidebar remember right here for each link we were showing an icon and finally inside of here we need to show an image that's going to be a self-closing image tag with a source equal to link Dot imgurl if we now save this you can see this great menu icons appear then we have to give it an ALT tag that's going to be equal to link dot name then below that image we can show A P tag that P tag is going to render the link.name as well and there we go you can see the dashboard campaign payment and so on let's style that P tag just a bit by giving it a class name equal to that's going to be a template string first we want to give it a margin left to divide it from the left side so let's do ml 20 pixels there we go that's better then we want to change the font to epilogue we can also make it semi-bold we can decrease the size a bit by saying text 14 pixels and then most importantly we want to change the color and the color is going to depend on is it currently active or not so we can say if is active is equal to link.name then we can change the color to text Dash hash 1D c071 we can close that and then if that is not the case we can opt in for more gray regular color by saying text hash eight zero eight zero one nine one there we go and we can close it if we save it you can see that this one is green now and all the other ones are gray perfect of course let's also style the icon a bit by giving a class name to this image that class name is also going to be dynamic w-24 pixels for the width of the icon let's do it properly and the same thing for the height H-24 pixels then we want to set object Dash contain and we want to check if is active is equal to link dot name then we can have a question mark for the terminary operator and set grayscale to zero else we want to turn the grayscale on like this so now you can see everything is grayed out but if we switch to campaign or profile the icon and detects changes to Green great but of course we're still missing a button to create a campaign right here you can see it's there but if we go to tablet or mobile it disappears so we need to reuse that same create custom button component so let's copy it from here go down we're gonna go down below the UL and there we want to create a div this div is going to have a class name equal to flex and margin X of 4. to divide it a bit from the left and the right side there we can paste our custom button and we can indent it properly it's going to be of a type button and it's going to say everything the same we want to keep everything as it is now if we save this you can see our create a campaign button and if we compare that with this version of the application it's looking great as well we can toggle it on we can toggle it off but on our current version we cannot seem to toggle it off so if we go to where our hamburger menu icon is right here set toggle drawer toggle drawer that doesn't seem to be working let's try to reload the page and yep it's still there but it doesn't want to go away so in here if we click that we indeed are setting it to not toggle drawer this right here is not the best practice whenever you're changing state with the older version of that state then you have to have a callback function get the previous state and then say not previous state this is a common react best practice but this is not going to fix our issue right now the actual issue is that we prematurely closed our brace right here and we're not accounting for the logic later on so we have to take this one and we can only end it later on I think about here so let's try to fix this error we have if not toggle drawer then Translate Y else right here and you can notice this that shouldn't be there so if we remove that and then close this right here save it it goes away and now we can open it by clicking on the menu icon or we can close it by going to another page so we can go to profile and we can go back to dashboard and we can also expand our browser and we can now use the sidebar to do the same so now our sidebar and the nav bar are completely done this part took the most time but it's good because that's going to be seen across all of our Pages the dashboard profile create campaign and everything else so with that said we're done with our sidebar and our nav bar we can now close it and we can go back to our app.js where our first component is our next step that is going to be the home page component where we can fetch all of our campaigns now if you think about it that might be a problem because right now we don't yet have a way for us to create a campaign so we need to go back to app.js and let's add another route that route is going to be to create a campaign so that's a self-closing route with a path equal to forward slash create Dash campaign and then the element is going to be set to a component of create campaign there we go and we also need to close it now as you can see we get an error and we're missing an N because create campaign doesn't yet exist and it breaks and that's because I'm missing an M right here there we go while we're here we can also add all of the other routes the third route is going to be the profile route so let's create a self-closing profile with a path to forward slash profile the element is going to be a self-closing profile page and we can close it we also need to close the route component itself so if we do that we're good to go and the last component on our list or rather the last route is a path to forward slash campaign Dash details and then forward slash column ID this is a dynamic route that's going to show the details of every single campaign so there we can render an element and that's going to be a self-closing campaign details component there we go let's fix this and we are good to go if we just add one more character right here there we go so just to show this to you we have four different routes the home route going to root the profile route going to the profile component create campaign going to the create campaign page and campaign details going to campaign Details page I would love to start working immediately on the home route but that doesn't really make sense because there's no data to work with so we need to control click into the create campaign first create a couple of campaigns and then we can focus on showing them but this is good because in the create campaign we'll actually have to connect with her blockchain connect with your smart contract and then create the actual campaigns on the blockchain to be able to fetch them so this is the first time that we're gonna start creating the actual interaction between our front end and our back end everything is just starting to get more exciting so let's continue to get started developing our create campaign page we can start with the Imports we're gonna also have the use State field coming from react we're going to have the import use navigate as well one more time and that's coming from react Dash router Dash Dom now this is also going to be the first time where we're going to import ethers coming from ethers this is a utility Library that's going to allow us to interact with our smart contract we can then import the money icon coming from assets and we're gonna also import our custom button component that we created not that long ago that's coming from dot slash components we're going to also import the check if image utility function coming from dot slash utils great now we can immediately initialize our const navigate is equal to a use navigate hook coal we can also create our states in this case we're going to have two different use States the first one is going to be a use State snippet called is loading and at the start it's going to be set to false below that we're going to have one more use State and this one is going to be our form set form and that's going to be equal to an object at the start inside of this form we're going to have all the fields needed to create our campaign it's going to be a name campaign title story goal and date and campaign image so let's do just that we can provide a name then a title we can also do a description finally we're going to have a target a deadline and an image which is also going to be an empty string at the start great now we have everything we need to start developing create campaign layout first we're going to have a div and that div is going to have a class name equal to BG Dash hash 1c1c24 our classic dark color it's going to be of a type Flex justify Center and items Dash Center it's going to be of a flex Dash call because we want the elements to appear one below another it's also going to be rounded dash 10 pixels and on small devices it's going to have a padding of 10 usually a padding of four if we save that and go back to our side we can click create campaign page and you can see this create campaign component now sometimes inside of there we're going to have our loading so we can say if is loading then show the string of loader later on we can create this as a real component for now we can leave it like this and below that we can have one more inner div and within that div we're going to have an H1 where we can say start a campaign there we go now of course it's hard to see it so let's give this H1 a class name equal to font Dash epilogue let's also give it a fun Dash bold on small devices text-25 pixels to make it large usually text Dash 18 pixels leading Dash 38 pixels and text Dash white this should be much better let's also style the div that's wrapping our H1 by giving it a class name set to flex justify Dash center items Dash Center padding Dash 16 pixels to give it some space on small devices min-w-380 pixels to give it some regular width that's always going to be there let's also change the background a bit to Hash 3A 3a43 there we go and let's make it rounded dash 10 pixels there we go this is looking better now below that we can start adding our form so we can go below this div wrapping our H1 and we can create our form this form is going to have an on submit property and once that happens we want to call our handle submit function this is a function that we haven't yet created but we can Define it right here const handle submit is going to be a regular function looking like this which we can fill later on our form is also going to have a class name equal to wool margin top 65 pixels Flex Flex Dash call and cap dash 30 pixels that way all the inputs are going to appear one below another now we can start adding the input fields some input fields are going to come together for example the name and campaign they're going to take half the space so they're going to be in a shared div and then some are going to take the full width of the screen so for the ones that are going to take half the screen we can wrap them in another div like this and that div is going to have a class name equal to flex Flex Dash wrap and then gap-40 pixels like this and now inside of there we can show those inputs now we are not going to hard code every single input because that would be a lot of repeated code we're going to create a new form field self-closing component so let's do just that by going to components and creating a new form field.jsx component where we can run rafce and we can also export that component from our index.js by changing the custom button to form field of course before changing it duplicate it and now if we go back and reload inside of the create campaign we of course have to import it from components that's going to be form field and you can see the form field right here now we can duplicate it as many times we want and it's going to appear right here now we can pass the right props of this form field so let's do just that that's going to be label name equal to your name and we can put an asterisk meaning that it is required we can then add a placeholder set to John Doe we can change the input type to be text we can set the value to be formed.name and we can add the handle change which for now can be an empty callback function and we can duplicate this form field right here for the second one we're going to say campaign title right here the placeholder can be something like write a title and it's going to be form dot title with that said we can now go into the form field and we can develop this component that way both of these fields are going to change immediately and we can then keep reusing this form field component for all of the other fields as well that's the beauty of react to get started When developing our form field we can first get all the props that we passed into it that's going to be label name placeholder input type is text area this is going to be a field that we're going to see later on value and then handle change finally great now our input or rather our form field is going to be consisted of a label and an input so let's start by wrapping everything inside of a label component that label is going to have a class name equal to Flex dash 1 W Dash full flex and then Flex Dash call inside of there we can check if there is a label name so that's going to be label name and only if there is then we can show a span element that span is going to render the actual label name now if we save it we can already see your name and campaign title appear right here but let's style it a bit let's give that span a class name equal to font Dash epilogue font medium text Dash 14 pixels leading dash 22 pixels text Dash that's going to be hash eight zero eight one nine one and finally MB for margin bottom of 10 pixels now if we save that you can see this looks much better much closer to the final design finally below that we want to know if this is a text area or an input so inside of the label but below the label name we can make another check is text area if it is we then want to show a text area input that looks like this else right here we want to show off course an input so since we're going to work with inputs first let's focus on that right away our input is going to be required it's going to have a value equal to the value that we passed through props it's going to have an on change equal to handle change that we also passed through prompts type is equal to input type coming from props and step is going to be set to 0.1 that allows you to switch the number of ethereum right here if you click on these arrows great and then finally we can add a placeholder equal to placeholder and a class name now bear with me there's going to be a lot of class names to make this look good padding Y dash 15 pixels that's to extend it a bit on small devices px25 pixels so on smaller devices they're going to take the full width as you can see right here usually padding X is going to be 15 pixels outline is going to be set to none we don't want that ugly outline border is going to be set to 1 pixel then we have to set the Border color so we can say border Dash that's going to be hash 3a3a43 then we can set the BG to transparent okay that already looks much better then we can set the font to be epilogue and we can set the text to be white we can also set the text to be 14 pixels there we go now they fit again we can change the placeholder text by saying placeholder colon and then text Dash that's going to be hash 4B 5264 there we go let's make it rounded a bit rounded dash 10 pixels okay and let's also on small devices give it a min-w-300 pixels for the minimum width there we go this is now our input now our text area is going to be almost exactly the same as our input so let's simply copy all of these properties and let's simply paste them right here we need to have required we have to have the placeholder then these Styles in this case we don't need the steps but we do need the rows the number of rows so in this case it's going to be a number of 10. the input type we don't need right here the on change we of course do need and that's about it great now we have created our form field component and we can go back as you can see we didn't have to create each one separately we just reuse the same component two times and we're going to reuse it one two three four more times so going back to our create a campaign page we can go below this div now and we can add one more form field we can do that really easily by just copying the last one and pasting it right here instead of campaign title we're gonna put a story right here and say Write Your Story we need to write something compelling here to make people want to donate and instead of input type text this is going to be is text area because people can write a longer story right here and then we can change the value to form dot description the handle change for now can be set to blank and as you can see we get this huge 10 rows by default long story looking great and you can see by default it is all mobile responsive but if we expand it it's also looking great finally below that we can create this Banner that says you will get 100 of the raised amount so that's going to be below the form field and that's just a simple div that div is going to render an image that's going to be of a source equal to money so if we save that we can see the money bag right there it's also going to have an ALT equal to money and it's going to have a class name equal to 40 pixels for the width so w-40 pixels and h-40 pixels as well for the height finally we can set object Dash contain below that we're going to have an H4 so we can say H4 and there we can say you will get 100 of the raised amount of course that is dark right now so let's simply give it a class name let's change the font to epilogue let's give it a fun Dash bold to make it a bit more visible let's increase the text size all the way to 25 pixels change it to text Dash White and give it a margin left of 20 pixels there we go already looking a bit better but finally let's style this div to make it appear like this Banner right there to do that we can give it a class name set to W-4 to take a full width Flex that's going to make them appear in a row justify Dash start to appear at the start but then items Dash Center to center it vertically then we can give it a p-4 for padding and spacing BG Dash hash 8 C 6D f d this is going to be that purplish color finally let's set the height to be 120 pixels and rounded dash 10 pixels there we go this is looking so much better and now we can continue with our form fields for this one we're again going to have two form fields that can appear together in a row and we already had that at the start so we can simply copy this div containing two form fields and we can paste it right here below this div if we save that that's great we get two more inputs but this time it's going to be goal and then we can say eth 0.50 that's going to be for our placeholder and form value must not remain name rather it's going to be Target and for the last one it has to be just a bit different we can change the campaign title to end date placeholder can also be end date but the input type is going to be a date and the form value is going to be deadline there we go so now we have that date picker as well finally the last missing piece of the puzzle is this submit new campaign button so what we can do is below the form field we can create a div that div is going to have a class name Flex justify Dash center items Dash Center to Center everything both horizontally and vertically and the margin top of 40 pixels inside of there we can really easily use our custom button that we created before by giving it a button type equal to submit button by specifying a title equal to submit new campaign and by giving it Styles equal to BG Dash hash 1D C 0 7 1. and if we save that we get this grade submit new campaign button if we expand it we can admire our form in its full Glory there we go start a new campaign of course our logic isn't yet hooked up to our actual form layout so let's focus on that right away first we have to keep track of our form values as you can see right now we're never actually resetting those four values so let's create a special function that's going to take all of the values from all of our fields we can do that by saying const handle form field change that's going to be function that takes an event a key press event and then based on that it calls the set form function first we need to spread out the entire form and then we need to change only the special type of the field that changed so how can we know which field has changed we can call this either type or we can call it a name of the field and we can know that if we of course pass it to the function so we can pass it as the first parameter field name that is the most descriptive name field name and then where's the value stored the value stored under e dot Target dot value this is it this is how you make this function update every single field accordingly now let me show you how to use it inside of our field we can of course call it right here so we get an event as the first and only parameter and then we call handle form field changed and we pass the name of the field as the first parameter and then the event as the second one now bear with me the name is name here because that's exactly what we called it inside of the state we can now copy this and paste it to the second one but this time it's not going to be name it's going to be title let's move forward for the third one it's going to be description moving forward then we have our form field right here and that's going to be Target so let's paste it and change this to Target moving forward we have the end date or rather the deadline so we can copy the form.deadline and make it right here finally there is one more that I missed if you look at the finished design there's a campaign image right here and on our current version the end date is the last one so what we can do is we can duplicate our last form field one more time change the label to campaign image and then we can say Place image URL of your campaign there we go that's going to be input type of URL and then we're going to change that to form that image and handle change is going to handle form field change under image there we go now we have a full form it looks like I made one small mistake these two form Fields the goal and the end date were wrapped in a div and we didn't properly close that div so I have to move this closing tag right here to properly close them so we have div and then we have goal and end date and div and then finally we have the form field and then a div wrapping our button now the button is nicely centered and everything is looking great perfect now we're also updating our values but what to do with them once all of our values are stored in the state how can we actually submit it well that happens instantly since our button is of a type submit so it's going to call the handle submit function inside of there let's first get the event as the first and only parameter and let's do e dot prevent default this is something you need to do in every single form in react because the default browser behavior is to reload the page after form submission in react you never want to do that and this prevents the default Behavior so now instead of here let's actually console log the form to see if all of our values are there great I'm going to expand this open up the inspect element and then the console it looks like the form field is not defined let me just reload the page there we go that's good and now I'm going to enter my name enter the campaign title for example building a computer story is going to be I want to build a computer from scratch to be able to record YouTube videos and then the goal is going to be let's do something like zero point one five eat the date is going to be by this Friday and then the campaign image you can go to Google and you can right click the image and then copy image address then by going back you can simply paste it right here and we can click submit new campaign and as you can see all of the data is right here and it is ready to be submitted so now we are ready to finally create the functionality to connect our smart contract to our front-end side and therefore pass the data to our smart contract great we're going to contain all of our smart contract interactions in one single file that's the best practice I can give you when working with web3 applications all of that is going to be contained inside of our context so instead of the context folder create a new index.js file this is a place where we're going to store all of our web3 logic and then we're gonna wrap our application with this context so that every single page and component can use it without any problems this is a centralized source of Truth so let's start with Imports we're going to use import react we're gonna need to use context in this file as well as create context and that is coming from react then we're going to import everything we need from third web so that's going to be use address use contract use metamask and use contract right these are all utility functions coming from at third web Dev forward slash react and we can also import ethers coming from ethers there we go then we have to create our context by saying const State context is equal to create context finally we need to create and Export our context Provider by saying export const State context provider is equal to this is a regular react functional component but it has children inside of props so we can get those children that allows us to wrap our entire application with the context provider but then still render all of the children that are inside of it finally now is the time to connect with our smart contract we can say const contract is equal to use contract and then to that function we have to provide our contract address we can do that by coming back to our dashboard and then simply copying the address to clipboard and then pasting it right here great now there are two different ways to call write functions such as create campaign and donate to campaign if we go back I'm going to show you both ways we can say const mutate async and then we can rename that to create campaign that's going to be equal to use contract right to which we pass the contract and then specify the name of our write function in this case create campaign this is going to allow us to Simply call this function and create a campaign by passing all of the parameters to it the other way is just to call the contract that call and then pass everything you need you can use any one of these methods with that said this was the address of the smart contract but now we also have to get the address of our smart wallet and that's going to be const address is equal to use address also const connect is going to be equal to use metamask with this we can connect a smart wallet great so now we have everything we need to interact with our smart contract so what do you say that we start with our first function which is publish campaign we can say const publish campaign is equal to an async function that accepts a form back inside of our starting campaign page we'll send that form that we console logged not that long ago remember so we can say const data is equal to a weight and now we call that create campaign function that we have right here at the top and we want to pass the entire form to it with some slight adjustments we're going to call it pass in an array that looks like this and we have to send it in a certain order first we need to send the address from the owner who is creating this campaign then we have to send the form.title which is the title of the campaign and then so on but now how do I know in which order do I have to send this well let's go all the way back to our web3 side of things to our contracts and then right here let's search create campaign and there we go it's the address of the owner first the title second description and so on so in that order let's continue form that description is the next one form dot Target after that then we're going to have a date but we have to formulate data bit by saying new date form dot deadline and then we can get time this is going to give us access to a number of seconds passed since 1970. this is how JavaScript handles dates and finally the last one is form dot image great with this we are ready to create a new campaign we can wrap this in a try and catch block to be sure that this worked well so we can create a try and catch move this right here to the try and then if it went successfully we can say console log and say contract call success and we can console log the data if it failed we can duplicate this console log and we can say something like contract call failure and we can cancel log the error as well there we go with this our first call to the smart contract is done but as you can see our published campaign function we just created is declared but it's still not used so how do we pass it all the way here from the context to our create campaign page well our state context provider has to return something right so we can say return it's going to return a state context dot provider and most importantly it has to have a value right here value is going to be everything that you want to share across all of your components in this case we want to share the address of our smart wallet that's one thing and then in new lines we can share everything else that we want to share we can share the contract itself but most importantly we can share the create campaign function but keep in mind this create campaign is the name of the contract Hall we need to refer to our publish campaign function so what we can do is simply rename the publish campaign to create campaign in this case and we're now sharing that across all of our pages finally we have to render the children in between our state context provider there also has to be a way for us to use to utilize that context so we can create a custom Hook by saying export const use State context is equal to a function that simply calls the use context and then we pass in that state context great now of course this wouldn't work if we don't wrap our entire application with that context so we can go back to our main.jsx and inside of here we can import State context Provider from dot slash context and we can wrap our application with it State context provider and make sure that the app is inside of it there we go now it looks like there is an error inside of the index.js that seems to be online 41. but if you read the appropriately it says fail to parse if you're using jsx make sure to name the file.jsx extension so I'm going to just rename this to index.jsx save it reload the page and hopefully it works let's open up the inspect element and the console and this time we have the misspelling of the address there we go so if I fix this we should be good and we are great so now we're in the home page if we move to create a campaign that's great but now how can we say for sure that we can access this address contract or create campaign function inside of other Pages well there's just one way to know right let's go back to pages and create campaign this is where right now we're just console logging the form but we need to call a function so what we can do is we can import the use State context so import use State context coming from dot dot slash context now we can get it right here at the top by saying const create campaign is equal to use State context and that's it this is how you share data and functions and all the functionality across all of the pages in your app you just create one context a centralized source of Truth with calls to Smart world functionalities and then you share it across the values through here we call it create campaign and therefore we can get it right here so now inside of here there's just one thing left to do we can make this function asynchronous since smart contract calls do take time and we can say await create campaign and we need to pass some props to it we are going to first spread the entire form and then we're going to change the target just a bit our Target is currently in a normal human readable amount that's going to be 0.5 or similar but we have to change it into way which is a subunit of eth we can do that by saying ethers Dot utils dot parse units and then we pass the form.target and say 18 decimals that is how much weigh one if is great so now we're passing it in a proper format now there's one more check we want to do before we verify that we can create a campaign we want to ensure that the image that we pass is a valid URL image and that's why there's this utility function that simply checks if this image returns a callback does it exist so how to properly this utility function is right here let's call it before create campaign by saying check if image to which we can pass the form dot image and then there's going to be a second parameter which is a callback function that returns one parameter which is exists so if the image exists we can say if exists then we can simply do what we have just done we can await create campaign before we do so though we can start the loading process so we can say set is loading to True later on we can set the is loading to false after it has finished creating and then we can navigate to simply forward slash to be able to see it on the dashboard if the image is not valid if it doesn't exist we can simply alert provide valid image URL and we can also clear the URL by saying set form we want to spread the entire form but we want to set the image to an empty string there we go so now we can properly create our first campaign are you ready let's go ahead and give it a shot I'm going to expand this in its full Glory open up our console just to see how it goes there we go and let's start we're going to do the same thing we did before building a PC I'm building a cool PC let's set the goal to something like 0.5 the date can be Friday and then the image URL I had it already stored in my clipboard and let's click submit new campaign immediately we get an error and that's good because the error says that we are not connected to our wallet maybe some time has passed and we got disconnected so that's good because now we can actually check if we are connected or not I'm gonna show you that before we actually hard coded it so if you go back to our nav bar let's go right to our components navbar take a look at this connect button it is hard coded that's one thing and then also the address if you look at it is hard coded right here but now that we can use the context we can actually know if the address is there if our wallet is connected so what we can do is we can import that's going to be use State context coming from dot dot slash context and then from the context we can say const get me the connect function and get me the address and that's equal to use State context there we go of course we're going to delete our own address now let's remove this console to be able to see the button and now it says connect also I can see that this logo is currently not being used so I think it should have been used in this small navigation where we can use it right here instead of third web there we go so now everything is utilized and what we want to do is we want to check if we're connected that is happening right here with the address and now we have a real connect function if you go back to context that's the index.js of the context you can see that I I just lied there I thought that we have the connect function but we don't have it yet we're just passing the address and the contract the connect function we have declare though it is right here so the only thing we have to do is just pass it connect there we go it's that simple now back in the nav bar we can just form this from a regular string to a function call to the connect function and I think we had it in two places so let's search for it there we go this is the second one great so now if we reload the page it says connect we can click connect a new wild metamask notification appears we want to connect yes and now it says create a campaign because we are connected so now we can go to create a campaign we can repeat the process building a PC we can set the goal to 0.5 we can set the date and you can add a campaign image and click submit new campaign there we go a metamask notification appears and it says estimated gas that is fine let's confirm and we can even see it right here pending interaction but also if you go to dashboard and go under events I think we should be able to see it here so once this event is executed once it is fulfilled there we go a contract interaction we can now go under Explorer and we can immediately see if there is a campaign straight from our dashboard this is pretty cool so let's go get campaigns and there we go it appeared right here which means that it is actually submitted to the blockchain great keep in mind if we weren't using third web we wouldn't be able to immediately hear using our UI see that our campaign indeed did get through our smart contract and it got created on the blockchain great now we are ready to go back and we can close the nav bar close the context create campaign and we can go all the way back to our client source app.jsx and we can finally go to our home component because now we have one of those campaigns that we can actually see right now it says just home but let's go ahead let's fetch that campaign and let's showcase it right here on our home page great job so far inside of our home we can import two different hooks we're going to use use state but this time also use effect and we're gonna of course need our context so we can say import use State context coming from dot slash context when it comes to States in this application we're going to use a use state of is loading at the start set to false and also a state of campaigns so we can say campaigns set campaigns and at the start they're going to be set to an empty array the reason why we put campaigns in state is because we'll have to fetch them from the smart contract then we can get some data from our context by saying address contract and get campaigns if you think about it this get campaigns function is the function we haven't yet created in the use State context if we go in there we have only created the publish campaign but not get all campaigns so let's go ahead and create the get campaigns function as well immediately below published campaign we can say can't get campaigns that's going to be equal to an asynchronous function inside of there we can say const campaigns is equal to a weight contract dot coal and then you pass the name of the function inside of the smart contract you want to call and that's get campaigns it is that simple to make it cool to a Smart contract that's going to give us back our campaigns but we have to parse them a bit to get the meaningful data so right now if we console log the campaigns we're gonna get let's see how they're going to look like so we can go to the console and reload the page of course after we export this function out of our context so we can put the get campaigns right here in the value of our context and then back home we can have the get campaigns if we properly spell them and now inside of the use effect we can call that function so that's going to be use effect of course it has a callback function and a dependency array it's going to be recalled once we have the address and the contract so we have to ensure that the contract is there before we try to make a call we can do that by saying if contract then we can call our get campaigns but our get campaigns is an asynchronous function if we go into it we can easily see that so right here inside of the use State context we have get campaigns and it is indeed async so what we can do is we can declare a new function const fetch campaigns is equal to async function the reason why we did this is because we cannot call an async function immediately inside of the use effect rather to be more precise we cannot await and the result of this function needs to be awaited so instead of calling get campaigns here we can call it inside of fetch campaigns by saying cons data is equal to a weight git company pains and how everything is good now while we're here we can also set is loading to True before we fetch them and then after we fetch them we can say set campaigns is equal to data and we can also set its loading to false and now inside of the use effect we can call the fetch campaigns instead of get campaigns and now we get back an array which has nine different elements amount collected deadline image owner and a lot of different things but you can see it also has them in an indexed order 0 1 2 3 4 5 6. now what we want to do is we only want to fetch things that matter that we really need from those campaigns and we want to format them in a nice human readable format so in this case the target is a big number also the deadline is a big number and the amount collected is a big number we want to transform that into human readable numbers to do that we can say const campaigns is equal to campaigns.map where we get an individual campaign right here and then we're going to instantly return an object this is how that looks like so bear with me the syntax is a bit more complicated we have campaigns.map inside of which we get one individual campaign then we have parentheses which means immediate return and then immediately we have an object that means that we simply want to take one campaign and do something with it so what we can do is we can say owner is going to be equal to campaign dot owner title is going to be equal to campaign.title description is going to be equal to campaign.description but now we work with the Target and Target is going to be equal to ethers dot utles dot format ether and then we have to pass in the Target dot to string there we go so now this is going to be in a regular human readable format we're going to do a similar thing with the deadline we can simply do deadline dot to number and again the same thing goes for the amount collected so we can say amount collected is equal to ethers dot utils dot format ether and we can pass in the amount collected dot to string finally the image is going to be set to campaign that image and we need the PID the project ID is simply going to be the index of our campaign so we can use that as a second parameter right here and now if we console log our parsed campaigns right here you can see it's going to be a bit more easily understandable Target is not defined let's see that's going to come from here because that's supposed to be campaign dot Target same thing right here campaign dot amount collected.to string and the deadline again the same thing campaign dot deadline if we did that correctly now we have one object which has the amount collected 0.0 deadline which we're going to later on transform to a date description image owner project ID Target and title everything that we can fully read great the only thing this function has to do with that is simply return it so instead of console logging it we can put a return statement great and now inside of the home our campaigns is fully filled with the data so we can immediately Loop over it and show it but we have to be smart if you look at the finished version of the project right here and go to home you can notice that our home page is really similar to our profile page unfortunately now I have no campaigns here because I deleted my old account but it is the same thing just it's all campaigns versus your campaigns so we have to be smart and think of this ahead of things we're going to create a special new component called display campaigns Dot jsx and we can run refce inside of there this is going to be the function which we can import from within our home import display campaigns from that slash components and of course we have to export it from here so we can simply export it by saying display campaigns there we go so now instead of automatically looping over our campaigns inside of the home we can now render that special display campaigns component as a self-closing tag and we can pass a title called all campaigns we can also pass the is loading equal to is loading and finally we can pass the campaigns themselves campaigns is equal to campaigns the reason why we did this is because now we'll be able to reuse this component from within our profile page as well I'm going to show you how simple that will be great with that said we can dive into the display campaigns component and start creating the layout there inside of here we can import use navigate as when we click on a specific card we want to navigate to that specific campaign so that's coming from react router Dom we're going to also import the loader component coming from dot slash assets there we go and that's going to be it for now we can get all the props that we passed in earlier such as the title is loading and campaigns themselves great we can initialize our const navigate is equal to use navigate and we can immediately dive to the layout of our application we're going to have a div and immediately below that we're going to have an H1 that's going to render the title now if we save that and go back you can see that it just says campaigns right here all campaigns and we can really see our title it could be hiding somewhere so let's apply some class names let's give it a class name equal to font Dash epilogue and let's give it a font semi-bold text Dash 18 to make it bigger and then finally text Dash white and text Dash left if we save this we can see all campaigns which is exactly our title great now next to that we also want to show the number of campaigns so we can simply render the campaigns dot link that's it and we have to spell this properly so that's going to be campaigns right here and it's a zero let's put that inside of parentheses there we go all campaigns one great that's looking great now below that we can create another div and this div is going to have a class name equal to flex Flex Dash rap margin top 20 pixels and gap-26 pixels inside of here we can check if we are loading so we can say if is loading and end then we want to show an image that image is going to have a source equal to loader and the alt tag is going to be loader of course we have to apply some class names in this case we're going to give it a w Dash 100 pixels as well as h-100 pixels finally object Dash contain now if we save this and reload we saw that loading for a second great now we have to check if we maybe have no campaigns and we can do that with another check if not is loading and campaigns dot length is equal to zero and meaning in that case render a P tag that's going to say you have not created any campaigns yep there we go and we can have a class name it's going to say font epilogue it's also going to be font semi-bold text-14 pixels leading Dash 30 pixels and finally text Dash we can provide some grayish color such as 818183 if we save this we should not be able to see that because we indeed do have one campaign in case you want to test it out this is how it's going to look like great so now is the time that we Loop over our campaigns and show our campaign cards for that we need to do one final check if we are not loading and if campaigns dot length is greater than zero then we want to say campaigns dot map and then for each campaign we want to render a fund card this is a custom component that we are yet to create we can provide a key equal to campaign.id and we can spread the entire campaign into it finally we can pass the handle click that's going to be equal to a callback function that's going to call our special handle navigate function and to it we can pass campaign now you might be wondering what is this special handle navigate and not our usual navigate that we use well the handle navigate is a function that we are going to create so cons handle navigate and as we said it takes in a campaign the reason why we're creating this function is just to increase code readability still we're going to use the regular old Navigator in this case we want to go to forward slash campaign Dash details forward slash and then campaign dot title but this time we also want to provide a second parameter which is state new react router allows you to pass State directly through routing isn't that crazy so we can say campaign is equal to State and then this data of the campaign we clicked on is going to be passed through state to this campaign Details page now it looks like our fund card is not created and that's fine we have to create it so inside the components let's create a new fund card.jsx let's run rafce and let's export it from our index there we go fund card and inside of display campaigns we of course have to import it by saying import font card from dot slash fund card we can do it like this or straight from components either way it should work now it looks like the fund card is not defined even though we have created it right here fund card so if we reload it still breaks now it says campaign is not defined so if we go back let's try to search for campaign and right here it looks like I misspelled campaign so let's fix that there we go and we are good we have one campaign and we can see One Fund card for that campaign but now of course we want to see something that looks like this we want to see a beautiful fund card so to implement just that we can now control click and we can start developing the fund card layout again we're thinking in terms of reusability here once we develop it once we'll be able to reuse it for all future campaigns with that said let's get started with developing our fun card to get started with our fun card we can import the tag type which is one of the assets as well as third web coming from dot slash assets and we can also import a utility function called days left coming from utils now when we called our fun card we spread out all of the campaign properties so we can get them right here through props that's going to be owner title description Target deadline amount collected image hand handle click now we have everything we need now we have to convert the days left from our deadline which is currently a number so we can say const remaining days is equal to days left and then we pass the deadline to it now for the layout and the Beautiful look of our cards first we're going to have a wrapper div this div is going to have a class name equal to on small devices width is going to be 288 pixels usually width is going to be full it's going to be rounded Dash 15 pixels and it's going to have a BG of hash one c one C two four finally once we hover over it we're going to have a cursor pointer there we go now if we save this we cannot see anything yet because the div is empty and also this div is going to be clickable so once we click we're going to provide the handle click function to navigate to that specific campaign now inside of there first and foremost we want to show the image of the campaign so we can say source is equal to image coming from the props if we save that we can see our building a PC campaign now let's give it a alt equal to fund and let's give it a class name equal to W Dash full H dash 158 pixels object Dash cover and rounded Dash 15 pixels there we go this is looking much better now below that we can have a div and that Dev is going to be a wrapper for our content so we can give it a flex and flex Dash call as well as b-4 for padding inside of there we can have one more div and inside of that div we're going to have an image that's going to have a source equal to tag type now if we save this you can see this folder and also we can give it a altac equal to tag and we can give it a class name equal to w-17 pixels for the width age-17 pixels for the height and object Dash contain there we go now below that we're going to have a P tag where we're going to have our category so in this case we can say category and we can give it a class name equal to margin left of 12 pixels so divide it from the image margin top equal to 2 pixels like this to divide it from the top font Dash epilogue then we're going to have a font medium text dash 12 pixels and then text Dash that's going to be hash eight zero eight one nine one if we save that we can see category right here now this is not something that we currently make use of when creating our campaign but feel free to add the category to the create campaign page and implement it in the smart contract that's another task for you to do for now we can hard code the category to something like education let's also give a class name to this div that's going to be equal to flex Flex Dash row to appear in a row items Dash Center and mb-18 pixels to divide it a bit from the image there we go now below this div we want to have one more div that's going to have a class name equal to block there we want to have our main title so we can render an H3 tag that's going to render the title and immediately below it we want to have a P tag that's going to render the description now if we save that it's going to be barely visible and our description currently technically is the title but let's apply some class names so we can better see this content class name is going to be font epilogue then we're going to have a font semi bold as well as text-16 pixels that's for the size then text Dash White text Dash left leading Dash 26 pixels and finally truncade if the title is too long this is going to shorten it there we go now let's do a similar thing for our description class name let's give it a margin top of 5 pixels to divide it from the title font Dash epilogue find Dash normal font dash 12 pixels a bit smaller from 16. text Dash that's going to be hash eight zero eight one nine one and text Dash left leading Dash 18 pixel and truncate if we save that it's looking great but maybe you put a bit longer description there now it looks like the font normal and font 12 pixels applies the same property so in this case we won't even need the font 12. there we go great finally now we have to focus on the amount raised and days left and finally the creator of that campaign so that's going to be below this div inside of another div that div is going to have a class name equal to flex justify between Flex wrap margin top of 15 pixels and gap-2 now inside of there we're going to have two different divs because we have two different parts the raised amount and the days left so let's create one div that's going to have a class name equal to flex and flex Dash coal because these elements are appearing one below another right here and before we duplicate it we can add the content inside of it so we're going to have an H4 with the amount collected and below that we're going to have a P tag that's going to say raised off Target so how much have we raised now we can apply class names so for our H4 the class name is going to be fond Dash epilogue font semi-bold text Dash 14 pixels text Dash that's going to be hash B2 B3 BD color grayish color and leading dash 22 pixels there we go we can see 0.0 now we can also style the V tag by giving it a class name equal to margin top of 3 pixels to divide it from the top fun Dash epilogue we're going to have font Dash normal text dash 12 pixels leading Dash 18 pixels and text Dash that same grayish color of 808191 of course put a hash in front finally on small devices the max W is going to be 120 pixels for the width and we want to truncate it if we save that it says 0 0 raised out of 0.5 great now we can take this entire div and duplicate it below instead of the amount collected we want to show the remaining days and right here we can say days left if we now save this this is looking great 0.0 raised of 0.5 three days left in building a PC card we're almost done now we have to focus on showcasing the owner of this campaign so that's going to be one div below and our final div this div is going to have a class name equal to flex items Dash Center margin top is 20 pixels and cap dash 12 pixels inside of there we want to have a div that's going to wrap our image that image is going to render the third web asset it's going to be of a type user and it's going to have a class name equal to w-1 over 2 h-1 over 2 and object Dash contain now if we save that we're going to get this huge image right here and that's because we haven't yet provided the class names for the wrapper div so let's go right here and let's provide a class name equal to w-30 pixels for the width h-30 pixels for the height rounded Dash full Flex justify Dash Center items Dash Center BG Dash hash one three one three one a and if we now save this you can see that it nicely appears in a circle finally after this image and the div we can render a P tag that P tag is going to say buy and then it's going to render a span inside of which we can render the owner address that span is going to have a class name equal to text Dash hash B2 B3 BD so now we can see it but we also have to style the P tag by giving it a class name and saying flex-1 epilogue font normal text dash 12 pixels and text Dash that's going to be hash 808191 and we can give it truncate property now it fits nicely right here and we have a beautiful campaign card great now if we were to add one more campaign card it would appear right here next to this one which means that we're utilizing the full power of react as a matter of fact we can try creating a new account and then creating another campaign the only thing you have to do to create a new account is go to metamask click right here and click create account let's call it account two now you can go back to account one and you can click Send let's transfer between my accounts and let's send to account to let's do 0.25 and next hand sent eth is currently being sent let's switch to a second account and let's connect it the amount of ethereum should arrive really quickly and there we go it's there now let's connect our second account and let's create a campaign let's do something like JSM we can take the campaign title from here let's call it save nature save live so going back save nature save life the story we can copy right here you can type something else the goal is going to be one Eid and the date is going to be the first of January 2023. finally you can go to Google and find that image URL or an image address of a nature image I'm just going to take this one right here and paste it under campaign let's go ahead and click submit a new metamask notification appears let's confirm it and keep in mind we haven't yet created the loading for this component we left it static so we can come back later on and fix that loading but for now let's give it a moment and we can track our progress right inside of metamask there we go pending we were redirected and we can see two beautiful campaign cards for two different campaigns created by two different users but now what if we want to know which campaigns did we create did this currently logged in account create well for that we have this profile page which is currently empty now by using all of the best practices that react offers thinking about reasonability up front let me show you how simple it is to create this profile page you won't believe it the only thing you have to do is go back to our home page copy the entire page go to pages and profile and paste the entire home page rename the home to profile as the name of the component as well as the export at the bottom and you can see that we get the same thing but now to switch it let's go back to our context by going to context and then the index.jsx inside of here we're getting all campaigns but we only want to get some campaigns so let's create a new function const get user campaigns which is going to be equal to an async function we can say const all campaigns is equal to a weight get all campaigns then we can see const filtered campaigns is equal to all campaigns dot filter there we're going to get a campaign and we can make a check if campaign dot owner is triple equal to the address of the currently logged in account only then keep it and finally return filtered campaigns now we can share that right here through value so campaigns get campaigns and this is going to be get user campaigns that we want to share finally going back to profile instead of utilizing get campaigns we can only call get user campaigns and with that said we get one campaign wasn't that simple we can now go back to the dashboard to get all campaigns or click our profile to get only the one we created you can notice how code reusability makes all the difference if you like this part of the video You're Gonna Love what we do on jsmastery.pro there I teach you a lot of these neat little tricks on applications such as filmpire where you build your own Netflix clone or a fully fledged 10 plus hour nft marketplace where you build your own smart contract from scratch as well on top of that if you'd like to really step your game we have the JSM masterclass Pro experience where we help you land the highest possible web development opportunities with that said let's go back to replication and let's continue with the development of our great crowdfunding platform the profile is done home page is done as well and what is left to do is of course if you enter into the campaign we have to develop the campaign Details page so if we go into campaign details that's going to be the next thing we have to implement to get started with our campaign details let's first import use State and use effect from react we're going to also import use location coming from react Dash router Dash Dom from the location we're gonna pick up this state that we sent through the routing finally we can import ethers coming from ethers now for some local Imports we're gonna import the use State context coming from Context we're going to also import our custom button that's going to come from dot slash components we're gonna also need some utils for example calculate bar percentage coming from utils and then also days left which we also saw before and finally we're gonna need some assets so we can import third web icon coming from that slash assets there we go and we are ready to start creating the campaign now let me show you what I meant when I told you that you can transfer State through routing with the new react router Dom we can say const the structure the state is equal to use location and we call that as a hook finally let's console log the state now if we save that and go back let me just show you how we're navigating here if we go to home remember we click on a specific campaign and then we pass the state as the entire campaign so going back here now we can console log that state from the location let's clear the console and then let's click on a specific campaign and there we go our state is right here which means that we can now showcase it on our campaign Details page we're gonna also need some things from the use State context so we can say const get donations which we haven't yet created contract and the address is equal to use State context now we're going to also have some component local States so we can say use state that's going to be is loading and set is loading at the start set to false we're going to also have the amount we want to donate so we can say amount set amount and at the start set to an empty string and finally we're going to have an array of donators so we can say use State snippet donators set donators and at the start it's going to be set to an empty array great and as the last time we have to parse the days left or the deadline so we can say const remaining days is equal to days left State DOT deadline and with that we are ready to look and feel of our campaign Details page first of all we're going to wrap everything in a div and then immediately there we're gonna check if we are loading and then we're gonna show a loading dot dot if we are now if we're not loading then we can show a div and that Dev is going to have a class name equal to W Dash full to take the full width of the container Flex to be a flex container on medium devices Flex Dash row but usually Flex Dash column margin top 10 to divide it from the nav bar and GAP Dash 30 pixels inside of there we're gonna have one more smaller div this div is going to have a class name equal to flex-1 flex Dash coal and inside of there we can showcase our image that image is going to have a source equal to State DOT image if we save that we're going to get our huge image right here we can give it an ALT tag equal to campaign and then we can give it a class name equal to W Dash full H dash 410 pixels and object dash cover and rounded Dash XL to give it rounded corners and this is already looking so much better now below that image we want to have one more div this div is going to have a class name equal to relative it's going to have a w fool h-5 pixels so only five pixels of height and it's going to have a background of 3A 3a43 finally it's going to have a margin top of two you can see this line right here that's what we're doing but now inside of that line we want to calculate the percentage of the funded amount so that's pretty cool we're going to show how much of the entire project has been funded we can do that by creating a new div and giving it a class name equal to Absolute age-4 and then BG that's going to be hash 4acd 8D this is a bright green color now if we save that we won't be able to see it because we haven't yet funded but later on we'll be able to check it out now we have to make this Dynamic so to this div we're going to also give a style property there we can specify the width of that style and we're going to make that a template string there we're going to call our calculate bar percentage that's going to be a function to which we can pass the state.target and then state that amount collected and at the end we can put the percentage sign right here finally we're going to also give it a Max width of 100 percent great now let me show you how this calculate bar percentage Works behind the scenes it just takes the goal and erase the amount and then it calculates the percentage great so now we have that percentage bar and we have our image we can go below this div right here and Below one more div so only have two divs left right there and there we can start by creating these count boxes you see those three boxes right here so let's create a div that's going to wrap them by giving it a class name equal to flex on medium devices width is 150 pixels W is full usually Flex Dash wrap justify Dash between and gap-30 pixels inside of there we want to render a new component called count box a self-closing component to which we can pass a title the first one is base left and then the value which is going to be remaining days finally we can duplicate this both for the raised amount and total backers so right here we can pass a dynamic title that's going to be raised off state DOT Target and then how much was raised we can pass it through the value that's going to be state DOT amount collected and for the last one we have to provide the total number of backers so total backers and there we can get the donators dot length great now if we save this we're going to get an error and that's because we haven't yet created this component so going back to components and creating a new count box.jsx running rafce and then exporting it from the index is going to fix that error so that was count box and now back inside of campaign details we can import count box from our components and there we go you can see three different count boxes here but now is the time that we dive into it and we develop its look and feel there through props we're getting the title and the value as you know because we sent them a second ago and then we're gonna have a rapper div that div is going to have a class name equal to flex Flex Dash coal items Dash Center and W Dash 150 pixels if we save that nothing is going to happen because our div is empty so let's give it an H4 that's going to render the value and let's also give it a P tag that's going to render the title so now if we save this you can see days left raised off and total backers finally let's apply some class names to both of these properties for the H4 let's give it a font Dash epilogue let's give it a fun Dash gold text-30 pixels to make it a bit larger text Dash white padding Dash 3 to give some spacing BG Dash hash 1C 1c24 rounded Dash D for top 10 pixels W Dash fool text Dash Center and truncade if we save that this is looking great now let's do a similar thing for the P tag by giving it a class name of font epilogue font normal text-16 pixels text Dash hash eight zero eight one nine one BG Dash hash 28282e padding X meaning only horizontal of three and then padding y meaning only vertical of two W Dash full for full width rounded Dash B meaning on bottom 10 pixels and then text Dash Center if we now save this we can see our beautiful cards great this is starting to look more like the campaign Details page that we want to finally we of course have to do all of this part the Creator the story donators and most importantly the ability to fund so let's go from top to bottom we can go back to campaign details and go below this div right here actually we're going to go below one more div so we only have one left that's because we want to move outside of this entire rectangle right here and we want to go down that means that we can create a new wrapper div for the rest of the content that's going to have a class name of Mt 60 pixels to divide it from the top Flex on large devices Flex Dash row usually Flex Dash column and gap-5 inside of there we want to have one more smaller wrapper div that's going to have a class name equal to flex-2 like this Flex Flex Dash coal and gap-40 pixels finally inside of there we want to have one empty div and after that div put some spaces right here because we'll have to add another empty div later on so first we're starting with the Creator we can look at the reference design and Creator is right here this is looking really close to our number right here so we can copy the class names from our count box for the H4 let's copy the entire H4 actually and let's paste it right here within the div now we're not going to show the value rather we're simply going to hard code creator now if we go back you can see Creator right here but we're going to modify these Styles just slightly instead of bold it's going to be semi-bold instead of 30 pixels it's going to be 18 pixels of size it's going to be text Dash white and we don't need any other properties that we have here rather we only need uppercase there we go so let's save it and this is looking great now below that Creator we want to create a div for this little portion where we have an image an address and the number of campaigns so immediately below the H4 create a div that div is going to have a class name of margin top of 20 pixels Flex Flex Dash row items Dash Center Flex Dash wrap and GAP Dash 14 pixels inside of there we want to have one more div that's going to be the div for the image so we can say class name is equal to w-52 pixels h-52 pixels Flex items Dash Center justify Dash Center rounded Dash full and then we can give it a BG hash to c2f32 and a cursor Dash pointer finally inside of there we can render a self-closing image tag that's going to have a source of third web we can say alt of user and we can give it a class name equal to w-60 percent H dash 60 percent and object Dash contain if we save that we have our image right here now below this div containing our image we can have a simple div that's going to contain our stats so we can say H4 that's going to render the state DOT owner which is the address and then below that what we can do is we can hard code the number of campaigns so we can say 10 and then campaigns there we go so you can see everything right here now let's apply some styles to rh4 class name font Dash epilogue font semi bold next Dash 14 pixels text Dash White and break Dash all this is going to apply a word break property there we go below that we can style the speed tag by giving it a class name of margin top of 4 pixels font Dash epilogue font Dash normal text-12 pixels and text Dash hash eight zero eight one nine one now if we save that this is looking great finally we can duplicate this entire div containing the Creator and everything inside of there because we want to show the next section and it's also going to have the story which is the same as the Creator and the donators is also going to be similar so we can start by duplicating this section that's just this empty div where the Creator is on the top and the three divs at the end let's paste it in this case we won't need anything that is below the H4 so we can simply delete that part right here and just keep the H4 but we're going to rename that to story finally below we're going to have a div that's going to have a class name equal to mt-20 pixels and there we simply want to render a P tag and this P tag is going to be the same as these campaigns right here so let's simply paste the campaigns change it to state dot description but rather we're going to just increase the font size a bit to 16 pixels we also want to give it a leading Dash 26 pixels to make the text appear a bit larger and text justify if we save that we can see our building a PC right here but as you can see it appears that the story is not in line with our building APC whereas here it is so let's see why that is the case first of all on the description we don't need this margin top right here we just need font epilogue font normal text 16 we need a color leading and text justify and that is inside of this div with a margin top so everything here is looking good but here's the catch this H4 doesn't need a P3 that's what moves it around so if we fix this you can see now it's looking great and actually the above one right here which is this H4 doesn't need the padding of three either so if we fix that now everything is aligned now we have a story although this description is quite short sometimes you can put bigger descriptions such as this one now let's move on to the donators and again that's going to be really similar so we can copy this div entirely change the story to donators and now in here we're going to have some Dynamic logic so let's keep this P tag for later on but for now let's give this div some more properties such as Flex Flex Dash call and gap-4 inside of here we want to check if there are any donators by checking if donators that length is greater than zero if it is then we want to say donators.map and then get each individual item or a donator and also an index for each one of these we want to return a div so right here we can say div and there we can say donator this is simply static for now but if there aren't any donators in that case we can say or render and we simply want to render a P tag that's going to look like this instead of stay the description we can say no donators yet be the first one and we can save that there we go donators no donators yet be the first one same as on the design but later on once we get some donators we can render them out right here for now we can move to the last part of the page which is the fund card through this input and this button will be able to fund the campaign so to get started let's go below one two and then three divs so keep in mind you have to exit three divs that's going to be one two three and then down inside of here we can start creating that layout so we can say class name is equal to flex-1 and then we can give it another title which we can copy from the top H4 donators paste it here and this is going to say fund if we save it that's looking good but now let's focus on creating this entire card to do that below this H4 we can create a wrapper or a container div and give it a class name equal to Mt 20 pixels for margin top it's going to be flex and flex Dash column since elements are going to appear in a column we're going to give it a padding of four and a BG of hash one c one C two four and rounded dash 10 pixels if you do that you should be able to see this rectangle appear at the bottom finally inside of there we can render a P tag that's going to have a class name equal to font Dash epilogue it's going to have a font Dash medium text Dash 20 pixels to make it a bit larger leading dash 30 pixels text Dash Center and the text color is going to be text Dash hash eight zero eight one nine one inside of there we can say fund the campaign there we go this is looking good and below this speed tag we can render a div that div is going to have a class name equal to mt-30 pixels and we can render our one and only input that input is going to have a type is equal to number we can set the placeholder to something like eth 0.1 so people know that they can type Eid amounts there we can set this step to be only 0.01 since we're working with ethereum amounts not dollars or cents and we can give it a class name equal to W Dash full padding y of 10 pixels and let's save it there we go this is how it's looking right now but if we give it on small devices padding X is 20 pixels and usually padding X is 15 pixels we can also remove that Outline by saying outline none and give it a border by saying border 1 pixel and Border Dash we can give it a color of 3A 3a43 most importantly we can set the BG to transparent we can set the font to epilogue we can set the text to White and this already looks much different much closer to our finished product let's also give it a text Dash 18 pixels to make it a bit larger and leading dash 30 pixels finally let's set the placeholder color by saying placeholder column text is hash 4b5264 and rounded dash 10 pixels and there we go our input is done now we can also specify the value to be equal to amount and the on change is going to be a simple callback function that's going to take in an event a key press event and it's going to set the amount to e dot Target dot value and there we go now we can set the amount of eth now let's create this little Banner right here back it because you believe in it support the project for no reward just because it speaks to you and then the fund campaign button just below this input we can create that div by giving it a class name equal to mt-20 pixels to divide it from the input then we can give it a padding of four a BG of one three one three one a and a rounded of 10 pixels there we go now inside of there we can render an H4 and that H4 is going to Simply say back it because you believe in it there we go and below that we can render a P tag that's going to say support the project for no reward just because it speaks to you there we go of course this is not going to look good right now because it's dark and dark so let's give it a class name to this H4 font Dash epilogue font semi bold text Dash 14 pixels leading dash 22 pixels text Dash White and save it looking good now for the P tag let's give it a class name equal to margin top of 20 pixels font Dash epilogue fund Dash normal let's go back a bit leading dash 22 pixels and text Dash that's going to be hash 808191 there we go this is looking great finally we can render our custom button below it so just one more div below we can create a custom button component let's give it a button type BTN type equal to button title is going to be fund campaign Styles is going to be W full and VG Dash hash 8C 6D FD that is that purplish color and we can give it a handful click equal to handle donate this is the function that we are yet to create so right here we can create const handle donate that's going to be an asynchronous function because there we're going to make a contract call and contract calls do take some time so as you can see our complete campaign page is now designed we just haven't yet created the donators part and that's because we cannot yet even donate I also noticed that we are missing some space between the button and this div so instead of merging top on this div let's put margin y meaning top and bottom there we go so now let's expand this and would you look at that this is looking like a great campaign page they want to get 0.5 to build a PC and they have three days left so what do you say Let's help them right in this case to help them we have to make the fund functionality work so to do that what do you think to which file do we have to go well we have to go back to our context and then our index.jsx inside of here below get users campaign we can create our new function that's going to tap into creating and getting donations right inside of here let's create a new function called donate it's going to be an asynchronous function that's going to accept a PID a project ID and the amount that we want to donate there we can say Khan's data is equal to a weight contract dot call and our function is called donate to campaign and it accepts three parameters the PID the address and the amount finally we can simply return the data this is a function right on our smart contract and we can verify that if we go to our dashboard and C donate to Campaign which accepts a project ID and a token value great with that said we can now pass this donate function all over our context right here now what we can also do while we're here is we can get all donations so let's create a new function const get donations is equal to an async function that accepts a PID as the first and only parameter there we can say cons donations is equal to a weight contract dot coal get donators and we need to pass the PID now inside of here we have to get the number of donations by saying const number of the Nations is equal to donations 0 dot length these are old at the Nations on a specific project now we can parse those donations by seeing const Parts donations is an empty array and then we can create a for Loop we can say four let I is equal to zero I is lower than of number of donations I plus plus and then we simply want to push to parse the Nations parsed the Nations dot push we want to push in an object that has the donator inside of it that's going to be equal to the Nations 0 and then I and then the actual donation amount which is going to be ethers dot utos dot format ether and then we pass donations one and then I and that's going to be dot to string before the ending of the parentheses there we go so now we have what we need the donator and the donation for each donation so we can simply return the parsed donations there we go and we can pass the donations right here get donations great with that said we can go back to our Pages campaign details and now we can make that donation so scrolling up let's now handle the Donate function the only thing we have to do here is first of all the set is loading to be equal to True at the start and then after we initialize the loading we can get the Donate function from our use State context and then we can simply call it right here by calling a weight donate and that's going to be it but we have to ensure that we are calling it properly and that we're passing the PID that is going to be the state DOT PID to it and finally then we can set the is loading to false after we successfully donate now if we look into that if we go to the Donate function and go right here to the use State context we can see that we are passing the PID but we're not passing the amount so right here we also have to pass the actual amount that we want to donate as the second parameter then we can do a weight contract dot call where we pass the name of the function on the smart contract we want to call the PID and finally we don't have to pass the address just the amount but it has to be parsed in a different way it's going to be parsed as a value inside of an object where ethers dot utles dot parse ether and then we pass in the amount so we have to first parse it to be able to send it over great with that said we can now go back to campaign details and our donate function is ready now of course we won't be able to see those donations if we don't fetch them as well so above let's create a const fetch donators async function and this function is simply going to say const data is equal to a weight get donations to which we can pass state.pid and then we can set donators to be equal to data now this function is not being called right now and when do we want to call it well we want to call it as soon as our campaign Details page loads so we can use the use effect have a callback function and then in the dependency array we can put the contract and the address we have to ensure that the contract exists so we can say if contract only then call Fetch donators and there we go the donators are set and then we're going to have access to them right here inside of donators so that's great let's try to make a payment if we go back to our app we have an error so going back and opening the console we can see address is not defined let's see where that is that is right here I am missing a second s and if we save that come back everything looks good sometime has passed so I got disconnected I'm gonna connect again that's great and now let's fund I'll donate 0.05 and click fund a new metamask notification appears and you can see 0.05 plus some gas fees and I can click confirm now our loading still isn't properly working it's just a simple loading screen later on we're going to implement an overlay but for now we can see that the transaction is pending and hopefully there we go it went through so now if we go back to our dashboard we can see that we raised 0.05 out of 05. we can see that we have total backer 0 which doesn't look good so let's go back reload the page and then click again yep it still says zero but the amount seems to be all right and in here we can see donators of zero that doesn't seem to be good so what we can do is we can console log the donators right here or rather just the data now we can inspect go to console and it looks like get donations is not a function I misspelled it that was supposed to be get donations there we go if we now fix that and reload the page it says that contract that all is not a function let's see where that is happening that is most likely happening in the context where we were supposed to type contract dot coal not all if we now fix this and go to inspect element now it says invalid big number string value value 0.x interesting so we're trying to parse some numbers it could be the number for the backer as that is the only thing that's not showing up here so let's see what's happening with our number of backers that is right here this should be working donators dot length so are we also console logging the donors we are right here okay and but we didn't see this console log appear in the console so the error happens even before invalid big number unfortunately we don't get a lot of information on where this is hiding invalid big number doesn't really say a lot so let's try to debug it if we comment out this fetch donators functionality what is going to happen now as you can see there is no that error so if we bring this back and if we bring this back it's going to get back there there we go so we know that the error is most likely somewhere inside of the get donations function so let's go into the state context and get donations and inside of here I missed the function call of the two string method so if we fix that that should work and there we go total backers is one and we can see our donator and a donation so now these three cards are working perfectly but we are yet to display our donators right here in the list so now that we have the data we can go all the way down to donators and we can show something and by something I mean have a div where each div has a key that key is equal to item Dot donator and then we can also say slash and pass the index to be unique we can give it a class name equal to flex justify Dash between items Dash Center and GAP Dash four now inside of there we're going to have two different p p tags the first paragraph is going to render the index plus one which is the number of the donation Dot and then the item dot donator this is the actual address finally let's give it some class names so we can see it that's going to be font Dash epilogue it's going to be fun Dash normal text-16 pixels text Dash that's going to be hash B2 B3 BD and leading Dash 26 pixels as well as break Dash or now if we save that we unfortunately still cannot see it and that's because we misspelled the length right here at least I did so make sure that it is donators dot length and you'll be able to see it right here now we can duplicate the speed tag and instead of rendering the index and the donator we simply want to render the item dot donation there we go you can see it on the right side right here we can also change the color of the second tag just a bit by saying eight zero eight one nine one so there we go now we have the amount and donators and with that said our campaign details is now completed this was a long component with a lot of functionality but now we're finally able to donate and view donations but we can also view the entire campaign so right here we can go back we can see that we have raised 0.05 out of 0.5 three days left by who created this campaign and then we can see all information right here alongside the donators and now we're certain that the fund campaign card works because we can actually see our donation and not only that the amount that we sent which was 0.05 was actually transferred to our account one isn't that great perfect with that said we can collapse it one more time and what we can do next is implement the loading State remember while we're submitting the funding or while we're creating a new campaign nothing really happens there's no loading but now we're gonna Implement a custom loading state or rather a custom loading overlay should I say it's going to appear across our entire application while the interaction with the blockchain is happening so what we can do is go to components and create a new loader.jsx component there you can run rafce and let's immediately export it just so we don't forget that's going to be loader now we can go into the loader component and implement this simple loading overlay to start implementing our loader the only thing we have to do is import the loader coming from dot slash assets and now we can create one wrapper for our entire screen that's going to have a class name equal to fixed instead of 0 Z of 10 meaning it's going to show on top of our content and it's going to take the full height so we can say H dash screen we can give it a background but it's going to be an rgba zero zero zero which is black and then 0.7 for the opacity finally it's going to be Flex items Dash Center and justify Dash Center so that everything appears in the center and flex Dash call inside of there we can render an image that image is going to have a source equal to loader the alt tag is going to be set to loader as well and it's going to have a class name equal to W Dash 100 pixels H dash 100 pixels and object Dash contain finally the only thing we have to do is add a P tag that's going to have a class name equal to mt-20 pixels font Dash epilogue fun Dash bold text Dash 20 pixels and text Center inside of there we can say transaction is in progress we can put a Break Tag then and then say please wait dot dot dot great now we can go back to wherever we typed loading let's see we can toggle on this match case and it looks like we're using loading right here in display campaigns we're also using it right here in campaign let's see there we go loading but let's turn on this match whole word and then we can see where we really need to implement that loading so first of all it's going to be in campaign details so right here instead of loading dot dot we can import the loader component and now we can render it the only thing we have to do is just put the self-closing loader component right here that same older component is also going to go in one more place and that is when we create a campaign so you can go to create campaign and right here you can see we typed loader so in this file as well we have to import the loader and then render it right here as a self-closing component great now to test it out we can create one more campaign so we can go to create a campaign I'm going to type Adrian let's do something from here maybe Building Hope Village so we can copy the title building Hope Village we can add a story you can type something in the description the goal can be one Eid the date is going to be let's do something like this and then for campaign title you can get this from Google I'm just going to copy the address from here paste it and click submit new campaign as you can see we have our loading but it doesn't look that good we missed the white color so while we have the chance let's go back to loader and right here we have to say text Dash White and there we go transaction and progress it also looks that the flex.cole is not applied properly it looks like I typed Flex Flex this was supposed to be Flex stash call and there we go transaction in progress and now we know now our user knows that they have to make an interaction with metamask as soon as we confirm it you can see transaction is still in progress that's because transactions on the blockchain do take some time but as soon as it is finalized the loading is going to stop and will be redirected back to the home page and there we go that works perfectly now finally let's see if it's going to work for the Donate functionality as well so let's go to save nature save life and let's also make sure that we redirect once we fund the campaign so I'm going to search for fund campaign there we go and there on handle donate we want to navigate to the home page so let's see if we have imported the navigate right here we haven't so we can do use navigate we can initialize it here cons navigate is equal to use navigate and finally right here we can navigate to forward slash there we go perfect so let's try to donate 0.02 click fund transaction is in progress which is perfect and we can now confirm as you can see we're waiting for the confirmation to happen and immediately after it is done will be redirected back to the dashboard and there we go we might need to reload the page one more time now you can go into save nature and we can see that we have one backer 0.02 perfect with that said our dashboard page is done our profile page is done as well our create a campaign page is done and all of this is entirely mobile responsive as you can see it feels like a native mobile application perfect it has been phenomenal having you with me throughout this entire video thank you so much for watching and thank you for improving your own web development knowledge with new technologies such as web3 now that we're almost at the end of this video I hope that you now share my enthusiasm for a huge impact the third web has on the web3 community with that said there's just one thing left to do and that is deployment to deploy our great project we're going to use a simple react deployment tool called netlify we can start by signing up or logging in at top right once you're in you can go to sites and now you can scroll down and we can drag and drop our build folder right here back in our code you can close all of the currently opened files collapse it open up your terminal stopping from running by pressing Ctrl C and then Y and then you can run npm run build this is going to create an optimized production build of your grade application and there we go if you now go to file explorer client you'll see a new dist folder right click it and then click revealing File Explorer or open in finder you can open it on top of your browser and then simply drag and drop the entire this folder right here this is going to upload and deploy your application to the internet in just a couple of seconds there we go our production build is now published and the website is deployed under this Mary Sable random URL if you want to use this application to put it on a portfolio with a custom URL or you want to have a real email connected to it and faster speeds as well I would highly recommend to check out hostinger's hosting I personally use them for all of my major projects the link is going to be down in the description but with that said let's click this link right here and check out our great project all of our campaigns are immediately right here and we can now again connect to our application but this time not connecting to localhost but rather to our real published URL there we go and regarding the blockchain side we didn't have to do absolutely anything because we're still utilizing the same smart contract published on third web perfect with that said huge thanks to third web not only for sponsoring this video but for creating such an amazing software that is a huge Game Changer in the whole web3 industry and if you like building this project you're gonna love building nft Marketplace it is a 12 hour course we're gonna build a solidity smart contract use nextgs and harness the full power of the blockchain by watching this video down in the description you're getting a special YouTube discount code so feel free to check it right away a if you're watching this video at the time of the release we are soon starting with another cohort of the JSM masterclass experience if you're learning a lot through these pre-recorded videos on YouTube imagine how much can you learn if myself and other team of developers guides you and mentors you every step of the way if that's something you would be interested in make sure to go to jsmaster.pro and click the take the quiz button to see if you're eligible with that said thank you so much for watching and have a wonderful day [Music] thank you