NextJS ChakraUI Prisma Social Dashboard | Episode 8

NextJS ChakraUI Prisma Social Dashboard | Episode 8


NextJS ChakraUI Prisma Social Dashboard | Episode 8

NextJS ChakraUI Prisma Social Dashboard | Episode 8
Hey! In this episode we implement the Like Button Component \u0026 his route for each post and we implement Prisma on routes/api as well. We also implement comments component / api.

Enjoy!

#prisma #nextjs #devcontainer

Environment: TypeScript, Prisma, NextJS, PostgreSQL, VSCode remote container, ChakraUI, ARM64, Node16

Closed captions sponsored by Prisma. Get yours for free here: https://pris.ly/closedcaptions

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…  
Episode 7:    • NextJS ChakraUI Prisma Social Dashboa…  

Timeline:
00:00 intro
01:30 Like Button
09:00 like api
28:00 fix refresh after liked


Content

0.7 -> - [Instructor] All right, guys, let's continue
2.66 -> with another episode.
4.82 -> And today we want to start implementing like functions
11.77 -> on our post.
13.48 -> So, we have up until now the post
17.98 -> and on the the post the main one,
20.17 -> we have implemented read more that goes in the pages.
23.95 -> In the post dynamic ID.
26.62 -> So we can log in, everything works.
31.23 -> We have rendered it, this form also
34.34 -> on the detail of a post in case we are not logged in,
39.26 -> we don't want to render
41.15 -> and give the chance the user to comment.
45.32 -> It should sign up or sign in
49.03 -> and it can comment it up again.
52.44 -> And yooo, this is John.
58.28 -> Is John or not?
60.82 -> Okay, let's start, go back on the,
65.13 -> this one will be implemented then,
68.752 -> I want to implement the like button,
71.68 -> just want to make the set screen a little bit bigger.
77.06 -> So read more, when the post and now,
81.85 -> we have here the like button.
85.61 -> Like button is a component that we don't have yet.
91.48 -> Let's create it.
98.889 -> So, I don't need it anymore, like button, sorry.
101.35 -> Maybe you hear noise now
103.59 -> because I touched my microphone.
107.05 -> Const LikeButton in line, it arrow function of, yeah,
116.49 -> working on windows entire morning,
121.16 -> return,
132.64 -> I want to pass something.
136.95 -> This will be ID, author ID
141.67 -> and we have something, child to parent.
148.16 -> Do we need it now or?
152.28 -> Not now, we will implement this later
156.924 -> because we have to go step by step
160.876 -> and let's declare props,
166.83 -> like button props.
168.67 -> Let's open in types, yeah,
177.58 -> export interface,
185.24 -> like button props.
187.17 -> What does this one have?
190.81 -> Yeah, da, da, da, ID, author ID,
194.281 -> the author ID, yeah.
198.9 -> Number for the moment, we'll see then what do we more,
211.21 -> button props, like button props, yeah.
214.87 -> This is okay.
215.703 -> We want to return a tool tip
223.46 -> and the tool tip I think as, yeah,
228.64 -> as I thought the, not the place content,
237.953 -> should we write for, placement, yeah.
244.65 -> Sees left, has arrow, the label.
255.02 -> Where do we have label?
257 -> Do we have something?
259.83 -> I think is in the utils constant, yeah.
267.866 -> LIKE_BUTTON_TEXT and this will have, yeah.
280.49 -> Smash the like button.
286.48 -> Okay.
290.575 -> Wait, like button text, yeah.
295.173 -> You should import it.
296.969 -> and the background will be green.600.
303.61 -> And in the tool tip, let's import an icon button.
310.92 -> Self-closing tag, yeah.
314.56 -> Self-closing tag, one weekend.
319.17 -> The icon button is from chat aria rock, yeah.
322.68 -> That's right.
325.69 -> And this will have the onClick, then,
330.94 -> just, right, the aria label, like button
340.628 -> and the icon, we can assign an icon.
345.36 -> All right.
350.17 -> Yeah.
352.31 -> Hi outline thumb up.
360.15 -> But, this as a component, yeah.
371.68 -> The like button, can we just maybe import of course,
381.74 -> like button,
391.513 -> I don't think I exported.
399.255 -> So we can,
407.647 -> like button and like button will have,
411.66 -> so we have to pass the ID
415.772 -> and this will receive the ID and author ID.
425.55 -> Author ID.
429.44 -> That's, we are here like button, yeah.
433.15 -> That's right.
434.5 -> So we have the like button.
436.66 -> We should implement, read comment button.
446.21 -> Yeah, comment button.
447.383 -> This will end, this one later.
451.94 -> Okay.
452.773 -> The like button,
453.64 -> we only have to create a function
460.44 -> on onclick,
463.89 -> async
467.72 -> in line our function
470.83 -> and create destructure, success and error.
478.5 -> And then we will see how we can implement the success later.
487.33 -> Fetcher, so we need to create this API, like,
495.41 -> create and pass the ID and the author ID.
504.75 -> And now we can use the mutate for fetching on this route.
517.62 -> Mutate, success, error.
524.96 -> Okay.
526.03 -> We have to create the API, like, create, pages, API.
535.78 -> Yeah, pages, API, like,
541.467 -> So, API create a folder, like the secondary comment
548.007 -> and create data script
558.18 -> and export default async function,
569.4 -> handler request
570.64 -> of the next API request.
581.93 -> Next API response.
586.5 -> And again, we need the token from request.cookies.
594.92 -> We need the ID and the author ID.
603.37 -> Always has a destructured object,
608.827 -> we retrieved this from request.body.
614.12 -> This is empty space from yes code check.
618.29 -> Let's declare, let like, author ID here.
628.22 -> Now we can open the try catch block.
631.87 -> Okay, we have the first, we have the first main,
636.46 -> if to check.
639.48 -> So if token,
643.46 -> we get the authenticated user
664.16 -> from his email of type, any.
670.94 -> Let's import to jwt
679.07 -> from jsonwebtoken.
681.04 -> So jwt, this is always the same stuff.
685.84 -> We have wrote several times yet.
687.98 -> So, give me,
695.12 -> this is where Prisma comes to action,
701.03 -> user.findunique
716.08 -> where email, it's a space a little bit, this one.
722.886 -> And now, what is interesting in this like
728.05 -> is that we can also find all likes for this post
735.477 -> and you will see why.
740.27 -> Let's save this,
742.04 -> let's set them in a variable.
746.216 -> Const all likes and this is wait,
753.84 -> Prisma.like.findmany
766.68 -> where, do we have, oh, I think I have to open an object.
776.469 -> The post ID, what exactly is the ID coming from here?
784.88 -> That's one thing.
786.949 -> And now we map,
794.22 -> we map through it and,
808.21 -> we map through it and we assign the like author ID
818.89 -> to our variable.
823.43 -> So all likes map, just allocate
835.38 -> like author ID equal, equal lk.authorID.
844.98 -> Now, if me.id equal author ID,
855.22 -> we're gonna respond with something.
862.23 -> Want to avoid that the logged user likes his own post.
865.95 -> This is why all of this check.
867.77 -> So, we return a response status
870.72 -> and with a JSON object error,
873.4 -> you cannot like a post you created.
878.56 -> Okay.
879.393 -> Another thing, if the like author ID
885.127 -> is equal to me.ID,
897.23 -> we check that the logged user ID is the same as the author
900.92 -> for this post like,
901.813 -> I can avoid that he likes the post twice.
905.69 -> And again, we return the status of 400.
908.19 -> You cannot like a post twice.
910.15 -> So these are two different error objects.
914.47 -> Okay.
915.303 -> And now we can construct our like objects.
921.14 -> So we have the await prisma.like.create
934.787 -> in the create we have some data
941.44 -> and we have the author.
946 -> And as we did the last time we connect the email.
959.44 -> Author, yeah.
964.48 -> Post, yeah, the post.
968.636 -> We connect the ID.
980.83 -> After that, what do we do?
984.53 -> This is the else block
986.64 -> so, just close it
988.42 -> and respond at status 200,
994.33 -> that's okay.
996.26 -> With a JSON liked with success.
1012.43 -> Could have done this in all
1013.43 -> of the response, basically, yeah.
1015.38 -> It's up to you have fun doing this.
1018.56 -> Maybe we refactor responses.
1025.73 -> No console error, just an object as error.
1032.16 -> You must be logged in to like.
1044.49 -> Can we use this one for, yeah, of course.
1050.87 -> For the error block,
1055.18 -> we want to return, right.
1057.97 -> We return catch error, you must be logged in.
1061.59 -> I'm just checking if, 'cause I'm tired.
1064.21 -> So, well too much code today.
1068.087 -> And, didn't plan to do, after a strong day,
1071 -> a tough day of coding other tutorials.
1074.22 -> But I wanna make this soon and fast and finished this one.
1081.651 -> So, yeah, like button as his own API route,
1089.03 -> API like create API like, create.
1094.28 -> And the API is okay, the like button is okay.
1099.583 -> So we should be able to at least like,
1106.61 -> and fetch data.
1108.59 -> So, okay, on the same route.
1112.61 -> we are liking and John Doe.
1117.42 -> So John Doe has created this post
1122.007 -> and as you can see, we cannot like it.
1125.84 -> We have the error here.
1128.35 -> But now we should have also this error
1130.3 -> because we have already, I was mad he like, okay.
1135.58 -> How did I write inside it?
1139.73 -> Smash the like button.
1144.99 -> And yeah, we should have also the same error
1151.44 -> because we already liked it.
1157.26 -> You cannot like a post twice.
1159.79 -> This one should be different.
1165.57 -> You cannot like a post you created, so our errors work nice.
1170.86 -> And we just have to create a pop ups to throw them
1177.91 -> and display to the user.
1185.07 -> Okay, for doing that,
1186.24 -> we should create maybe something
1189.11 -> in this like button that allows us to throw the error here.
1194.45 -> This is the children
1196.395 -> (clears throat)
1198.26 -> that we are using here in the post.
1201.09 -> So, we should maybe have
1205.22 -> to get something from this children component
1210.299 -> that allows us to know that we are throwing
1214.04 -> and send to parent the error.
1217.96 -> So, I want to declare another property here,
1223.65 -> child to parent and we have
1226.54 -> to declare maybe here in the props
1231.12 -> and this one will be child to parent
1241.55 -> with a property of success.
1245.97 -> And this will be a Boolean
1248.49 -> but then then type, any child to parent.
1255 -> Don't make it optional.
1256.47 -> So we have the child to parent declared here,
1259.966 -> and we have to use it here.
1264.97 -> Child to parent success, true
1273.09 -> otherwise we throw the error.
1277.77 -> Now we can use it like here,
1281.67 -> child to parent and our child to parent can call it.
1292.58 -> We are gonna use the handle.
1297.19 -> The handle click function that we want to create.
1300.6 -> And we use the use callback hook.
1305.653 -> So, let's do this, const handle click.
1318.76 -> Use the callback from react
1322.89 -> and the callback, we will receive the error
1331.33 -> from child open arrow function, just parenthesis
1339.38 -> and let's create a variable.
1343.69 -> Our first is, save in a variable called isError
1353.39 -> as a string for telling if the type
1361.52 -> of error from child equal to a string.
1369.25 -> So will a boolean variable.
1376.61 -> likedSuccess equals liked with success.
1387.25 -> We can also actually save it
1389.97 -> in our variables where we have all of the constants,
1393.31 -> but for the moment to let's save it here.
1398.87 -> What is it saying?
1400.98 -> And yeah, I want to use the toast here, toast
1411.26 -> So the toast will have the position,
1415.57 -> useCallback is throwing me an error, I don't know why.
1424.26 -> Actually, it was right,
1425.093 -> this was not what I thought, this is...
1440.587 -> A lot better
1443.85 -> And, and, and, and, yeah, we have the,
1449.92 -> declare now here.
1456.192 -> There was a string,
1458.93 -> so, the position and the title is,
1462.16 -> if the error is a string warning
1464.16 -> or success in description, we check always from this
1469.64 -> or liked success
1472.11 -> because we can also have the success situations.
1479.5 -> So, we're gonna throw the something green
1485.085 -> in the description and the status warning of success.
1489.6 -> So let's see this in action,
1492.5 -> we have called it here.
1496.01 -> So now, if I refresh the page,
1500.94 -> you cannot like a post twice.
1503.45 -> So we can throw the error to the user.
1509.01 -> This will have, you cannot like a post you created,
1512.92 -> but let's create the third post and let's like it.
1522.04 -> You cannot like a post you created, it's right.
1525.87 -> Now, we log as a Jane Dane,
1534.2 -> we log in and we like the post of John Doe
1537.57 -> Just make it disappear, the first one.
1541.6 -> Right, so liked with success, our function works well.
1547.44 -> So we will work for our errors
1549.45 -> and for the success situation here.
1556.02 -> And I think we can also implement the like button here
1562.17 -> on the post, we have to go out.
1567.26 -> Inside here I don't think we have, no post detail.
1571.76 -> So the post detail and let's see what we can do here quickly
1578.641 -> for having exactly what, okay, so, this is the same,
1585.76 -> so, I can maybe copy and paste since
1593.11 -> after useEffect, yeah.
1596.071 -> So, useCallback, we import it.
1602.29 -> This is the same error,
1604.75 -> I want to rename it as string.
1612.23 -> This is the same.
1613.063 -> And do we have a like button here?
1617.79 -> And this is the same.
1619.66 -> Okay.
1620.493 -> Yeah.
1621.631 -> It's comment out, so like button, it's the same component.
1628.5 -> So we can use all of these properties,
1632.01 -> the props that we pass,
1633.83 -> we have it that's why before we didn't use them.
1640.3 -> Now we used it.
1642.01 -> So I think that on our post detail, we can,
1647.15 -> John Doe, we are logged as, okay.
1649.92 -> We are logged as a Jane Dane.
1651.23 -> So now let's go on the John Doe but don't like
1653.98 -> from the main head index, let's like it from here,
1662.71 -> liked it with success.
1665.43 -> But what we can do now after this one,
1670.62 -> I think we have to maybe adapt the counter or something.
1678.16 -> Or the, we have to fix the route
1680.01 -> because now, you can not like a post twice,
1683.27 -> but as you can see,
1685.139 -> we didn't refresh anything.
1688.9 -> So, let's see what we have.
1697.62 -> Okay.
1698.453 -> We need something to make this work.
1702 -> So let's create.
1706.55 -> Okay, you know what?
1707.383 -> Let's delete everything.
1712.58 -> Recreate a post as a John Doe, second post
1720.45 -> And I want to like it on, I want to log in as a Jane Dane.
1731.62 -> Now, I want to go on the John Doe post,
1733.73 -> logged in as a Jane Dane
1735.09 -> and be able to like it and refresh the page.
1738.66 -> So we need something here after the toast maybe,
1745.5 -> we have to useRouter somewhere here.
1750.09 -> Let's call it here.
1757.75 -> useRouter, this is from next, right.
1761.11 -> useRouter, useRouter, is from next router, yeah.
1771.22 -> Then just after the toast,
1774.09 -> when we open the toast router here,
1780.64 -> we want to push on the route.
1785.92 -> Yeah, I think we can use back ticks,
1788.52 -> 'cause should be a dynamic post.
1793.91 -> And now the $ ID, can pass it also
1803.186 -> as an option and post ID.
1807.52 -> Don't worry about the warning here.
1813.38 -> So whatever we like on the same route here, like this post,
1820.76 -> we are able to refresh the page.
1823.21 -> So this is what we wanted.
1825.87 -> Now, I tried again,
1827.22 -> and we should throw the error
1831.44 -> because we cannot like a post twice.
1835.03 -> So this is fixed.
1838.2 -> Now on the post, always on the post,
1841.7 -> we want to start implementing the comment button here.
1846.96 -> I don't think we have it.
1849.33 -> Comment button, comment button, we don't have,
1852.74 -> we have a comment form, but a common button,
1855.41 -> because we wanna call it the combutton
1858.7 -> because we will have just a comment button here, basically.
1865.24 -> So CommentButton.tsx and, yeah,
1873.63 -> this is oh, comment, yeah, const.
1881.3 -> This is not common form, this is the common button,
1885.92 -> picked the wrong one.
1888.62 -> All right, you know what?
1889.71 -> This is very simple, copy and paste.
1892.35 -> Just being a little bit faster.
1896.69 -> The common button props, do we have it?
1899.38 -> Yeah, we do, pretty, pretty.
1906.83 -> So on the types,
1912.42 -> Common button props import it,
1916.24 -> common button props, we paste.
1919.728 -> I don't remember if the link is from, next link, yeah.
1926.64 -> Post ID, the icon button from ChakraUI
1929.86 -> and the HiOutlineChatAlt2.
1933.109 -> This is the icon, you can play with them.
1936.8 -> Post ID, we are ready, update
1940.495 -> and the common button here we can use in our post,
1947.73 -> right where we have commented
1950.23 -> and the common button that's imported
1953.46 -> So, the only job that this comment button has to do
1958.03 -> is to redirect also,
1962.2 -> and we have also the counter here.
1964.97 -> You should redirect and have the sent function
1969.608 -> as the read more button.
1970.68 -> So read more button brings us to the detail of each post.
1975.08 -> Same for it, you know, same for it.
1982.81 -> Home, comment
1990.738 -> Throw a comment man.
1995.33 -> Comment is one.
1997.11 -> You can all like a post twice.
2001.24 -> So, this guy redirects us to, let's delete this one.
2011.67 -> Things seems to work, no errors,
2013.64 -> except for the errors that comes
2015.11 -> from the backend, API routes.
2020 -> This will be, who created it, okay.
2023.6 -> Jane's second post, submit this and, detail
2035.77 -> Yeah, we can a like a post we created,
2042.15 -> John Doe maybe is the guy.
2049.43 -> We can like it, we can comment, comment here,
2055.188 -> I don't know what to write.
2057.44 -> And we can post this one
2062.45 -> on the post detail maybe it's something to show you.
2068.43 -> Yeah, blog author,
2074.83 -> what I wanted to show you is that an option
2077.03 -> that I just want to maybe write the component.
2084.51 -> You decide if you wanna use testimonial card,
2088.871 -> is another component that I found
2090.7 -> on the chakra-templates.dev testimonial card.
2096.01 -> So, pick up and paste everything from here
2103.5 -> and you will see if you want to use it or not,
2106.33 -> then you, you will see the difference.
2110.08 -> So, just after the post,
2115.14 -> when we map in our post map here,
2121.07 -> we can use this one or decide to comment out
2126.854 -> and let's import this one,
2130.33 -> I hope it's gonna work.
2131.42 -> This just, you know, this is cool.
2136.41 -> We have to adapt maybe the font
2138.1 -> but it seems cool, right.
2142.4 -> Where do we have another one for any kind of reason?
2149.32 -> I don't know why we have QV,
2152.76 -> but we should maybe have just one
2155.45 -> but this is just the font implemented
2159.43 -> because I had heard coded two comments
2162.2 -> but it's up to you,
2163.36 -> if you wanna use this kind of a UI for comments,
2167.11 -> you can use it,
2167.99 -> otherwise, you use this.
2177.88 -> And yeah, this is,
2180.29 -> I think this is all guys with eight episodes,
2183.56 -> we have covered,
2186.33 -> we have covered everything and we can commit this stuff.
2190.45 -> So, what we can do, what we can do here,
2196.75 -> maybe throw a few more tests.
2199.88 -> Yeah, basically, basically everything works.
2203.16 -> So we are not logged in.
2204.54 -> We can also,
2206.45 -> okay, you must be logged in to like,
2209.4 -> commenting, we can basically go on the route,
2215.7 -> for throwing comment, we have to be signed up.
2219.73 -> So, everything seems to work.
2224.11 -> I hope you guys appreciated this tutorial.
2227.09 -> And these are long episode, of course,
2231.41 -> but I prefer separate, a little bit in each episodes.
2236.82 -> And don't throw, as I said,
2239.29 -> in the intro videos tutorials
2241.48 -> for as say, five hours tutorial, 10 hours.
2245.24 -> But yeah, I think it was a great one.
2249.14 -> And we covered a few stuff from Prisma,
2253.17 -> we created different API routes.
2257.33 -> And if you have any questions,
2258.69 -> you can throw a comment
2260.09 -> in the section below the link of the video.
2265.02 -> So thanks to Prisma for providing the closed captions.
2272.85 -> And as I said, at the beginning of the video,
2275.05 -> don't forget to apply for
2277.242 -> for being the ambassador Prisma ambassador
2281.077 -> and you will get the chance to learn a lot
2285.29 -> from the community of Prisma
2287.52 -> and join, like the community as well.
2290.23 -> So guys, again, thank you for supporting me
2293.53 -> and watching this entire tutorial
2296.55 -> and I'll see you in the future in next Prisma tutorials
2300.21 -> and other stuff around code, bye.

Source: https://www.youtube.com/watch?v=l6HokesGy68