Creating A User Dashboard with Redwood and Prisma - Milecia McGregor | Prisma Day 2021

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
(bright upbeat music) - Hey everybody, thanks for coming. This is the workshop for Redwood, and I hope that y'all actually get something pretty cool out of this today. So the plan is we're gonna go through and make a dashboard. And this dashboard is gonna be for students, no particular reason why, just cause that feels useful. But I wanted to give you a quick intro. My name is Milecia McGregor, I'm a developer advocate at Iterative.ai, which is completely unrelated to Redwood because we do machine learning stuff. But I'm also a huge tech nerd, so I've done front end development, back end, DevOps, database, admin stuff. And in a previous life, I did robotics as a mechanical and aerospace engineer. So the reason that I ended up working with Redwood is because last year when everything was shut down, I ended up looking at just different JavaScript frameworks because we all know about reacting angular, but I was like, "What else is out here that seems useful." So I found Redwood, jumped straight in and now I'm basically like a Redwood fan girl. (Milecia laughs) So that is why I'm here to talk to you all today. But pretty much all of this is just gonna be live coding. I don't have any type of presentation ready, it's just us making this up. And feel free to stop me with questions at any time. It's not like this is something, I don't know, we have a couple of hours, so we have time if y'all have specific questions. So with that being said, I'm gonna try the hardest thing of the year and share my screen. Maybe. Oh, there it is. Okay. So I hope that y'all can see my screen okay. Sweet. Glad that y'all can see it. So we'll just jump straight in. I was debating earlier on whether to run the create Redwood app command live, but it can take a little while and I didn't want y'all just sit in here for like five, 10 minutes while all of these packages install. But the command to set up a new Redwood app is Yarn create Redwood app and then the name of the app you wanna make. Wanna try to make this a little bigger. Yeah, hopefully that helps. But you run this command and we've named our project student dashboard, and it'll go through and install all of these dependencies and get Redwood, basically bootstrapped and ready for us to work with. So they have some really good docs which I'll be referencing throughout this workshop. And community's great. I'm gonna try to stop saying so many good things about Redwood, but I don't really have very many bad things. So since I've cheated and already installed and created this new app, I'm gonna go ahead and go to my repo and open it. And this is what you'll see after that create Redwood app command is finished running. You'll have all of these files and folders that you have never created. And one fancy thing I wanna show you, if you run Yarn, RW dev, RW is short for Redwood, we'll be using the shorthand quite a bit. Let me change my Node version. Sometimes that happens. So make sure you're on Node somewhere between 14.0 and 15.0, if you're on the newest one like I was, it will cause problems and you won't be able to run Redwood. So this is doing some stuff, getting the front end and the back end running. And pulls up this in our browser. And ta-da, you're running a Redwood app right now. That fast. And if you ever forget which local host it's on, it's on eight, nine, 10 about those cool and convenient, so that you don't have to remember a whole lot. But when we run Yarn RW dev, what that does, it starts up our Redwood app and Redwood is based on a mono repo. Wait. Oh, okay. Yep, use Node 14. Thanks for that comment, Joel. But yeah, so Redwood actually works on a mono repo scheme. So we have our front end and back end packages together, but they're in these separate folders. So let's just go through what's happening in here. In the API folder, this is where all of our back end stuff happens. So this is where we'll be using Prisma to set up our database and seed some data, which we'll do in here. And then in the source folder, we'll have some stuff for our GraphQL back end, so the GraphQL folder, we'll hold the types for our queries and mutations and services will come to hold the resolvers for our GraphQL back end. And that's pretty much it for the back end. We have this package.json so that you know it's a different service. Then we have the web folder, this holds all of our React front end code. So in the source folder, you'll find some stuff that's already been bootstrapped for us. We have the app, we have a couple of pages. So if for some reason there's a really bad error, Redwood already has something to handle it for us. And if the user navigates to a page that doesn't exist yet, Redwood already has that covered. Then in layouts, this is how Redwood handles basically the layout for different pages. So instead of worrying about the styles that need to be applied to a certain page, you just put the routes in the layout and it automatically updates everything for you. And then components is pretty much where we put everything else. So if you have any styled components, we're gonna see how Redwood handles data in a bit and that's gonna add quite a few component too, but that's what the components folder is. And then here in the routes, you'll see this is just our routing. So few comments in here, 'cause Redwood's good about commenting code. But now that you've had a quick walkthrough of what all gets installed with Redwood, Let's go ahead and stop running the app right now. And I'll clear out my terminal. And we're actually gonna start with Prisma. So we're gonna set up our database and we'll be using Postgres. If you don't have Postgres installed locally, if you just go to the, I think it's postgresql.org site, we can take a look at that real quick. Yeah. So if you come to the Postgresql.org, you can download it for whichever operating system you're working with. But now that you know that database we're working with, let's go ahead and go in this API DB folder, and we're going start by updating our schema. So the first thing we need to do is change our provider to Postgres QL, because we're working with the Postgres database instead of MySQL. And I'll save that. You'll notice we're reading our database URL from the environment. So over here, if you open up the environment file, you'll see that there's this commented out line for the database URL. So go ahead and uncomment with that. You want this to be your connection string to Postgres. So I'm super original when I come up with my username and password from my local instances. So these are my credentials, and no they're actually not that unique. They're pretty simple. So my username is Postgres and my password is admin. So when you did set up your Postgres instance, whatever username and password you gave it, that's what these two values will be. And I'm not running on postgreshost.com, I'm running on local host. And the port should be fine unless you have something running on it already, so make sure that when you do configure or you have configured your Postgres instance, know which port you're pointing it to. And then for the database name, we'll just call this student dashboard. All right. So this is just our connection string to get to our Postgres instance. We shouldn't have to do anything else with that file. Sorry, sometimes the Zoom controls are right above the little tabs here. But anyways, so we have our database URL to find, we don't have to worry about this stuff 'cause it just makes it quiet for us. And of course, Redwood has some bootstrap code. So gonna remove that to do. And we're actually gonna start building our student database model. So let's say we have students which are our users. We'll call this model student. And this will be the name of our table in Postgres as well. So I know sometimes people like to do pluralized names for their database tables, but with Redwood things work out better if you just use the singular form, just because of how it handles things for you automatically, you don't have to, you can tweak things to however you want, but just know it's a little bit easier when you use the singular form in Redwood, but we'll keep going, so we have an ID email. We'll keep that. We should probably know their name. You don't really want students in your class and you don't even know their name. So we'll add the first and last name. And let's add a role which will be a string. So we have our student models and we're gonna make a few more things. So something else that students probably care about are their grades. We wanna make sure that we have a way of storing their grades in the database. So we'll make a new model called grade and we'll give it an ID just like the student. So I'll copy and paste that down here. And what should we call this? So this is their grade, I guess let's just call it grade. It will be a string and we will have grades that are associated with each student. So to do that, I'm gonna go ahead and make this student ID. And it'll be an int that refers to this student ID in the model up here. And above it, I'm gonna make a two digit connection. So a student relation, I mean, and what this does is just gonna connect our student to the grade. So we'll have add relation. And the field we'll be using is the student ID, and this will reference the ID in the student table. And I'm gonna go ahead and format that. And what this does is it adds this array of grades to our students, which is pretty much what we expect because a student will have a specific grade and something else we should attach is probably the class name. Let me change that to course name, so that doesn't get confusing when we move to the front end. And that'll just be a string, I'll format a little bit. Actually let's just make this course. We haven't made the model for it yet, but that's okay, we'll come back too, so for now, let's just comment that up. And we're gonna make a model for the courses. So students are probably signed up for multiple courses and we need to know which ones they're in. So that means a student will have a relationship with multiple classes. And so same thing, we'll add an ID here, and then we'll add a name, which was just gonna be the name of the course. And let's see, every course will have. (Milecia mumbles) I'm trying to think about these relations. So if we have a course, students can belong to multiple courses. So I think what we'll do is add a course ID here, and this will be a foreign key. That's basically what this relation is doing, it's adding a foreign key in our database. So we'll have a relation to the field course ID and this will reference the ID of this course table. So we know that students will have a course ID. We know that each course will have a grade, but I'm just trying to make sure this makes sense. And while I'm doing that, does anybody have any questions they'd like to drop in the chat? Like I said, I wanna make sure y'all feel like you can actually ask stuff because it's not just necessarily me talking to y'all if y'all have questions, we're friends. But we have our course, we have our student and we have the grade for those courses. So grade will be attached to the course, which is attached to the student. I think I'll just leave it like this for now. No need to make it too complicated. But regardless, we have these three models, which correspond to three tables in our Prisma database. So now we're gonna go ahead and seed some data. That way we won't get weird errors when we make the page for this stuff. And of course, Redwood has a bunch of good comments in here. So if you're not familiar with database seeding, you can check out some of the Prisma docs. And if you need just more of those details about how seed migrations and all that works, you can check out Prisma's docs. But for now, I'm gonna come in here and uncomment this code. And we're gonna do something similar to this, but we're just gonna make on entity for each table. So I'm gonna delete a bunch of stuff, like a lot of stuff. So I'll get rid of pretty much everything except the, oh wait. Don't bracket too hard y'all. (Milecia laughs) Okay. Now we're just gonna seed individual roles and gonna delete this too, because we won't be able to see more, but we're going to start with our student. So we'll create a new student in a database. We'll need these fields. So we have our email, which I'm just gonna make up. We'll say it is testbest.com. We have first and last name. So first name will be, I don't know, Kaiya. Last name will be Best. And what else do we need? We need a role, so we'll just say student teacher. Student teacher. And what else did we need here? Ah, of course ID. So when we make the course, I'll actually do that before we create the student, it'll make a new ID. And since we're auto incrementing an integer, it's just gonna be one. So that's how we know what the course ID here is. And actually I'm gonna go ahead and swap these two things around, just so it looks like we're actually writing stuff, and I'm gonna copy this await here and paste it up above. And we're gonna create a course now, which will be a lot easier 'cause there's only two things to put in there. So I'm gonna delete all of that. And in here, will just be name and we'll say Redwood. Yeah. That's all we need in this one. Sweet. And then we'll make our seed data for four grade. So we already have our student. I'm gonna copy this and we'll make a grade, which would just have the grade and the student ID. So we're gonna say that everybody here today gets an A. And the student ID is just gonna be one, 'cause like I kind of explained earlier, since we are just auto incrementing our integer for the ID, when we run this seed, it will make a new student called Kaiya, and her ID will be one. So now we have everything in place that we need to run in migration. So let's see if I actually typed everything right. And we'll run Yarn RW Prisma. Migrate. There. Might need a name for this. So we'll just call this the initial migration. And if you notice over here, we have this new migration spile and it generates the SQL for us. So we have everything that we need, it even made our foreign keys, it made this unique index. Yeah, it just did everything for us. Nothing is no. So if I come over to my Postgres instance. And I refresh it, you'll see this new student dashboard database. And if I drop into the schemas and tables, you'll see the three tables we made. So let's see if my seed data is here. My seed data is not here. So I'm gonna take a little peek at another thing that I made, just to make sure that I didn't do something weird, which happens quite a bit to me. Doesn't look like anything weird happened. Let me try to just run the seed manually. So if we do Yarn RW Prisma DB, then we run seed. Okay, it says it's been seeded. Let's see, yip, there we go. I just needed to manually run that seed. And after we did the migration, we just seeded the database with this Yarn RW Prisma seed command. So if I go back in Postgres, you'll be able to see all of the data that we made. So let's check out our student and boom, everything is in there exactly like we expected it. This is off to a good start. Stuff is working right. I like that, but anyways, I'm gonna clear out the terminal now. Now we have our back end in place, at least the database part. And now I'm about to blow your mind with some of the stuff Redwood can really do. So we are going to make a new page. This is gonna be our homepage. And yeah, it's just what the root of our app will go to instead of the placeholder right now. The way we'll make this page and the way we'll be doing a lot of stuff is with some of the Redwood COI commands. But before we jump into that, I wanna check, anybody has any questions so far? Don't be afraid to post something in the chat. I'll be checking it just throughout, so if you don't have anything right now, that's fine too. But we'll run Yarn RWG, which stands for generate. and we'll generate a new page. And we'll just call it home because it's gonna be our homepage, actually, let's be more creative, let's call it a dashboard, 'cause we're making a student dashboard, so a homepage should be that. So we're gonna make this dashboard homepage in a way that we direct the root of this page is just by adding it to the end. So we're saying we want dashboard to point to the root of our app. And we're gonna go ahead and run that. Generally, if you don't specify the route that you want, Redwood we'll just create a route based on the name of the page that you give it. So we've generated this new page, this is inside of our web directory. So the first thing I wanna look at are the routes. If you look here, we did not add this route, it was auto-generated or automatically added when we ran this one command. And now when we run the app, it will go straight to this dashboard page. So if we go into pages, you'll see this new directory called dashboard page, and it has the dashboard page component, we have a storybook story for the dashboard page in case we wanna do some kind of component driven development or we just wanna test this component in isolation. And then we also have tests already. Redwood generated all of these files, pre-populated with stuff for us, just for this one command. And this is where Redwood started it to, guess, steal my little tech heart. It does so much for you, but it doesn't do it in that black boxy kind of way that a lot of frameworks do. You can go in and edit all of these files. If you wanna completely gut this, you can, Redwood doesn't hide anything from you, which is really nice. So we're in this dashboard page and I'm gonna run the app with Yarn RW dev, just so you can see what this looks like now. So it's loading up for us. And you see, this is not the placeholder we had before. This is exactly what is in this file here. So is gonna serve as our dashboard homepage for everything. But before we get too far into this page, I wanna show you the cool thing. So I'm going to open up a new terminal down here and we're still in the same directory, but we want to be able to add new students. we wanna be able to add new courses and we wanna be able to give students grades. So the way we're gonna do this is by creating this entire CRUD functionality for all of those actions. And yeah, this is where Redwood gets incredible. So we're gonna run Yarn RWG for generate and we're gonna do a scaffold for courses, but we'll just say course. So I'm gonna run this. My local setup is a little weird, I'm sure we all have those quirks. But when I open a new terminal, it just resets my Node version. Should fix that one day but not right now. So I'm gonna go back up in the terminal and run this command. This is where Redwood flexes itself. So when you run the scaffold command, it makes everything for you, it makes the front end, the back end CRUD, everything. So let's just dive into this, in pages, you'll see we have this new course folder and inside, of course, you'll see we have all of these different folders. So we have a file to look at an individual course. We have one to look at a bunch of courses. We can edit a course. We can make a new one. All of this is just here for you. And let's take a look at the routes, you'll notice we have all of these new routes too. So we have a route to make new courses, edit them, look at them individually, look at a list of them, it's all generated for you. We even have a layout for this course already. So if we come back up here to layout, you'll see this courses layout folder, and it's just this layout in place for you. You didn't have to do anything to get this, it already has styles applied, it's just nice that it did every thing for you. But that's not all, so that's just the front end piece, part of the front end piece. If we look in the component, you'll see there's a course folder that has a bunch of new stuff. So if we look at this course file in particular, you'll see that we have bunch of stuff in here that handles the course details, we can edit, we can delete, it even has the GraphQL mutation in here for you. It's already there and it's already being created basically. So we have that for one page, then we have this course cell. So cells are something that are unique to Redwood and it's just the way that Redwood handles data management. So you're able to pull in your course information through the GraphQL query and this cell handles it for you. So if it's still in a loading state, this message will get displayed. If there aren't any courses returned from this query, then this gets displayed. And if there are courses returned, or if there's one course, I should say, since we're getting it by an ID, this success component will return that course component we just looked at, but with data inside of it. So that is where course comes from in this component, it's coming from this cell. So that's just a little bit about how Redwood handles data. And then we have a form, I don't know about y'all, but sometimes I just hate making forms. You don't have to hate it anymore because Redwood does it for you, it even has a built in error handling. (exhales heavily) I don't know, that makes me super excited, so I'm gonna try to calm down, but we have the form. If you do have multiple courses, then it'll show all of them in this courses list, which is just a table that has all of the courses returned from the database map to different rows. And we get this data from our courses cell. So here, this is where the query comes from, where we fetch all of the courses from the database. This is how we handle, if it's still loading, if there aren't any courses, we'll link the user to create a new course. And, yay, thanks for the feedback, Jake. I'm glad that it feels familiar, or it's good so far, But anyways, so empty state, we have the ability to direct users to make a new course. And if we actually get some data back from our GraphQL query, it will display that courses component like you saw here. So that's a little bit about how Redwood handles data management, how it handles forms, plus take a look at this edit cell. So this is another one that we have our query already here for us. We actually have a mutation here for us, since this is the edit cell, we would be updating an existing course, which that makes sense. And we have our loading as usual because this is probably pulling up an individual course. And then the success, when we submit it, it's just posting this to the back end through that mutation we have up here. And this is just the form. So that's all happening here. And then in new course is super similar. So you already have your create mutation here. You have this new course component that uses the force. Everything's just already in place for you, which makes getting a really complex app up and working really fast. So yeah, again, Jacob, you're right, you don't have to make a whole lot of decisions to get rolling. Pretty much to get started with Redwood, as long as you know what your database schema is gonna be like, you already know what your functionality is. You can just use Redwood commands to generate everything else, 'cause this was just the stuff it made on the front end, we haven't even touched the back end. It has all these GraphQL queries and mutations in place, but we didn't make any of these. We didn't do this. We haven't made any types. But if I close all this stuff and go to the API folder, you'll see, we didn't have to do any of that. This scaffold command. Look at that. We have this courses SDO with all of our types defined. We have our mutations defined, everything is here. So the way that this gets generated is based on that schema.prisma file we made earlier. Redwood has a way of just taking the schema and generating everything based off of it. So we don't even have to worry about syntax issues, it's already done. And the reason that this has giving us an error right now is because we haven't generated the student type yet. But don't worry, we will very soon. I just wanted y'all to see, look at all the stuff, it's just here. We have types, we have queries, we have mutations and we're not done yet. If you look in services, there's this courses folder that has all of the resolvers. It has a scenario for us where we can define some data that we use in our tests. It actually made the GraphQL tests for us, which is pretty crazy. We didn't have to write any of this code and it's already a maintainable project, which is wild. So we have our resolvers in this course.js inside of our services folder. And you'll see that if we were doing like a production app, you can require authentication right out of the gate. But since we're not worried about authentication right now, we're gonna look at these queries and mutations. So these make calls to the database using some Prisma stuff that Redwood has kind of put a thin layer on top of, just to make it, I guess a little easier. But pretty much, we have our call to get all of the courses, we find many. We have the thing to get one course by ID, the mutation to create a course, the mutation to update one, the mutation to delete one. It's just here. We didn't write any of the code. And now we have this fully functional front and back end CRUD. And I'm gonna show you that it's fully functional because we go back to the browser and I'm gonna go to this courses URL. Oh no. Why did it crash on me? Oh, sometimes when you make a bunch of changes, (Milecia sighs) this is where it gets a little tricky with Redwood. So if you go ahead and define your model with these foreign keys and you use Redwood to auto-generate a lot of things, you're probably gonna need to go ahead and auto-generate everything, you don't necessarily have to, but Redwood is gonna make references to those other types, like I showed you here in API. If we look at this type, it already has a reference to student, but student doesn't exist. So that's where this error is coming from. And we'll go ahead and fix that by scaffolding the other views. So we'll run Yarn RW generate, which is just G for short and we'll run scaffold for student, and it's gonna generate all of the exact same files just for students. So you'll see this new SDL is in here and it has our students. So we're gonna go ahead and finish up. 'Cause you see we have this grade, that's definitely gonna be a problem. So we'll run Yarn RWG, we'll scaffold our grade. So now that we have everything in place, we should be able to run this, but I might need to restart the server, so let's see what happens. Let me refresh this page. Oh, we didn't need to restart the server, it just works, because generally Redwood just works, it's the thing that I enjoy the most about this framework. I've done quite a few live demos with it and it very rarely breaks, and if it does break, it's probably because of something that I did or I forgot to do, just like you saw a second ago with getting this course's view to show. But what we have here is this table with the data, we seeded in the database, if I click quick show, boom, is just this course one detail. If I edit it, it brings up the form where we can change this to, I don't know, Redwood Prisma Day. Yeah. If I stop using caps lock, that might be nice, but we'll save that, and I just wanna show you it's working, so we'll come over here to the database and this is what it looked like before. And now this is what it looks like now. Yeah. So thanks Dean, I'm glad that this is making sense. I hope y'all are as excited as I am. I'm really trying to keep it not, I'm not trying to fan girl too hard here. (Milecia laughs) But anyways, we haven't written any code outside of making that model. That's it. We didn't make this, we didn't style this table. Look at this, look at this new course thing. It's just here. Let's make a new course. Let's call it Redwood GraphQL, I don't know, just making up a name. But if we save it, boom, it's right there in the table, if we come back to Postgres, it's right there in the database and we didn't write a line of code for this. If I want it to go ahead and delete this one, it even asks for confirmation, it doesn't just randomly delete stuff for you. So if you confirm, it's gone, if I come back over here, it's also gone, all of that and we didn't write more than a few lines of code. It's beautiful. So we have all of our GraphQL definitions. We have all of our resolvers, we have a fully functioning app. Like pretty much anything we do from here is just adding Polish, cleaning things up and making sure that it is ready to ship. Yes. So we're basically getting ready to ship it and what we're gonna do, I just wanna show you, that all of these pages exist in our functional and it also makes me feel better to know that stuff is working. So if we go to the parades route, look at that, it's already there. And then if we go to students, I bet you, it's already there. Look at that, it's just so nice. But now I wanna show you a little bit about the details of Redwood. So we have the CRUD, we have the back end, we have everything we need laid out here. So on the front end, we need to clean things up. It would be nice. We don't have a layout for the overall dashboard, so that's something we should probably get together, and you guessed it, there's a command for that, so we're gonna run Yarn RWG, and this will be a layout, and we'll call this dashboard because when we created the page for the dashboard, it didn't auto generate a layout. It just made the page, the test, the story book, and it added the route. It did so much for us that we can add our own layout. So when we run Yarn RW generate layout, this just generates another thing, it's not ready for production yet because they're still getting the 1.0 version ready. So I wanna say that should be done in a few months, but do not hold me to that at all. That's a core team decision and I'm just a humble fan, but I think that it should be ready in like a couple months. But with that being said, let's look at this layout, so it has the storybook, it has tests, all of that's already in there. But what we really need is to decide how we want to style this, and the way we'll do that is, I'm gonna add the style component library to the project. But there's something you have to keep in mind when you add packages to a Redwood project, you wanna make sure that you add the package in the right directory. Because like I mentioned a little earlier, this is like a mono repo, so we have our front end and back end services together and doing just an overall Yarn add at the root level, will not work because there's nothing at the root level. So for us, they'll clear out this terminal again, we're gonna CD into the web directory and this is where we'll add the style component package. So we'll run Yarn, add styled components, and we'll just be using this to make our layout actually look like a dashboard. So I'm gonna go ahead and import style component up here. So we'll import styled from styled components and we'll use this to make some new stuff, I might be a little bit of a weirdo here, but I like to have my component at the top of a file, I know most people do it the opposite way, but it makes sense to have the style components at the bottom to me. So feel free to put yours on top if you like. But the first thing we'll do is just make a container. So we'll make this container and it will be equal to styled.dev, we'll use the little back ticks because we need a, what is that? A string template? And then we will say that this is a flex, so we'll give it a display of flex. I think that's it for now. Maybe we'll make sure it takes up the whole width. So that'll take up a hundred percent of the page and I'm gonna to wrap the children. That's so weird. I'm gonna wrap the children in a container. So we'll put that there and go ahead, I wonder if my formatting will do that. Nope. So I'll do this like this. There we go. So now we have a container for our children, but there's one thing that we might wanna add. Having some navigation to those different pages would probably be useful instead of just having to manually go into that URL, like we have been. So to do that, I'm gonna make another styled component and I'll call that nav. And it will be a styled nav, because we still wanna keep those HTML semantics straight. That way people who are using devices like screen readers can still get around the page easily. So that's why we're using the nav here. But we'll say this has a width of 20% and what else? Let's give it a right border, did I type that right. I don't know. We'll find out if that is the right way to type that CSS property. Sometimes I forget the names of them. But anyways, we'll have this as a solid one pixel. And I don't know, let's see what random color this makes. Yeah, no clue what color that's gonna be, but it'll be something, so I'll say that. And then inside of our container, just gonna drop down and add this nav here. So now we get to talk a little bit about Redwood routing and I'm gonna steal an example from our dashboard page. So Redwood handles routes pretty similar to everything else, it's just the way that we add a link is a little bit different. But I'm gonna take this import line from the dashboard page and just copy it. And I'm going paste it over here. And I'm also gonna copy a link, well, this link here, and we will put this inside of the nav. So now I have a link to the dashboard, which just takes us home. If you look over here at the routes, you'll see that all of these have a certain name and that name is how we reference the route that we want. So back here in the layout, you'll see this routes.dashboard, well, that is referencing this dashboard name. So that's where those things come from. I'm gonna do this and we'll copy and paste this, think three time's enough. So we'll go to our courses page. We'll go to the student's page and we'll go to the grades. And just because I feel like that's is gonna look really funky, I'm gonna add another style. So inside of this nav, I'm gonna add a child selector thing. So on this we'll say that we'll add a padding to the bottom of 18 pixels. And this CSS might not even be right. We'll find out here. So let's go back to the browser and go home. Oh, something we might need to do is actually use this layout. So if I come back to the routes, you'll notice that we have these set components that wrap certain routes in certain layouts. So when we were running the scaffold command, it was generating these routes wrapped in the specific layout for that page. But now we wanna apply this dashboard layout to all of the pages. And we'll do that real simple, we'll use another set component. So at the very top, we'll have set wrap equals dashboard layout. And it probably, yip, it auto imported that for me, I don't know if it'll do that for everybody or if that's just part of my settings locally, but it's there. So we'll close that tag, and I'm gonna the that closing tag and move it right down below the dashboard page. So I'm deleting the not found page out. I don't know why I'm leaving it out, it felt like a good idea. But let's go ahead and wrap that in there too. That way, if they are somewhere weird, they can click on a link to get out of there. So I'll save this and then come back and see why there's an error. It shouldn't matter, but I'm gonna import that. Let's see, gonna refresh the page. Yeah. It's here. It's pretty ugly, but that's okay. It is okay 'cause I just wanted you to see that we can do this. So if we spend a little bit of time just styling this, what I really wanted to do now that I think about it, was make this display flex and then we'll do a flex direction is column. Let me see if I did it. Yip, that is what I was going for. Maybe if I add that back and do all of those with padding bottom of 18 pixels again. Okay, that's starting to look like something. So I'm gonna try not to spend too much time on style and all of this, but the next thing we'll do is just add a container for our children. Think that's so funny to say. But we'll make a new container that we'll call component holder? Names are hard, y'all. So this will just be a dev with those same template strings. And we'll give this a width of, let's say 75%. And we'll give it a padding, might not even need that with, but we'll see in a second. So I'm giving it a padding all around, of 24 pixels, and now I'm gonna wrap the children in this component holder. Move that tag down here. And save it. Hey, it looks okay, we'll take that way width. The last thing I'm gonna do as far as styles on this is probably just add a height of a hundred view heights, that way this takes up the whole page. So maybe I need to do that at the container level. Yeah, that looks like a dashboard, that looks like a real dashboard y'all. I'm okay with this. So now that we have that in place, let's actually click through. Now it looks like something people might actually log into and do stuff with because you can navigate around. Let's say I go to the wrong page, it still gives me that page not found. Did I wrap that page not found in here? I did. Well, now I found this or something, we can edit that. It's just the way that Redwood put it in initially. But let's add a new course just to show you something real quick. We'll call this GraphQL again. I'm gonna add a new student, but how about best@rest.com. And we'll have Beth Bowman. And she's just a student, but she's in that new course. So we got that. And then we will give Beth, which her ideas two, we'll give her a B. So we get that in place. Now I wanna show you what happens if you need to make updates to your data base, so this is pretty common, sometimes you'll be working on a project and a client will come back, or a product will come back with a new requirement and you need to completely update your back end. It happens. So in this case, let's say that on student's table, do we want on student? No. Let's say we will have a course ID also associated with the grade. So if we come back in here and close all of our awesome fricking stuff. We'll go to the API folder, open up our schema. And what we'll do is add another foreign key to the grade table. So we wanna associate a course with these and that's what we'll be doing. So come back over here, we will add another foreign key. We'll call this one course ID, and it's in int. And that relation will be two course, which will have a type of course, and we'll have a relation of fields, we know we're gonna reference this course ID. And the course ID is going to reference the ID in the course table. So I'll format that. There's some shortcut key I have, but whenever you make a foreign key relationship, you'll notice that it tags the table onto, it makes a reference to the foreign key table on the primary table, if that makes sense. So you've got to have that there so that the two tables are connected. So I'll save this and come over here. Clear my browse, clear my terminal like I normally do. And then we'll run Yarn, RW Prisma my great dev, so we're adding a new migration. Oh, there is something that I think we wanna do. So since we're adding a new value after an initial migration and we have data in the data base, we probably wanna make this course ID optional. Well, there we go. So the reason that we're doing this is because right now, the way that our database is set up, we don't have a course ID for those students that are already there. And we can go in and update that in a number of different ways, which we will, but just to get this migration going, we're going to make this course ID an optional field. So, oh, I'm also in the wrong directory. So I'm still in web here, but I shouldn't be in web when I'm running Redwood commands, you should be in the root of your project directory when you're running Redwood commands. So we'll do Yarn RW Prisma, migrate dev again. Okay, that's better. And we'll say we added course ID the to grade. Okay. So now that field is on our table, we need to go ahead and update couple things in our GraphQL. So we'll update this to have, the grade type to have course, which would just be course. And we're not gonna include the exclamation point because these are optional, so we'll have a course ID of it. Let's see, probably need the course ID for creating a new grade. And we'll also need it when we update the grade. So we have our types updated, that should not change anything with our resolvers. Nope, nothing to change there. And yeah, if we come back over here to the browser and refresh. Wait, there's front end stuff we need to do too. So this is why you wanna try to have as much of your model defined upfront. You probably wanna do that in general, but with Redwood in particular, since it can handle so much out of the box for you, if you have your model clearly defined upfront, when you run these commands like scaffold, or you make a new layout, or maybe you just run to generate an SDL in general, it will have everything that it needs to do that. But this is also the beauty of Redwood. You don't need the Redwood commands to make updates to your files. You can just go in there and edit them like you would normally do. So what we're gonna do, if I can just get that to close. Sometimes the little Zoom commands are just in the wrong place. So let me try, there is no better place for it. Anyways, I'm gonna go ahead and close out of the API folder and we'll go back to web. So over here in our grade, let's take a look, so we know when we are fetching data, now we wanna bring back the course ID. So I'll save that. And when we are updating data, we'll probably also want the course ID. Let's see, what else do we need here? That should be good for editing. Then if we look at the grade component, that's fine. Great, so let's bring in the course ID. And then, let's see, for the form, we definitely need to add that to that form. So the good thing is that we can just do some copy pasta, so we'll just take the student ID field, copy it and paste it below. And just update some names. So this will be course ID, type that in, this will be course ID, what else will be? Everything is course ID now, so we'll have that. And what else? I think that is all of the course ID updates we need here. Yes. So let's take a look at grades. We don't need to update anything there. We'll get that cell, probably need to bring in this course ID here. That's it there. The new grade. Yeah. Yeah. I guess we don't need to return to the course ID when we make a new grade. That's fine. So now with all of that in place, if I refresh. Modified that, everything is updated now, why are you not showing me this course ID? Let's see if it's in the form. It is in the form, a student ID isn't in the form. Oops, I deleted that. That's my bad. So now we're gonna remake the student ID one. So we'll just update these again to be what they were initially. No big deal. So that'll be student. Oh, we need to, where's that table? That is why it's not showing. Table, right here. I need to add that student ID here, that would help. So we'll add that. Not student ID, course ID. So we'll add the course ID here and save everything. And now we have everything. So I'm gonna say somebody got a B plus, we'll give it to Beth, why not? And the first course, so we'll save that. And there you go. So like I mentioned earlier, we need to update these two to have a course ID and then we can actually update that migration one more time or I should say we can make a new migration. So that course ID is always required because you probably shouldn't have a random grade just floating around with students that's not attached to anything. So I'm gonna go ahead and edit this and add that course ID to the first student. And then I'm gonna add a course ID for the second student. I'm gonna put two here. Everybody's in the first class. Oh, wait, did I put? Oh, that's right, we deleted that, so this will be three. So those auto-generating IDs, if you delete anything, then that ID is no longer valid. But anyways, we have a new course ID and all of that good stuff. So let's come back here and update our schema. So I'm gonna remove this optional flag from everywhere. So on the back end for our grade, let's make this required. So we'll just be adding some exclamation points because we're really excited about these course IDs. So we've got that in place. Now I'll switch terminals, clear that one out and we'll run another migration. So Yarn RW Prisma, migrate dev. Made course ID required. On. Great. So now we're able to make this a required field for all of the future inputs. The only reason we didn't do that before was because we had existing data that did not have a course ID attached to it yet. But since all of the data in the database has a course ID now, we are good to go. So this is actually it. This is what I have for you for making this Redwood dashboard with Prisma. And I hope that it was really informative, I hope you got as excited as I did because we did a lot of stuff without writing a lot of code. And I'm gonna push this repo up to get hub here shortly, and I'll drop a link to it in the Prisma Day channel in Slack, so if you wanna take a look at this code in more detail, it'll be there for you here in a little bit. But before I disappear, I wanna know, do y'all have any questions whatsoever? This felt like a lot, but at the same time, we really just ran a few commands. As long as you're comfortable with React, GraphQL, Prisma, or just some general database setup stuff. You're pretty much good to go with Redwood. So does anybody have any questions for me they like to put in the chat? Or you can reach out to me on Twitter @FlippedCoding, I can drop a link to that here. Oh no, that's not it. So yeah, if you have any questions about this or anything else Redwood, the GraphQL, Prisma related, feel free to reach out to me on Twitter or in the Prisma Day channel on Slack or wherever else you can find me on the internet. So I'm gonna open it up or throw the offer out there one more time for questions. Ooh, is it possible to map a Prisma response to a class that includes methods instead of a plain object? Yeah, I don't see why not. Are you talking about here in our resolvers? Let me get one open real quick. So do you mean we have a method in this delete function instead of just doing a plain old object thing here. Like we do some data handling before we get to the delete part. Is that what you mean, Eduardo? Ooh, yeah. So there's no problem there. You can definitely just have a response in there instead of just a regular object. As long as you execute the Prisma requests, like with a delete or update or whatever, you can put anything inside of here, as long as it maps to your database, you can put anything inside of the data, you can put anything inside of this function, if you have some processing to do before. Did that answer your question, Eduardo? Yeah, I think so. But, what? The objects that are returned to the client.find method. Oh, you're fine, no worries about the English, I barely understand English myself, so worries. Do you mean over in the web? Let me see, do you mean like in here? Where we return the stuff in the query. And then Jacob to answer your question, you can host it on Netlify, Vercel, those are the two that are just off the top of my head. But yeah, there's a couple of other places that Redwood has really good host support for, but it's somewhere in the docs, but I know Netlify and Vercel are already up there on the list. No, I don't think you need Node to host, you can just throw it up on one of those quick things like Netlify, probably Heroku. I'm not sure. Oh, you mean the client object of Prisma. Eduardo, you mean actually inside of the Prisma command? I think I got you. So you can still map this stuff. Where is one of the good ones? Let's look at grades maybe. Yeah. So basically what you could do, is inside of here, if you had like, I don't know, you know specifics of what is in the database, so you could have something like, I don't know, what did we have in grade? Course ID would be equal to input.courseid. Or maybe you have it as course number or something. So if you wanted it to destruct that object like that, that's fine, there's nothing stopping you from doing that. As long as when it gets to the database, it matches the model that you made, whatever you do inside of that object is up to you. Does that answer your question, Eduardo? Yay, I'm glad we got that worked out. So did anybody else have questions? I have no problem answering whatever you feel like asking. I'm also getting really good at sitting with awkward silences because of how much a virtual stuff has happened in the past year. So I'll give it a few minutes, but if nobody has any questions, you can feel free to leave and go back to some of the other Prisma Day workshops. I'll be around for a couple more minutes. Oh yeah, this is recorded too. So if at some point you do wanna come back and look at this talk later, I'm not sure when the people at Prisma are posting these videos, but it will be live at some point. I do hope this at least got everybody as worked up about Redwood accounting when I first saw it, 'cause it completely blew my mind. I saw one command can make my front end and back end. And it does all the crack stuff. It's like, holy crap, this does everything. I don't even need to write code anymore. But when you start adding some of the, after you get past the initial setup and you need to start adding features, and you need to start making updates to things. It gets back to the regular code, it's just Redwood give you such a big jump out of the box that you can get to feature implementation and start iterating on things like that a lot faster than you would if you had to build out the form, build out the GraphQL services and build everything. So it's just a great way to get you jump-started. But if nobody else has any questions for me, then I think I'll go ahead and check out. Thanks for coming to my workshop everybody. And I guess I'll see all around the internet. (bright upbeat music)
Info
Channel: Prisma
Views: 239
Rating: 5 out of 5
Keywords: prisma day, prisma day 2021, redwoodjs, prisma
Id: Oa_W6cCY4x0
Channel Id: undefined
Length: 86min 31sec (5191 seconds)
Published: Wed Jul 14 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.