NextJS ChakraUI Prisma Social Dashboard | Episode 7
NextJS ChakraUI Prisma Social Dashboard | Episode 7
NextJS ChakraUI Prisma Social Dashboard | Episode 7 Hey! In this episode we implement the dynamic route for each post and we implement Prisma on routes/api as well. We also implement comments component / api.
Work with devcontainer: • Getting Started with VSCode devcontai… I remind you that you can also work locally, devcontainer is not a must. Mac users: don’t forget to enable access to workspaces in Docker desktop in settings/resources/file sharing and add the /workspaces path.
Demo: • Social Dashboard New Tutorial Announc… Episode 1: • NextJS ChakraUI Prisma Social Dashboa… Episode 2: • NextJS ChakraUI Prisma Social Dashboa… Episode 3: • NextJS ChakraUI Prisma Social Dashboa… Episode 4: • NextJS ChakraUI Prisma Social Dashboa… Episode 5: • NextJS ChakraUI Prisma Social Dashboa… Episode 6: • NextJS ChakraUI Prisma Social Dashboa…
Timeline: 00:00 intro 01:50 post detail api 09:15 implement babel superjson 11:45 Post Detail component 26:40 comment section 33:00 Comment Form 45:00 comment create api
Content
0 -> (gentle music)
2.03 -> - Welcome back, guys.
3.47 -> We are at episode seven,
6.29 -> and until now, we are
able to log in, sign up,
11.96 -> create users, create posts.
16.4 -> And in the last video,
we also had the chance
20.24 -> to be able to delete the post we created.
27.75 -> So this one, too, I created.
32.04 -> Read more, want to implement this.
34.68 -> So the dynamic route and
render the component.
38.84 -> And if I sign up as Jane Dane.
44.24 -> Don't remember if I already,
47.53 -> okay, login.
49.73 -> So, as you can see now, the John Doe post,
52.4 -> we can now delete magically,
56.41 -> and we can delete our own post.
59.58 -> Okay, so let's start to
implement the dynamic route.
63.38 -> So we have post here, and,
70.06 -> maybe let's write something
more concrete, like second post.
73.023 -> I want to go on this post seven or the 10.
79.14 -> Okay, so let's stop this
and maybe try to see
85.13 -> how can we do this on the read more button
88.67 -> in the read more button here.
92.72 -> We have the component,
but on the component,
97.21 -> this route here is not implemented.
100.47 -> So we should maybe take
a look in the API here,
108.03 -> and, close to API, I
wanna call another folder,
115.3 -> because we have API,
116.93 -> and all of the API, here, routes.
119.01 -> And this one I want to separate here,
121.54 -> and inside this post, API,
127.92 -> in the pages posts, I want to
create the dynamic [id].tsx,
137.224 -> as the good Next.js
route naming convention.
143.82 -> And I want to export const.
149.18 -> This will be the getServerSideProps,
157.08 -> of type getServerSideProps from next
163.73 -> equal the async.
170.39 -> We will have a params object here,
172.95 -> because we will need some
params from this returning.
178.92 -> And let's see what this is telling to us.
185.7 -> Props param, and...
187.22 -> Okay, maybe we should try
to continue writing this,
192.35 -> and let's see.
195.455 -> Did I import everything?
199.25 -> Because he already wants
the returns, I think.
202.06 -> So, return, props.
208.01 -> And I think, yeah, that's okay.
213.453 -> This will be the object.
216.72 -> We will call it matchedPost.
220.69 -> Okay, so what the heck
is the matchedProps?
227.09 -> I want to declare the id,
231.13 -> and type as a number,
236.63 -> and this will be params.id,
242.14 -> but check if it exists,
not throwing errors.
249.32 -> const, we take the variable name, equal,
255.79 -> and now we start to do some prisma,
260.25 -> from lib, dot post.
264.98 -> So findUnique, of course,
because we only want to find
271.336 -> the posts that corresponds to that id.
276.19 -> So findUnique, where,
282.48 -> id is id,
289.03 -> then, include,
292.29 -> so what do we want to include?
298.91 -> The author, the author
object is important,
304.07 -> and in this author object,
want to select what?
308.29 -> The email and the id.
310.72 -> So select, another curly
braces, email, true,
323.07 -> and the id, true.
327.63 -> So select the author,
332.53 -> under the author, the likes.
340.46 -> Oh, select and, again,
345.39 -> so select in the select object.
352.42 -> We have the id.
355.18 -> It's everything nested,
so I'm trying to focus,
359.71 -> okay, you know what?
361 -> Gaining a little bit of time,
362.82 -> I just copy and paste for being sure.
366.95 -> So likes, we select the id, and the likes,
370.17 -> we bring again the object of author,
373.4 -> and we select the email and the id.
379.68 -> So, because here we have
basically the three main objects,
385.58 -> the author, the likes and,
under the likes, the comments.
389.59 -> In the comments, we select the text,
391.56 -> the id, the author object,
and we bring them all,
397.01 -> and we return the props post, matchedPost.
404.198 -> So we close all of this stuff.
406.21 -> and let's declare an object called Detail,
414.16 -> I mean, the functional component,
420.2 -> here, we take the post.
428.561 -> We want to create these post id props
434.94 -> in all of the props and...
439.629 -> Yeah, this is inside this one.
444.77 -> Interface, postIdProps, and,
453.739 -> I have to switch to Windows
455.31 -> and Mac keyboard layout every day,
457.51 -> and sometimes I get confused.
462.25 -> So the PostProps,
467.181 -> so PostIdProps,
473.75 -> so why is not importing this one?
482.91 -> We'll say the props.
485.97 -> And now we want to return something here,
498.4 -> could be up here, you know, like,
502.63 -> paragraph, for the moment,
505.56 -> here's the post details, yeah.
516.37 -> No, not this.
520.4 -> Post details.
522.02 -> And here, I want to export default,
531.3 -> Detail here, so we
bring all of this stuff.
535.239 -> I want to open my console here.
544.73 -> Even running this one, dev,
557.04 -> Post 10, serializing, post.createdAt.
561.5 -> So we try to resolve this one.
566.64 -> Okay, for that, we already
installed it actually,
570.69 -> we have something called superjson here,
575.39 -> but we have to implement a
configuration file for that, so.
584.33 -> I have to create babelrc,
and in the babelrc,
590.09 -> if you have followed my
other tutorial about Next.js,
597.06 -> we have presets and in the presets we have
603.34 -> next/babel,
609.85 -> and we can have plugins,
and here we can have
619.078 -> superjson-next,
625.323 -> superjson, yeah, should be this one.
628.447 -> Now, because this is for
serializing everything,
634.41 -> especially JSON objects,
637.42 -> if it's going to detect this one,
645.795 -> you should try to reload this.
650.319 -> We're reloading or not?
655.64 -> Okay, the post, at least we are
able to fetch the data here,
664.69 -> JSON, yep, so this is the
id, and as you can see,
670.69 -> we have everything.
671.7 -> So createdAt, it's what
caused the errors actually.
681.16 -> This serialized buddy,
superjson object here.
684.37 -> Good, so we go on this.
690.24 -> Yeah, so we should continue this
694.99 -> to stop this and we can
continue implementing.
699.42 -> So do we have here, like,
post detail components yet?
705.57 -> I don't think so.
707.69 -> Do we have a post detail?
708.76 -> We don't have a post detail.
710.94 -> So this will be our biggest component,
720.036 -> PostDetail.tsx, yeah.
724.7 -> Okay, so what do we have
inside here of important?
728.71 -> Everything's important actually.
734.68 -> Start to write it.
736.179 -> Const, PostDetail.
742.81 -> What do we have here?
767.86 -> Just at least to see if
we can import it here.
775.84 -> Self-closing tag,
779.967 -> and expression, oh yeah, only one.
790.14 -> Just refresh for seeing if
everything, you know, correctly,
794.97 -> and again, okay, I'm gonna leave it open,
800.36 -> but maybe just it'll be toggled here.
806.49 -> And this Chrome Canary
doesn't work as well,
810.38 -> so try to reload every time.
814.49 -> This is the Canary
version, nightly updated.
819.34 -> PostDetail, okay, so the components.
823.8 -> Okay, so, I wanna have
some props, like, yeah.
830.73 -> And I wanna pass it here.
834.96 -> Yeah, postDetail will have this.
842.02 -> I will explain later why, I'm
gonna call it pst, not post,
846.05 -> but it is the post object
that we are receiving
848.73 -> from the underlying post.
854.03 -> Yeah, the dynamic component.
858.61 -> Only need the author, id,
and let's create this one,
868.537 -> PostDetailProps.
871.84 -> Well, this one is gonna have a
PostDetailProps in the types.
881.2 -> So export interface PostDetailProps,
890.017 -> and PostDetailProps
will have, yeah, the id.
898.844 -> pst of PostProps, and,
911.874 -> authorId number, let's import this one.
921.41 -> So pst, id, author as props,
924.33 -> and let's start writing
some interesting hooks.
928.83 -> So what do we have in here?
931.05 -> Yeah, we should be able
to use the same stuff
935.66 -> for the useEffect.
937.48 -> Okay, so first thing, the toast.
945.485 -> useToast, from Chakra.
950.31 -> Now we have the object of me.
958.549 -> useMe from the hooks.
962.83 -> We have, yeah, yeah, yeah, yeah, yeah.
969.38 -> This one you already know,
971.69 -> so I will copy and paste.
973.76 -> This comes from also
the index page, I think.
980.47 -> Profile, yeah, that's the same, our index.
985.12 -> Checking and listing of this one.
989.26 -> So we missed this hook here.
1001.792 -> setLoggedIn.
1008.58 -> useState.
1013.17 -> useState of false.
1016.9 -> Yeah.
1018.36 -> That's the thing, and let's save this one.
1027.282 -> Const color, useColorModeValue,
1032.27 -> this is one, I think, we
are gonna have maybe too.
1041.45 -> Gray 900.
1044.47 -> And let's start to
write some Chakra stuff.
1049.66 -> So the parent, div element,
1053.61 -> and what do we have?
1056.16 -> Basic stuffs like Flex, yeah.
1064.26 -> In the Flex, we have the align of center,
1068.01 -> we have a justify center.
1073.24 -> In the Flex, we have a stack.
1078.32 -> The stack will have a spacing of 8.
1084.248 -> mx, margin, horizontal, auto.
1091.84 -> We have a width of 1,200
and padding vertical.
1100.43 -> So y.
1104.05 -> Horizontal, Same stuff.
1108.83 -> We have a center, it's
kind of a different one,
1112.34 -> never used it.
1114.4 -> py of six, easy.
1119.3 -> We have a box and let's
write this box, okay.
1125.17 -> Oh guys, I mean, just allow
me some copy and paste.
1133.119 -> You can just, you know,
property is nothing to explain,
1136.32 -> and inside here,
1145.51 -> just to be more, you know,
1148.08 -> because we have done stuff, so.
1152.946 -> A text, you know, just basic text here,
1158.74 -> and a post.
1167.46 -> pst, of course, I'm not giving to this
1172.648 -> the id that he's expecting.
1176.57 -> So, in the props,
1178.82 -> he wants a pst of post, the entire object.
1186.84 -> The id, post id,
1191.84 -> and, authorId of post.authorId.
1200.91 -> I think this one is fair
enough, yeah, you know.
1206.89 -> Seriously, do we have, I don't think so.
1213.6 -> You know, at least we
have the text now here.
1216.84 -> Let's remain on this one.
1218.22 -> So the post under the post,
1222.83 -> yada, yada, yada.
1224.53 -> PostDetail.
1229.643 -> Okay, we have here one stack.
1234.74 -> So this is outside the stack.
1244.883 -> The author is imported from what?
1249.42 -> He's a, yeah, he's a Chakra UI component.
1253.61 -> Sometimes you can create a custom avatar.
1258.64 -> Let's import the truncate function,
1262.64 -> and let's import the moment.
1266.77 -> Okay, it's the time to fix these on save,
1269.42 -> actually, you know what?
1271 -> I forgot to put this
configuration in the devcontainer.
1275.87 -> So what is missing?
1278.94 -> The remote containers.
1281.34 -> So we have,
1286.36 -> so the editor called actions on save,
1290.45 -> and this is source.organizeImports,
1297 -> of true.
1298.88 -> And I also want to, in case
you have a lot of open files,
1303.84 -> workbench.editor,
1311.897 -> it should write it, this one.
1314.37 -> Title, scroll bar sizing, large.
1318.4 -> Save it.
1320.3 -> And we can stop this guy here,
1325.23 -> Rebuild container for taking
1327.65 -> the last configuration about this,
1329.057 -> I hope it's not going
to break everything up.
1337.45 -> It's taking the new
configuration, I hope so.
1342.07 -> So we have, now, if I save this one,
1349.74 -> maybe we should format document, oh,
1358.61 -> was doing something, format
document with, prettier.
1364.69 -> It's already saving this one,
1366.08 -> but it's weird because I'm the other one.
1371.05 -> But, as you can see, the
action was taken, so.
1377.62 -> Read more, and if I save here,
1381.3 -> but these are important.
1384.97 -> Yeah, you know what?
1385.86 -> Forget about this one.
1388.842 -> So we have the stack here and
why don't we separate this?
1394.52 -> Separate this one.
1398.01 -> And the other one before
the closing box here.
1408.099 -> This one for the moment,
1411.46 -> putting the comments.
1413.7 -> This LikeButton here.
1418.97 -> So here we have to check the likes,
1425.49 -> because maybe we have
a post with no likes.
1428.74 -> So yeah, that's the thing.
1433.73 -> Home here, this second post,
1438.34 -> or the other one.
1441.446 -> And yes, yes, yes.
1445.51 -> We have also the center here.
1450.36 -> Go on this post.
1451.79 -> And now actually here, we have to bring
1455.91 -> also a component for writing comments.
1461.51 -> And in case the user is not logged in,
1467.7 -> we want to avoid the writing,
having an input actually,
1474.38 -> but having the authentication form.
1477.76 -> So we have to write,
1480.03 -> we have to write this logic here.
1482.4 -> So the stack, we have the
stack, the box, the center,
1487.04 -> and the stack and the flex.
1489.37 -> So we basically closed
everything inside here, yeah.
1496.11 -> Coming from, but one, logged in, yeah.
1499.34 -> So actually here we start
writing different things.
1505.76 -> So we have another center.
1509.57 -> Height, 20 pixel.
1514.53 -> but maybe I want to remove this.
1519.1 -> And inside the center,
we have the divider.
1527.47 -> Did I import this one?
1529.86 -> Width, 80%.
1540.07 -> Orientation, please, please.
1546.81 -> horizontal.
1553.77 -> Orientation, horizontal.
1557.663 -> I can also use self-closing tag.
1565.51 -> Can I say this one, please?
1570.74 -> Yeah, he's here, okay.
1572.78 -> Here we have the color.
1574.43 -> Okay, post, likes, length.
1577.29 -> Didn't implement yet.
1579.12 -> We'll do it then.
1582.56 -> And we start the comment section.
1597.91 -> Unable to write after a day of coding.
1606.49 -> So what do we do?
1608.22 -> pst.comments.
1612.11 -> We map inside here.
1620.34 -> And now let's space this one.
1623.31 -> We open.
1625.82 -> We have the author,
1633.193 -> the text, createdAt,
1639.03 -> but this one needs props,
1641.8 -> so I think we should create also this one.
1647.6 -> And before doing this,
1651.94 -> I wanna pass index of number,
1657 -> so this one doesn't take,
1659.66 -> it's like he doesn't
understand that we want to open
1666.99 -> the arrow function, right?
1670.35 -> And at the end,
1674.05 -> always being confused by as this stuff.
1677.53 -> Always, every time.
1682.27 -> SO even if I close this one,
1688.104 -> pst.comments.map, author,
createdAt, I close this one.
1694.43 -> This one is closed.
1696.39 -> This is my number.
1704.01 -> And here, so now I have
1711.114 -> the CommentProps.
1718.363 -> There's one, types,
1723.36 -> exports, CommentProps.
1730.49 -> This is an interface.
1732.32 -> What exactly does it have?
1737.286 -> What the heck?
1738.2 -> Am I dumb or what?
1740.11 -> This already exists.
1742.35 -> Don't need to write a new one.
1747.511 -> CommentProps, man.
1756.84 -> What is he saying?
1758.91 -> Expression expected, yeah, okay.
1760.767 -> You should wait maybe for that, yeah.
1764.21 -> Okay, okay.
1765.68 -> I can maybe bring everything here,
1768.08 -> because there is no need
to understand anything.
1774.49 -> The blog author, the blog author.
1776.413 -> This is a component that
belongs exactly to...
1783.38 -> Okay, the blog author is something
1787.21 -> that I have seen basically,
I want to separate this,
1791.96 -> maybe put it outside here.
1797.72 -> Taking a few images, random images.
1804.69 -> Image, where does it come from?
1806.86 -> I'm not remembering if it comes from Next
1808.98 -> or it's from Chakra also.
1812.74 -> Be careful about the import.
1817.48 -> You know, just component, sticking image.
1823.72 -> Extra space here.
1827.44 -> Yeah, for being more concise,
1832.02 -> let's put also the interface inside here.
1842.9 -> That way we have only one
corner with all of the props,
1850.69 -> and in the comment, basically
we will have it here.
1855.45 -> Comments, with this
blog author props here.
1861.93 -> You post comments and comments, yeah.
1867.47 -> Because we don't have any comments,
1869.09 -> that's why they don't have anything.
1891.478 -> Oh, this one, this is really,
1893.517 -> really from copy and paste
stuff and don't need it.
1899.26 -> So we will render these when
we will have comments here.
1936.806 -> Okay, so before the center,
1943.51 -> here, we want to check
if he's logged in or not.
1954.28 -> We render the AuthForm.
1960.02 -> Otherwise, we can render a comment form
1963.36 -> that we are going to create.
1970.78 -> My chair, I think, is getting low
1972.87 -> because I am destructing this chair.
1976.07 -> Okay, so let's create our CommentForm.tsx,
1986.821 -> CommentForm.
1988.83 -> Well, this guy as here.
1997.86 -> You suggest me already a name?
1999.33 -> This kind of wizard.
2014.1 -> Comment form.
2020.548 -> Export CommentForm.
2023.54 -> Comment form, comment form.
2028.48 -> So since we are logged in,
we don't have the AuthForm.
2033.64 -> We have did comment form, ugly, but yeah.
2041.08 -> You know, we are not logged in.
2044.62 -> From here, we can also logged in, can we?
2050.59 -> Because we have everything we need.
2060.383 -> And we entered the comment form.
2061.89 -> So we actually have to complete this.
2065.49 -> The comment form will receive
a prop, yeah, the id at least,
2073.18 -> as an object, and yeah.
2077.4 -> What are we going to do with the id?
2080.73 -> Nothing, I don't know.
2083.15 -> And how do we pass?
2087.596 -> This is our dear pst.id, right?
2097.87 -> pst as posts.
2100.74 -> Yeah, it comes from here.
2105.5 -> And the comment form, comment form,
2109.5 -> 'cause we want to try
to add some comments.
2115.33 -> So hooks, text, not test,
2122.504 -> setText.
2126.153 -> useState of empty string.
2139.49 -> I import the router and let's see
2142.67 -> what we are going to do with this.
2148.677 -> Here's a router, from what?
2150.64 -> Next router, yeah.
2157.134 -> The object of me, querying from the hooks,
2165.504 -> useMe and our dear toast.
2170.41 -> Our friend, toast.
2177.44 -> What the heck am I writing?
2180.46 -> Beautiful.
2185.58 -> Okay, let's try.
2189.21 -> I mean, let's start to import
2195.56 -> Flex and everything we
need from Chakra UI.
2204.75 -> I just want to start at
least to writing, you know,
2207.51 -> step-by-step then I will try to, oh, yeah.
2212.286 -> Oh yeah, oh yeah.
2213.93 -> This is also useful.
2221.47 -> useColorModeValue, this will have a white
2226.65 -> and gray 700, not 7,000.
2236.59 -> That way we can use the stack here.
2244.51 -> So I copy and paste.
2247.48 -> I import.
2249.287 -> This is opened.
2254.186 -> useColorModeValue, I want to
replace this with a color.