Create Sections Frontend

In this lesson, we're going to work on sections frontend

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

This lesson preview is part of the The newline Guide to Fullstack ASP.NET Core and React course and can be unlocked immediately with a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to The newline Guide to Fullstack ASP.NET Core and React with a single-time purchase.

Thumbnail for the \newline course The newline Guide to Fullstack ASP.NET Core and React
  • [00:00 - 00:10] Now that our back-end part is ready, we can start working on our front-end. Let's start with registering our endpoints inside agent.ts file.

    [00:11 - 00:20] Inside lectures, we can make a create endpoint. So here, let's write create.

    [00:21 - 00:35] This will have data and it will be a post request. So I can write requests.post, which will return a string.

    [00:36 - 00:47] The endpoint is going to be simply lectures and the body will be data. And let's close this angle bracket.

    [00:48 - 00:57] And as data, we will pass causeID of type string. So here, we can write causeID type string.

    [00:58 - 01:12] We will pass section name of type string. And lectures, which will be an array of lecture DTO.

    [01:13 - 01:24] So we can write lecture DTO, we can import it and use an array with it. And let's delete this angle bracket from here.

    [01:25 - 01:31] Now, let's register the second endpoint, which is cause is published. So here, we can create publish endpoint.

    [01:32 - 01:44] This will only take a causeID of type string. And this will be a post request as well.

    [01:45 - 01:59] So we can write requests.post and we are going to return a string from here as well. And the endpoint is going to be causes slash publish slash the cause ID.

    [02:00 - 02:05] So we can use dollar and curly brackets. And here we can pass the cause ID.

    [02:06 - 02:15] And since it's a post request, we will also pass empty object as the body. Let's create a new page now, which will be called section page.

    [02:16 - 02:29] So inside SRC inside pages, let's create a new file, which will be called section H dot TSX. We can start by creating a function.

    [02:30 - 02:50] And for now, let's simply return fragments and we can export it. And now let's register it inside app dot TSX file.

    [02:51 - 02:58] Let's go to app dot TSX. We can copy this one and paste it here.

    [02:59 - 03:13] This will have an endpoint of slash course slash lectures. And cause here will be dynamic because every course will have a different cause ID.

    [03:14 - 03:23] That's why I have used semicolon so that we can extract it from our match params as well. And here we can import section page.

    [03:24 - 03:36] And this is the URL which we are using inside the instructor page. So when a user clicks on the unpublished cause, it will go to slash course slash lectures and cause is dynamic.

    [03:37 - 03:42] That's why you're using it like that. And this is the exact same URL.

    [03:43 - 03:52] Now we can go back to our section page and this page is going to be a bit complicated because one section can have multiple lectures. So let's start with the state.

    [03:53 - 04:05] So let's start with the section name. So here we can write section name and set section name.

    [04:06 - 04:15] And for that, we will use U state hook and the default value will be an empty string. And this is always going to be a string.

    [04:16 - 04:24] And let's create another state for the lecture form. So here, let's create lecture form.

    [04:25 - 04:33] And here, let's write set lecture form. Again, we will use U state hook.

    [04:34 - 04:42] Default value will be an empty array. This form is going to be complicated. So for simplicity, let's make it type any .

    [04:43 - 04:52] Like I told you before, this form is a little complicated. So we will not use form from and design, which means we will do the form validation by ourselves.

    [04:53 - 05:14] So for validation, let's create a new function which will be called previous as valid. So below this, let's create a function which will be called brief, which means previous is valid.

    [05:15 - 05:40] We are creating this because if we create a new lecture form or a lecture field , we want to verify that the last lecture field is not empty. So if it's the first lecture, which means if lecture form.length is zero, we can simply return true because we don't have to verify if it's the first lecture field.

    [05:41 - 05:53] Now, let's create a variable called some empty. So here, let's call it const some empty, which will check if any value inside the item form is empty.

    [05:54 - 06:02] So what we can do is we can use lecture form dot sum. And inside, we will have access to the item.

    [06:03 - 06:16] Let's give it type any. And we want to check if any of the item dot URL or item dot title is an empty string.

    [06:17 - 06:39] So what we can do is check item dot URL if it's an empty string or item dot title is an empty string. We need this because before creating a new lecture field, we want to check that the previous lecture field is not empty.

    [06:40 - 06:49] This will go through the entire lecture form and check for every item and see if any of the field is empty, it will not create a new lecture field. Now we can set the errors.

    [06:50 - 07:00] For that, we will run a for each loop on the lecture form. So what we can do is if some empty, which means there is a field which is not filled.

    [07:01 - 07:05] So at this moment, we want to show the error. So now we can loop over the lecture form.

    [07:06 - 07:17] So here, let's run lecture form dot for each. Inside, we will have access of the item.

    [07:18 - 07:24] Let's give it a type any. We will also have access to the index, which will have a type number.

    [07:25 - 07:33] So here we can store all the previous values inside a variable. So let's call it const all prep.

    [07:34 - 07:44] And here we can create dot dot dot lecture form. So by doing this, all prep has all the lecture form fields value.

    [07:45 - 08:01] Now we can check if lecture form with a particular index is empty. So what we can do is we can check if lecture form at the index, because it's looping over every item of the lecture form.

    [08:02 - 08:14] And if the title is an empty string, in this case, we will set an error. Since we cannot mutate the state in react, we will use all prep.

    [08:15 - 08:25] And here we will pass the index. And we will store the error inside the errors property dot errors dot title.

    [08:26 - 08:44] And we can give an error now, which will say title is required. Same will be applied for the URL so we can copy it and we can check if lecture form at this index dot URL is an empty string.

    [08:45 - 08:58] So here we can make it URL and the error will say URL is required. And now to set the state, we can set lecture form and the value will be all prep.

    [08:59 - 09:13] So we are setting the values inside this variable and finally setting the state using this. And finally from this method, we will return opposite of some empty.

    [09:14 - 09:26] So if some empty is true, we will return false because it's checking if the previous field is valid or not. We can now create another function which will be responsible for adding new lecture fields.

    [09:27 - 09:39] So here we can create a new function. Let's call it handle add link.

    [09:40 - 09:46] In this function, we will get event as a parameter. So let's write event and give it a type any.

    [09:47 - 10:00] So in the beginning, we can write event dot event default, which prevents the default behavior of a form to submit it. Now we can write the initial state of the form.

    [10:01 - 10:16] So here, let's create an initial state and let's call it input state. And when we are going to create a new field at that moment, the title will be an empty string.

    [10:17 - 10:23] So we can write empty string and the URL will be empty string as well. So let's create empty string here.

    [10:24 - 10:46] And we also have errors. So what we can do is after our values, we can write errors and inside the errors, we can create title property, which will be null in the beginning and the URL property , which will be null as well.

    [10:47 - 10:56] So when we create a new field, our lecture title will be an empty string. Lecture URL field will be an empty string and all the errors will be null as well.

    [10:57 - 11:10] And now before adding the new link, we want to check if the previous field is valid. So here we can check if Priff is valid, which means the previous lecture fields are filled successfully.

    [11:11 - 11:21] In that case, we can set lecture form and inside we will get previous values. We can call it Priff.

    [11:22 - 11:30] And now we can write the previous values. And after that, we can write the values of our input state.

    [11:31 - 11:43] Now that we have an option to add new fields, we can also give an option to delete the previous lecture fields. So below this, we can create another function and we can call it handle remove field.

    [11:44 - 11:56] So handle remove field. This function will also have access to the event.

    [11:57 - 12:10] Let's give it type any and the index, which will be a number. We can start again with event dot, event default.

    [12:11 - 12:19] And after that, we will remove the field for which we can set lecture form. And here we will have access to the previous values.

    [12:20 - 12:35] Let's give it a type any now we can filter the previous values. So we can run Priff dot filter and inside we will have access to the item.

    [12:36 - 12:51] And now we will check that item is not equal to previous values with this index . So basically, we are removing the lecture field with this particular index using the filter function.

    [12:52 - 13:04] Now we can work on the handle change function. So below this, we can write const handle change.

    [13:05 - 13:15] So the handle change function will take index. So let's give it index type number and event with type any.

    [13:16 - 13:27] So inside, we can set lecture form and we will have access to the previous values. So let's call Priff.

    [13:28 - 13:36] The lecture form state will have multiple fields. So to get the value of the exact field, we'll have to map over the previous values.

    [13:37 - 13:54] So here we can return Priff dot map and we will have access to the individual item and the index. So let's call I, which will be type number.

    [13:55 - 14:13] Now we only want to change the value where I matches the index. So if I is not equal to the index, we can simply return the item because we don 't want to change anything in this case.

    [14:14 - 14:44] Otherwise we can return the item and set event dot target dot name to be event dot target dot value. So right now we are setting the values after this, we can set the errors.

    [14:45 - 15:21] So after that, we can write errors and here we can spread the previous errors item dot errors and now we can set event dot target dot name and we want to check if the length of the value is more than zero in this case error will be null. So what we can check is if event dot target dot value dot length, if it is greater than zero, then there is no error.

    [15:22 - 15:43] We can write null. Otherwise we can write the error inside event dot target dot name plus is required.

    [15:44 - 15:57] And let's change the spelling of required. I know it's a little more complicated because this time the form fields are dynamic because there can be multiple lecture fields and one section can have multiple lectures .

    [15:58 - 16:07] So check that we are creating this handle change function. Now that our functions are completed, we can start writing the JSX.

    [16:08 - 16:21] So first of all, let's remove the fragments and start with a dev with class name section page. This will have H1 tag.

    [16:22 - 16:37] So here we can write H1, which will say create sections. Actually we can write the course name after this.

    [16:38 - 17:04] So what we can do is we can import unpublished courses from use app selector and from here state dot user and from the unpublished courses, we want one particular course. Let's start with the variable called current course.

    [17:05 - 17:33] So here let's create a new variable current course and it will go through the unpublished courses and find the item or let's call it course because individual item will be a course and it will check if course dot ID is equal to match dot params dot course. So we need match.

    [17:34 - 18:06] So let's write it here and let's give it a type of route component props of type any and now we can check if course dot ID is equal to match dot params dot course. So this variable will go through the unpublished courses and it will find a course where the ID of the course matches this particular course ID.

    [18:07 - 18:21] And now what we can do is after create sections, we can write name of the course. So here we can write current course dot title.

    [18:22 - 18:29] That is possible that user refreshes the page and the value of current course goes away. So what we can do is we can create a user effect hook.

    [18:30 - 18:46] So let's create a user effect hook here. And actually we can move it a bit down.

    [18:47 - 19:02] So we can paste it here and this user effect hook will check if there is no unpublished course. In this case, we can dispatch get unpublished courses, function.

    [19:03 - 19:13] So for this, we will need dispatch. So here we can create const dispatch, which will be equal to use app dispatch.

    [19:14 - 19:30] And if there are no unpublished courses, we will dispatch get unpublished courses. And as dependency, we can write dispatch and unpublished courses.

    [19:31 - 19:40] Let's go back to the GSX now. So after the sections, we can create a card.

    [19:41 - 19:46] So let's write card and we can import it using addy. And we haven't imported it yet.

    [19:47 - 19:52] So let's add import. We can now write the input element.

    [19:53 - 19:58] And this time we won't import it from addy. So here let's write input.

    [19:59 - 20:15] We can give it a name called input section. We can pass a placeholder, which will say section name.

    [20:16 - 20:24] The value will be section name as well, which is our state. It will be required.

    [20:25 - 20:32] So we can write required, make it true. And the on change event will be very straightforward.

    [20:33 - 20:46] We will have access to the event. So what we can do is we can set section name to be e.target.value.

    [20:47 - 21:00] After this input field, we can loop over the lecture form because our lecture form will have multiple fields. So here we can write lecture form dot map.

    [21:01 - 21:14] And like always, we will have access to the item, which will be type any for now. And we can pass index type number.

    [21:15 - 21:28] Let's start with a div with class name section page underscore lectures. So let's call it section page underscore lectures.

    [21:29 - 21:40] And to make it unique, we will pass a key. Let's give it a value of item dash the index.

    [21:41 - 21:50] Now this div will have three children to input elements and a button. One input element for lecture name, another one for lecture URL.

    [21:51 - 22:03] So let's create two divs with class name section page. Undiscond score lectures.

    [22:04 - 22:11] Undiscond score item. Let's copy it one more time.

    [22:12 - 22:17] And the third item will be a button. So button we can import from Andy.

    [22:18 - 22:25] So let's import it. This button will have responsibility to delete the lecture field.

    [22:26 - 22:32] So we can give it a type primary. This will have a color red.

    [22:33 - 22:38] So we can give danger property to it. And it will call handle remove field function.

    [22:39 - 22:58] So we can write on change. And since we want to pass an event and the index, we can write handle remove field and we can pass and the index.

    [22:59 - 23:07] Now let's write the lecture item. And here we will use the input element from HTML as well.

    [23:08 - 23:20] This input element will have a name title. The class name will be input lecture.

    [23:21 - 23:31] Placeholder can be lecture title. So let's write lecture title.

    [23:32 - 23:39] Value will be item.title. So this item and title.

    [23:40 - 23:46] This will be required as well. So we can write required to be true.

    [23:47 - 23:53] And on change, we will call the handle change function. So we can write on change.

    [23:54 - 24:00] We will pass event. So here we can write handle change.

    [24:01 - 24:10] We will pass the index and event as required by this function below this. We can check for the errors.

    [24:11 - 24:28] So what we can do is we can check if item. errors.title, which means the value inside title is not false. In this case, we can create a new div.

    [24:29 - 24:40] So let's create a div with class name invalid feedback, which is going to show the error. So let's write invalid feedback.

    [24:41 - 24:48] And the value will be this exact same value. So we can simply copy it and paste it.

    [24:49 - 24:59] The logic for the URL field is going to be exactly the same. So we can simply duplicate it and we can pass it to the other div.

    [25:00 - 25:20] And now we can replace title with URL class name and stay the same. Placeholder will say lecture URL value will be item. URL and rest everything inside the input can stay the same.

    [25:21 - 25:30] And for the error, we can write item.error. URL. And it will say item.error. URL.

    [25:31 - 25:39] So everything else can stay the same. Now below the card, we can create three more buttons, one for adding the lecture.

    [25:40 - 25:45] So let's add a button here. This will have a type dashed.

    [25:46 - 25:53] So let's write type dashed. And this will call the handle add link on click.

    [25:54 - 26:06] So on click, it will call the handle add link function. And this button will say add lecture.

    [26:07 - 26:16] So here we can write add lecture. Now let's create a button for publish section.

    [26:17 - 26:27] So what we can do is we can simply copy it and make the type primary. We can delete this for now.

    [26:28 - 26:38] This button will say publish section. So we can write publish section.

    [26:39 - 26:44] And we can give it a class name as well. And the class name will be publish section.

    [26:45 - 26:54] We can write publish section. And we need to create a function which will publish the section.

    [26:55 - 27:01] So what we can do is here we can write publish section. The function is not here right now.

    [27:02 - 27:08] So we can simply go on top and start creating it. And before that, let's make it section.

    [27:09 - 27:23] So let's go on top and here let's create a function. And let's call it publish section.

    [27:24 - 27:32] This will be an asynchronous function. So we can write async and inside we can write try catch block.

    [27:33 - 27:49] So try and catch which will have an error of type any. Let's log the error console dot log error.

    [27:50 - 28:11] And inside the try block, we can create a variable called response which will call await agent. So let's import agent dot lectures dot create.

    [28:12 - 28:28] And inside we have to pass the cause ID. So let's write cause ID which will be match dot params dot cause we need to pass the section name which will be simply section name.

    [28:29 - 28:38] And finally, we need to pass the lectures. For this, we can pass the lecture form which is a list of lectures.

    [28:39 - 28:46] Now, if the response is successful, this response will be a string. So we can use notification from Andy.

    [28:47 - 28:56] So let's write notification dot success. And as a message, we can pass the response.

    [28:57 - 29:07] And finally, if the section is published, we can set section name to be an empty string. And the same goes for the lecture form.

    [29:08 - 29:15] And the lecture form will be an empty array. Because once the section is submitted, we want to create another section.

    [29:16 - 29:22] So we want all the previous values to be empty. Now we can pass this section as a function.

    [29:23 - 29:29] So here we have written publish section. Is there anything wrong with the spelling?

    [29:30 - 29:34] Because we have created it inside this function. So let's cut it from here.

    [29:35 - 29:46] And we can create it here. Finally, we will create another button which will be responsible for publishing the cause.

    [29:47 - 29:53] So let's go down. Let's copy this and paste it one more time.

    [29:54 - 30:02] This button will say publish cause. And the class name for this will be publish cause.

    [30:03 - 30:13] And on click, it will call another function which will be responsible for publishing the cause. So what we can do is we can write publish cause.

    [30:14 - 30:20] And now we can work on creating this function. So let's go on top one more time.

    [30:21 - 30:33] And above publish section, let's create another function called publish cause. This will be an asynchronous function as well.

    [30:34 - 30:40] So we can write async. And here as well, let's start with the try catch block.

    [30:41 - 30:44] So let's write try. And catch.

    [30:45 - 30:51] Let's write the error type any. And let's log the error.

    [30:52 - 30:59] Inside the try block, let's create a response. Const response.

    [31:00 - 31:12] This will be equal to await agent.courses.ablish. And here we simply want to pass the cause ID so we can pass match.

    [31:13 - 31:27] And this function will also return a string on successful response. So again, we can write notification.success.

    [31:28 - 31:38] And as a message, we will write the response. And finally, we can push the user back to the profile page.

    [31:39 - 31:46] So here we can write history. Since we don't have history, we can write it here.

    [31:47 - 32:01] So below this, we can write const history is equal to use history. And inside the function, we can write history.push and push the user to the dashboard.

    [32:02 - 32:11] So we can write dash profile. Now, as always, in the transcript, I have given you a file called section page dot SES.

    [32:12 - 32:18] Copy the file and paste it inside SAS folder inside pages. Create a new file.

    [32:19 - 32:35] Call it section page dot SES. Paste the code and then inside main dot SES file, import it and register it.

    [32:36 - 32:48] Here we can write pages slash section page. Let's check the terminal to see if we have any errors.

    [32:49 - 32:58] Now we can open the browser and check if everything is working as expected. Let's open the instructor page and let's create a new cause.

    [32:59 - 33:05] Let's give it some random title. And let's copy it for every field.

    [33:06 - 33:21] This is just a random course and we are just doing it to check if everything is working as expected. Now let's choose a category and this is music.

    [33:22 - 33:28] So let's click on music. Level can be beginner and language will be English.

    [33:29 - 33:32] Now let's click on submit. And it says cause created successfully.

    [33:33 - 33:38] And now we see it inside our unpublished cause. So let's click on it.

    [33:39 - 33:46] And this is how our sections page is going to look like. Now let's write section one and we can add lecture.

    [33:47 - 33:57] So if I click on add lecture and if it's empty, it will say title is required and URL is required. This is where our previous is valid function comes into the picture.

    [33:58 - 34:08] Now let's make it very simple and let me write lecture one. And you can copy any random URL from YouTube.

    [34:09 - 34:21] Just make sure you click on share and copy the embed code from YouTube and simply paste it here. And I'll add another lecture, call it lecture two.

    [34:22 - 34:39] And I will again copy a URL from YouTube and paste it here. Same goes for lecture three, lecture four and lecture five.

    [34:40 - 34:58] Now if I click on publish section, it says section added successfully. And now we can click on publish cause and it says cause published successfully.

    [34:59 - 35:15] And now what we can do is we can check if the cause exists because it's now published and if we click on music, we see our cause learn music with me. Let's add it to the card and go to the card, let's purchase this cause.

    [35:16 - 35:30] Again, we'll enter four to four to. And we can choose any expiry rate and we can choose our CBC to be one to three.

    [35:31 - 35:42] And now that our payment is successful, we see this cause. If you click on go to cause and we see our cause published.

    [35:43 - 35:52] Our title section one, section two, lecture three, lecture four, lecture five. Amazing.

    [35:53 - 35:56] This means what we have done is working as expected. Amazing.