Create Course Page

In this lesson, we're going to work on creating the course page

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:11] In the last lesson we worked on the instructor page and we are giving an option to our instructors to create a new course. We haven't created an endpoint yet to create a course. So let's do that in this lecture.

    [00:12 - 00:27] We will start with the courses controller where we will write a new endpoint to create courses. So let's open courses controller. Let's do it here and this should be an authorized function or method. So let's start with authorized.

    [00:28 - 00:45] And this time we only want the instructor to create this course. So we can also write roles here and we want to check the role of an instructor. So let's write roles and make it equal to instructor.

    [00:46 - 00:58] And it is authorized not authorized. And this will be a post request. So bottom, let's write HTTP post.

    [00:59 - 01:15] From this function we will return a string. So we can write public async task of type action result. And here we can mention the string.

    [01:16 - 01:35] And we can call this method create cause. And we will pass data from body. So let's write from body and the type of our parameter will be cause. So let's write cause and also write cause here.

    [01:36 - 01:44] Let's import authorize. And inside this method we will first set the instructor to be user.identity.

    [01:45 - 02:00] name because it's an authorized request. So whatever cause we'll get from here, we are not asking the instructor to mention the name from the client side. We will mention it from our server. So first of all, let's write cause.instruct or.

    [02:01 - 02:14] And this will be equal to user.identity.name. And after that we can add cause to the context.cause. So here we can mention context and we need context.

    [02:15 - 02:28] So what we can do is here, let's mention store context. And simply call it context. Let's import it.

    [02:29 - 02:49] And also initialize field from parameter. And now we can write context.courses.add and fill will add this cause which has all the properties and also the instructor property, which is being added from our server.

    [02:50 - 03:04] And finally we can write the result. So here let's mention result, which will be equal to context. And let's await for it.

    [03:05 - 03:13] And here it will be context.save changes async. And again we will check if it's more than zero.

    [03:14 - 03:33] And if result is successful, we can return a string, which will say cause created successfully. If the result is not successful, we can return a bad request.

    [03:34 - 03:42] So here let's mention bad request. And inside we can pass the new API response, the class we created.

    [03:43 - 03:55] And let's pass the status code of 400. And the message will say problem.

    [03:56 - 04:05] Creating course. Let's import API response using API.error response.

    [04:06 - 04:15] Now that we have created this endpoint, let's register this endpoint inside agent file. So let's go to agent.ts.

    [04:16 - 04:19] Let's add another endpoint for create. So let's write create.

    [04:20 - 04:30] And this will be a post request and which will take some data. So here we can write requests.post.

    [04:31 - 04:39] And this will return a string. And the endpoint is only cause.

    [04:40 - 04:46] And it's causes. And after that we will pass the data.

    [04:47 - 04:59] And for this data, we will have to create a new class for our model. So inside cause.ts file, let's create a new class for register costs.

    [05:00 - 05:07] So here let's write export interface. Register.

    [05:08 - 05:21] So from the client side, we will pass title of type string. Subtitle.

    [05:22 - 05:28] Again, type string. We will pass price of type number.

    [05:29 - 05:38] Description of type string. Language of type string.

    [05:39 - 05:51] Category ID, which will be a number. And level, which will have a type string.

    [05:52 - 06:00] Here we are not passing the instructor name because we are using username for that. And we are adding the instructor name from our server.

    [06:01 - 06:12] And also we are not passing any image because I have not added image upload service as a part of this course. So I have used a default image URL, which will be used for all images.

    [06:13 - 06:19] Let's go back to the agent file now. And here our data will have a register cause type.

    [06:20 - 06:32] Now we can start creating our create cause page. So inside SRC and pages, let's create a new file.

    [06:33 - 06:44] Let's call it create cause. Let's write the function.

    [06:45 - 07:04] And turn nothing right now and export it. And inside this function, we will need a control state for our form.

    [07:05 - 07:14] So here, let's create a state for values and set values. And we will use use state hook.

    [07:15 - 07:24] And this will be of type register cause. So we can mention it here.

    [07:25 - 07:37] Now we can write our default values. So we have title and default value empty string.

    [07:38 - 07:45] We have subtitle. We have description.

    [07:46 - 07:55] We have price. And we can give it a default value of zero because it's a number.

    [07:56 - 08:00] We have category ID. Again, we can mention zero here.

    [08:01 - 08:12] We have level and we have language. And now let's destructure these values from our values.

    [08:13 - 08:31] So here we can write const and I can destructure title, subtitle, description, price, category ID, level and language. And let's destructure it from the values.

    [08:32 - 08:41] We also need a form because we are using form from Nd. So here we can write const.

    [08:42 - 09:00] Form, which will be equal to and let's import it from form from Nd.useform. Now inside the return statement, let's start by returning and let's start with the content.

    [09:01 - 09:12] So let's import content from Nd. And on top, we will have a h1 tag which will say create cause.

    [09:13 - 09:19] And we can give it some padding as well. So let's write style.

    [09:20 - 09:31] And here we can write padding and let's make it 50 pixels for now. And below this create cause heading tag, we can start writing the form.

    [09:32 - 09:38] So let's write form and we have already imported it. So in our form, we need to give a layout.

    [09:39 - 09:53] So here, let's write our form layout and let's call it const form item layout. And we'll have label column.

    [09:54 - 10:02] And here we can add property for extra small and small. So extra small is denoted by access.

    [10:03 - 10:18] And here we can mention span of 24. And for small span will be eight.

    [10:19 - 10:28] And now we can write a repo call low. Let's mention repo call.

    [10:29 - 10:43] And here the same thing, extra small will be span 24. And for small, it will be span 16.

    [10:44 - 10:54] And now we can pass this form item layout to our form. So here, let's mention dot dot dot form item layout.

    [10:55 - 11:02] We can also pass the reference of the form. So here, let's write form and this will be equal to the form.

    [11:03 - 11:08] Name of this form will be cause. So let's write cause.

    [11:09 - 11:16] Let's start writing the form items now. So here, let's write form dot item.

    [11:17 - 11:28] And we will start with the title. So we can give it name of title.

    [11:29 - 11:38] And label will be cause title. And we can write the rules now.

    [11:39 - 11:49] Let's take it here and let's write the rules. So first of all, we should have at least 10 characters.

    [11:50 - 12:12] So here I can write minimum 10. And if no 10 characters are input, we can write the message, which will be title should have at least 10 characters.

    [12:13 - 12:34] And also, this is a required property. So we can write required to be true and the message will be please mention the title of the cause.

    [12:35 - 12:42] Inside the form item, let's mention the input now. So here, we can write input.

    [12:43 - 12:47] Let's import it from Andy. This will have the same name title.

    [12:48 - 12:58] So let's write name and it should be title. Its value will be title as well.

    [12:59 - 13:05] This should also have an on change event. So let's write on change and this will take a function called handle change.

    [13:06 - 13:17] So let's start working on this function now. So here, let's write const handle change.

    [13:18 - 13:49] This function will take event, which will have a type of change event and change event can be of HTML input element or HTML text area element, because we also going to have a text area input. And first of all, we can de structure name and value from e dot target.

    [13:50 - 14:03] And below this, we will set values and we can write values at front. And after that, name will have the value.

    [14:04 - 14:15] His name is going to be dynamic and it's the same name as this input element. So this title will have a value of this title and same goes for the other fees.

    [14:16 - 14:23] Let's write form item for subtitle now. So we can copy it from here because it's not much that is going to change.

    [14:24 - 14:33] And here title should be replaced by subtitle. And let's copy it.

    [14:34 - 14:44] And let's make it least. And it should be subtitle.

    [14:45 - 14:50] And here as well. And the name should be subtitle.

    [14:51 - 14:57] The value should be subtitle. And it should be course subtitle.

    [14:58 - 15:07] And now we will write form item for description. So we can copy this one more time and we will make changes for a description.

    [15:08 - 15:19] So here let's paste it and replace title with description. So let's write description.

    [15:20 - 15:28] And we can copy it from here. And here let's make it description.

    [15:29 - 15:42] And here as well, it should be description and description here. Name should be description and value should be description.

    [15:43 - 15:54] Now let's write the form item for price. So here let's write a new form item form not item.

    [15:55 - 16:04] And let's copy the rules. Let's copy the rules and paste it here.

    [16:05 - 16:16] Also let's write name which will be price. And inside this form item rather than using input, we will use input number.

    [16:17 - 16:45] So let's import input number and let's pass name which will be price value which will be price and an on change event which will be different because it's a number and it won't have e dot target property. So when we write on change event here, we will get a value.

    [16:46 - 17:05] So what we can do is here we can mention value and after that we can write set value. And now we can write values and after that we can mention price which will be equal to this value.

    [17:06 - 17:19] And for our input number, we don't have requirement for at least characters. So we can get rid of this and here please mention the price of the course.

    [17:20 - 17:31] Let's also mention the placeholder here which will say course price. And now let's write form item for the category.

    [17:32 - 17:44] So here let's copy a form item. Let's do it from the title and paste it here.

    [17:45 - 17:57] It should be category and label should be course category. And here it should be only required so we can get rid of this.

    [17:58 - 18:06] And here we don't need the input field so we can clear it. We already have categories so we can use a select.

    [18:07 - 18:22] So let's import select from anti and select takes property options which is for the dynamic properties. So here we can use categories that we have already imported.

    [18:23 - 18:31] So what we can do is on top. So here we can write categories which will be equal to use app selector.

    [18:32 - 18:48] And here we will use categories selector if you remember from here we want all the categories so we will so we will write dot select all. Now we can create a function which will shape the data the way select from anti expects.

    [18:49 - 19:06] So let's create a function and let's call it get select categories. And here we will create an empty array first.

    [19:07 - 19:18] So let's call it category array. This will be empty and also let's give it a type because this will have a value and a label.

    [19:19 - 19:35] So value will be a number and a label which will be a string. Now we can check if we have categories in that case we can use for each function on categories.

    [19:36 - 19:49] So here we can write categories dot for each and every category will have a type category. So let's import it.

    [19:50 - 19:59] And now we can push inside category. So we'll write category dot push.

    [20:00 - 20:17] And here the value will be category dot ID and label will be category dot name. And this will be an array.

    [20:18 - 20:27] So here also we need an array. And finally from this function we can return cat array.

    [20:28 - 20:33] So if we have categories they will return and shape it. Otherwise they will return an empty area.

    [20:34 - 20:42] Now inside the select component we can pass this function as options. So here let's write get select categories.

    [20:43 - 20:53] And since it's a function let's also call it. Now the select will have a value which will be category ID.

    [20:54 - 21:05] And it will have a placeholder which will be select the category. Let's push it down.

    [21:06 - 21:20] It will take an on change event which will return a value. And we will do the same thing set values and it should be value.

    [21:21 - 21:37] And here we can write set values and inside we will write the values. And after that category will be the value.

    [21:38 - 21:47] And this select should be self enclosing. So let's write like this.

    [21:48 - 21:54] And it should be category ID. Now let's work on the another form item which will be for the level.

    [21:55 - 22:01] So let's copy it one more time and paste it here. And this time it will be for the level.

    [22:02 - 22:08] So I can write level choose level. Please mention the level of the course.

    [22:09 - 22:17] Select the level and here it should be level. The value will be level.

    [22:18 - 22:40] And let's call it choose a level. And here as well please choose a level.

    [22:41 - 22:53] And also for the category let's write please mention the category of the course . And for this we can get rid of the options because we are not using the dynamic fields.

    [22:54 - 23:03] So here rather than self enclosing we can create a normal select component. And below this we can write option.

    [23:04 - 23:21] So let's write option and we need to import option as well. So what we can do is here we can de-structure option from select.

    [23:22 - 23:33] Now coming back and for our level we can start with beginner. So I can write beginner and copy it from here.

    [23:34 - 23:39] And also this option will be called beginner. Now we can copy it two more times.

    [23:40 - 23:56] So one for intermediate and one for advanced. And now we are left with one more form item which is for the language.

    [23:57 - 24:13] So I can copy it one more time and paste it and this is a language. And here let's try to choose language.

    [24:14 - 24:22] And here as well. And now we will start with the language called English.

    [24:23 - 24:29] So let's write English and we can write Spanish. So let's write Spanish.

    [24:30 - 24:45] We can add Hindi which is my native language. So let's write Hindi and let's do it one more and let's call it Japanese because I speak Japanese as well.

    [24:46 - 24:52] So these are the languages that I speak. You can add other languages as well if you want.

    [24:53 - 25:00] Now finally we can write our button. So below this I can write form dot item.

    [25:01 - 25:14] And this time let's import a button from addy. This button will be called submit and it will have a type primary.

    [25:15 - 25:26] And this will call a function which will submit this form. So let's create on click and let's call it on submit.

    [25:27 - 25:45] And also our form has on finish property. So here if we write on finish we can pass the on submit function which we are going to create right now.

    [25:46 - 25:52] So here let's create the function. Let's call it on submit.

    [25:53 - 25:56] This will be an asynchronous function. So let's write async.

    [25:57 - 26:21] And here we can create a response because we are directly going to call await agent dot courses dot create and we will pass values. And if response is successful we can write notification dot success.

    [26:22 - 26:39] And as a message they will pass the response. And finally we will push the user to the instructor beach.

    [26:40 - 26:55] And since we don't have history let's write history which will be equal to use history. And if you remember we are returning a string.

    [26:56 - 27:06] So this will be a string which will say course created successfully and this will be shown as a notification message. Now we have created our create course page but we haven't registered it.

    [27:07 - 27:23] So what we can do is we can go to app dot t six file and we can copy it. This will be slash instructor slash course.

    [27:24 - 27:43] And this will be called create course. Let's go to the browser now.

    [27:44 - 27:48] And click on new course. So looks like something is off with this.

    [27:49 - 28:14] This is our price form item so let's go back to the browser and inside create course page and for the price we need to pass a label. So let's write label which will say course price and a placeholder which will say course price.

    [28:15 - 28:19] And now everything looks like this. We can try creating a new course now.

    [28:20 - 28:32] So let's refresh it one more time. And inside cost title we can call it learn Spanish with videos.

    [28:33 - 28:38] And since it's a test let's copy it here and here. And this should be a text area.

    [28:39 - 28:51] So let's go back and for the description. Let's make it input dot text area.

    [28:52 - 29:02] And now it looks like a text area. The price can be nineteen ninety nine.

    [29:03 - 29:34] We don't see the category. So what we can do is we can go back and inside app dot file inside the app init function we can also await and dispatch get categories async function because if a user comes to this page directly we want our app to call this function as well.

    [29:35 - 29:44] Now let's go back to the browser and let's click on languages. The level can be beginner and a language.

    [29:45 - 29:49] Let's call it English. Now we can submit this course.

    [29:50 - 29:59] And as you can see it says created course successfully. And we see my unpublished courses with learn Spanish with videos course.

    [30:00 - 30:07] Amazing. Now in the next lecture let's make another page which will be responsible for writing sections and lectures.

    [30:08 - 30:09] Let's work on it next.