Creating XPoster use TRPC, Next.js and ChakraUI - Settings Page

Creating XPoster use TRPC, Next.js and ChakraUI - Settings Page


Creating XPoster use TRPC, Next.js and ChakraUI - Settings Page

This was originally a two-hour Livestream that was edited down to show you how it works and what we are doing.

Don’t miss the next one:

https://twitch.tv/jamesperkins

OR RIGHT HERE!

Join this channel to get access to perks:
   / @james-perkins  

Follow me on:
📃 Website/Blog: https://jamesperkins.dev
👉 Twitter: https://twitter.com/james_r_perkins
👉 Linkedin: https://www.linkedin.com/in/james-per
👉 Github: https://github.com/perkinsjr
👉 Discord: https://discord.gg/dqYP9Mc
👉 Twitch: https://twitch.tv/jamesperkins


Content

0 -> Hey everyone. This was originally live streamed, but it's been edited down into
3.092 -> a nice compressed version of the video. In this video you'll see
6.532 -> me create a settings page using TrpC, Clark,
9.722 -> Next, JS and Chakraui. By the end, I have a working
13.7 -> version. Hope you enjoy it. I'll see you in the next one. Hi, it's me
18.05 -> friend SHBoy. We're live streaming, we're doing things,
21.716 -> we're rebuilding things. This live stream is going to be me be
26.01 -> probably rebuilding a single page with TrpC,
29.858 -> NextJS and some other stuff. I already have some code that's
34.178 -> been written before. So we'll show that and I'll explain how that
37.484 -> code works now and then what we need to add to our TrpC
41.622 -> stuff. Okay, so here is the app
45.152 -> layout right now it may look fairly familiar.
48.91 -> We have a Prism schema, we have a source file that contains
53.29 -> all sorts of goodies and it has Next, yes,
56.452 -> TLPC. And it has Clark already configured.
59.97 -> So Clerk is in a couple of different spots here.
64.15 -> First in the pages we have sign in and sign up. And these just
67.912 -> hold a sign in and
71.336 -> a sign up page. And then we also have this user
75.118 -> profile page which holds just the user profile in general.
79.324 -> So if someone wants to update something on their user profile, they can do it.
83.93 -> And that's about it for at least
87.356 -> UI components. And then we have this
91.772 -> user web hook, which I just literally finished yesterday.
96.67 -> And what this does is it looks for two events. One is
100.32 -> the create event and one is the updated event. And this
103.972 -> comes from Clerk. Essentially what we're doing here is just either
107.7 -> inserting into the database either the name
111.396 -> of the email or if they've never been create
115.172 -> before, create a user ID and then
119.012 -> a name and an email which we can then associate with other parts in our
122.088 -> database when we get to those. James and then if it's not one of those,
125.192 -> we just reject it. But yeah, so this is just for a bit of
128.796 -> a user sync back that isn't really required and I could
132.476 -> just use something like front end metadata to link
136.124 -> Superbase and Clark together.
139.292 -> But I just wanted to make sure that we could use
143.116 -> web hooks here and that they function the way I expect them to.
147.39 -> So we have that and then we have a standard TrpC setup,
151.03 -> which would probably better if I actually looked at the server.
154.61 -> So we have context here, which is actually run against
158.9 -> Clerk's users with this piece of code here,
162.356 -> which then returns the user in full.
166.31 -> And then we have our TrpC
169.518 -> middleware that just checks to see if they're off. If they're
172.958 -> authed, great. If they're not, that's fine as well.
177.21 -> So we have options here to make sure that
181.02 -> the user in general can do what we expect.
184.65 -> So now we have that, we can talk about the
188.348 -> DBE, which we're using Prisma, but we're actually used superbased
191.538 -> in I guess a nontraditional sense. So I'm using TrpC with
195.088 -> no front end code for it. So I have RLS
198.678 -> turned on with no way for anyone to
202.352 -> actually make a request to the database without the database password
206.77 -> or the server token that comes along with it. So we have three
210.692 -> models here, we have a user model, we have a settings
214.718 -> model and a subscription model. Now this is based upon
218.846 -> older code which you can see here.
224.15 -> So this is the original microsess that's still good
228.796 -> today and it's still making me money. So that's good here's.
232.242 -> Application settings. It just has this user profile
236.098 -> at top and then it has a bunch of API keys and if you want
239.632 -> an RSS feed and then you can manage
242.896 -> your subscription by clicking this button. And then
246.352 -> this is powered with charge b right
250.016 -> now, but we're going to change that because I can now
253.652 -> use something else. And that's
257.242 -> basically the settings page. And then basically the idea here
261.828 -> is that you go to this page and you upload
265.262 -> a markdown, for example, like this one and
271.03 -> that translates into HTML here. And this is what the
274.568 -> whole blog post looks like from start to finish. And then we
278.636 -> can export this out to your favorite provider by clicking this button
282.684 -> and choosing whichever one you want, spitting a blog post title
287.234 -> and you're good to go. And then that will cross post that content
291.63 -> to another provider so that you can write it on your own,
295.744 -> own the publication, but also share a bunch of other places,
299.414 -> super useful for that kind of stuff. And yeah,
302.448 -> it's still making me money but I feel at the moment that
306.404 -> it just looks like shit and it's using some really janky code in
310.164 -> the back. So I thought why not just rebuild
314.05 -> what we have already created. Plus it gives me
317.608 -> an excuse to write a lot of code and it gives me an excuse to
321.128 -> write a lot of TrpC code. Yeah,
324.568 -> let's talk about the code that we need to implement because some
328.444 -> of this has actually changed. Right? So this
332.348 -> is the page we want to do. We just have this add accounts that upgrades
336.034 -> your integrations and then based upon that pulls in data
339.948 -> based upon X or Y. And if there was
343.312 -> data here, show you there's a lot of jank in here. First thing
346.672 -> we want to do is go to our settings page right now, which has nothing,
350.83 -> and we want to be able to get the users data from the
354.228 -> database using TrpC and the user ID because those are the
357.604 -> only two things we need to make this work,
361.508 -> I think. So if we look at a
366.728 -> router, I created one, and we have a mutation
370.718 -> here that doesn't actually do anything right now, and it doesn't actually but we
374.392 -> do have this protected route right here that
378.172 -> we could just return something, which would just be
382.25 -> settings. And then we just need to do
386.41 -> something with the context, which means we would need to
391.63 -> pull in our prisma.
396.03 -> Maybe that's not what I called it. It is what I called it.
400.61 -> And say data
406.85 -> select oh, wait,
409.94 -> am I writing the right code here?
412.37 -> Nope. I'm thinking find
416.52 -> unique where
420.87 -> the user ID is.
424.872 -> Context user ID.
428.49 -> Yeah. And then
433.77 -> we just need to select this.
439.39 -> What are you complaining about? Why would these be
443.63 -> oh, that's right. I think I check and admit this
447.024 -> for now. It's been so long since I've used Prisma
451.002 -> and we can get rid of this right now. Probably this.
456.21 -> I wrote this very quickly before we what
460.788 -> did I miss here? Let's see.
464.63 -> Oh, it might just be okay,
467.75 -> so I just need to return settings
470.958 -> and then just this data and
475.148 -> then this. All right,
479.69 -> and then you probably want this to be there.
484.268 -> Okay, so now we should be able to go
488.256 -> to our settings page and say TrpC
494.19 -> oop, forgot to put it in my import.
500.13 -> And we'll call this Settings and we'll set
503.972 -> this to setting routes. And that's
508.938 -> poor naming convention, isn't it? Let's see what comes out first
514.47 -> and then I'll go back and fix it after
518.296 -> the fact. Let's just do that.
521.59 -> This should come back as null. It shouldn't come back as anything.
524.84 -> There shouldn't be any settings for this user right now,
527.93 -> which is fine, that's what we want. So there's two stages
531.25 -> to creation there is nothing and then there is something and
535.292 -> based upon whether our users put anything in will
539.36 -> allow us to do something. But I want to see if we get an error
542.118 -> first. Okay, so if
545.808 -> I go to settings we should
549.312 -> get blank page and we get a query.
553.73 -> So that's good. So now we should just
558.69 -> update mine with some arbitrary settings.
562.314 -> So now we can take this button and we can add in to our settings.
565.934 -> Here a mutation. So we should call this Get
570.31 -> Settings and then we'll
574.654 -> create one called Update Settings
578.81 -> which is also a protective procedure, but it's a mutation.
583.61 -> It'll also be asynchronous and
587.068 -> we'll need context and we'll need input.
590.91 -> And we'll put an input here and
594.272 -> then we'll do const. Obviously we need
597.808 -> to go and actually do something with this because right now it doesn't
601.434 -> do a lot, but we can do const. Update equals
605.53 -> awaits prisma saying update
610.21 -> or Upset because we know
613.8 -> for a fact that this user potentially
618.174 -> could not have anything in their database.
621.982 -> Right? So we have two pieces.
625.246 -> When the user first looks in for the first time, they don't have any settings
629.346 -> because they haven't put any of their data in. Then on
633.628 -> secondary requests, we could just use upset
637.122 -> here to verify whether or not they have it and then if they do,
640.32 -> we can insert it. So what we need to do here is we'll
644.182 -> do create and we'll put
647.584 -> dev two. We'll just put hello dev
652.052 -> two because there's more in here. There's like hashing
656.698 -> and all sorts in here that I have to do.
661.49 -> But this will just get a good baseline
664.75 -> that the database works and then we can go back and do other
668.472 -> stuff to it. User ID will be context
672.174 -> user ID and
677.852 -> then we need where
682.22 -> clause where user ID
686.044 -> equals context user ID
690.75 -> and then finally we need update
695.71 -> where something.
699.47 -> For now we'll just put dev two as updated
703.65 -> and we can hit save and then we can
707.588 -> see where we're at here and we can just return for
712.388 -> now. Great. And then we
716.632 -> need to close out this.
720.104 -> There we go. All right, so now we have everything, right? So here basically
723.336 -> the idea here is we're going to update we could just actually just return
727 -> this for now where the user ID equals context
730.706 -> user ID. If they don't have it, we'll just add all of this data in
734.732 -> and then we'll update this. I have a feeling that I may
738.128 -> have fucked up prisma somewhere along
742.032 -> the lines of how everything's connected. So we
745.328 -> may need to do something like user
750.43 -> connect user ID,
753.39 -> context user ID.
758.11 -> I think that's what I'm supposed to do, but I can never remember. Anyway,
761.476 -> we'll leave it in there for now and then what we can do is go
765.288 -> back to our settings and say Tatian
769.39 -> equals TRPCS
775.13 -> mutation. That's not how that works,
778.892 -> is it? Update saying start use
782.956 -> mutation. Feel like I fucked something
786.636 -> up and now I can't remember what I did
791.87 -> even though I've written TrpC code a thousand James.
797.07 -> Let me look at this screen.
803.01 -> That'd be what I'm doing and
806.932 -> then that's what I want to do.
809.892 -> Okay, let's just mutate not mutation
813.758 -> event you're really helpful vs code.
816.87 -> Just trust me, bro. I wonder if
820.408 -> I just move this to here.
823.19 -> Oh wait, I'm so stuck. I am on fire today.
827.532 -> Oh yeah, I've had a good day at work.
830.65 -> That's a ten in my book.
834.57 -> Damn it. But for now we can just delete this
837.708 -> back out. Do console log
842.25 -> and let's finish this out. Are there any variables?
845.702 -> I don't think there are. Are they? Let's look.
848.99 -> I have an input here, but technically there is no
852.612 -> input. Guess I could
855.988 -> just do that burnout and we'll just do
860.61 -> handle click and then we can
863.828 -> actually see here is where
868.712 -> it tried to commit something. Let's see.
872.87 -> Super Bass, the app
876.636 -> that signs me out 600 times a day.
880.01 -> Hey oop troll.
884.97 -> Okay, so we have everything,
890.03 -> although I have no active on here.
893.76 -> But if we go here and we should see a
897.504 -> settings ID attached to it. TADA. All right,
901.332 -> cool. Dope. And now if I press it again,
905.044 -> it should do the upset version.
908.77 -> So let's just test to make sure that works.
912.53 -> Oh yeah, testing things by clicking buttons.
917.67 -> And then if we go back here and we
920.792 -> refresh this update it. All right,
923.992 -> cool. So that's how you test everything works.
927.29 -> You just write really simple buttons and queries and
931.052 -> then fix it after the fact.
933.61 -> Okay. And then let's
937.734 -> fix this real quick. Oh, RNS is
940.928 -> enabled. Okay. Just no policies. That's correct.
944.67 -> I'm using it in nontraditional sense, so that makes sense.
948.67 -> What is this code? What is this? The double squares
951.878 -> in the sign in page route. So anyway, to answer your question,
955.572 -> what is this? This is called an optional catchall route.
959.49 -> So this gives you the ability to pass in query
963.262 -> parameters, and it will use those query parameters for
966.952 -> something. So in this example, if you were to
970.168 -> go to here and
973.928 -> log out here's the signing page that we're currently
977.868 -> on. And if we sign into
981.116 -> this, let me actually fix it. So it's using the right one. Is this
984.588 -> the right one? Yes. Paths.
988.33 -> Let's update these real quick. Sign up
993.55 -> and sign in. All right,
997.344 -> so I apply these changes and go back to my application.
1002.13 -> We should be able to go to
1006.468 -> localhost again. All right.
1009.972 -> This time it's really hard to see on
1014.552 -> screen, but if you look here, maybe if I
1017.768 -> zoom in, it doesn't work on zoom in. That's fine.
1021.51 -> The URL right now is this.
1025.59 -> So these querying parameters wouldn't work. And then when
1029.548 -> you use something like OAuth to do a sign in. So let's sign
1033.276 -> in as me again. The URL
1037.31 -> that gets passed back contains OAuth tokens.
1041.03 -> Oh, hello. What is happening now?
1044.67 -> I like to go in crazy, but yeah. So there's some
1049.47 -> changes there that allow you to essentially optional catchall
1053.098 -> route that allows you to catch things like OAuth parameters or something
1056.612 -> like that, which is what we're using in Clark
1060.634 -> to do sign in, sign up, user profile,
1064.586 -> all that kind of jazz allows you to essentially handle OAuth.
1068.95 -> Let's try this one. So essentially that's all they're doing. Optional casual
1072.622 -> roles. That's the next year's thing. If you've never seen it before, next year's
1075.854 -> has a great documentation about how they work.
1079.724 -> All right, so now we have that.
1083.21 -> I suppose we should build something up. Oh, actually, we should
1086.668 -> make sure that this actually loads saying.
1090.188 -> So let's do a div real quick and
1093.696 -> do Sangsangs.
1097.974 -> I got to fix that dev too. Yes, no problem,
1103.01 -> anytime. Okay, so if I now
1106.612 -> go to settings, in theory, we should get thanks.
1110.708 -> Updated. That is indeed what comes from the database. Okay,
1114.068 -> so all of that is working now. So we now have optional
1117.518 -> catch our route. We now have the ability to
1121.352 -> technically update them, although we need to add Zod to
1125.096 -> handle the input in. And then we should be good to
1128.684 -> go, at least for this page. But we got a lot of UI to build,
1132.972 -> and that's where my handy Dandy Shacker
1136.658 -> UI comes in. I bet we can find something in here that will probably do
1139.728 -> what I'll form layouts, baby. We could probably take
1144.83 -> some of this because I only want them to be able
1148.352 -> to update a very small amount of code,
1151.876 -> which is basically just this
1155.316 -> piece, but with four or five pieces,
1158.09 -> I'm more interested in what they're doing here in
1162.692 -> this space. Let me just check Twitch again, make sure it hasn't exploded
1166.718 -> into a million pieces. No, we're still good.
1170.12 -> All right, cool. Let's go and see
1174.47 -> if we can build something fairly similar to this.
1177.516 -> Right. Okay.
1181.37 -> So let's import container,
1184.73 -> set the max width to seven
1189.12 -> Excel, and then we'll
1194.352 -> import that container.
1197.95 -> Yep. And jamstack and form control
1203.79 -> and form input.
1207.63 -> Input. And we'll call it day.
1211.14 -> Right. And then we'll do a stack.
1215.11 -> And inside of that stack, we'll have a form and we'll
1218.814 -> have an input pipe equals
1224.31 -> password.
1227.35 -> Cool. All right, everything seems to be working now, so I can
1230.54 -> go back to this screen. Perfect. All right,
1233.85 -> so what we can do now is take an input
1237.362 -> as a password and we'll give it an
1241.088 -> area label set to dev
1245.152 -> to input.
1248.59 -> And then we'll give it a placeholder. We'll say
1252.368 -> dev to API
1256.33 -> key because I'm pretty sure I
1260.228 -> should check actually, while we're here.
1262.93 -> One of my open issues for this was to check to see if dev two
1266.472 -> had done anything yet. So we need hash node and
1270.872 -> hash node publication. And we'll just
1274.232 -> put in this for a quick second.
1282.73 -> We'll hit save, and we'll go look see what that looks like first.
1286.73 -> So we go here. All right. Step from being
1290.224 -> the size of hey, thanks for becoming a subscriber. I really
1293.472 -> appreciate that. Apart from being an absolute pain in the
1297.184 -> butt and being the full width that works.
1301.57 -> Although is it technically type password? Not really,
1305.604 -> but I think we can do this instead.
1309.17 -> Wait, no, that's not what I want.
1312.55 -> I think I want password. It's not really, but I
1316.568 -> guess it needs to be a password and
1320.79 -> none of them are required. Off the top of
1323.944 -> my head, you need one to
1327.528 -> actually use the project in the old one, you needed at least one to get
1331.228 -> it to go. Once you did one, you were good.
1334.38 -> But we can take this button here. Let me
1338.428 -> drop that in here and we can say button.
1341.71 -> Hey, Jess. How's it going? Yeah, I agree. We'll do
1345.168 -> James custom for it. Probably in the long term long range
1348.742 -> of everything. I'll end up just making something custom that
1352.836 -> does what I want. Cool. Looks like a thing.
1357.17 -> Is form control an individual thing, or is it on everything?
1361.828 -> It is on individual things. All right,
1365.51 -> we'll just set this to dev two. I can never remember
1370.47 -> getting old. And then form
1374.392 -> control ID is hash
1379.058 -> node. And then we'll call the last one hash node
1382.322 -> pub. Hash node pub.
1389.63 -> And that should be everything.
1392.4 -> And then we can wrap this whole thing in a form.
1396.59 -> And then she it. Did I fuck up.
1400.768 -> Oh, one more. And now we have a form that
1404.388 -> we can say on submit and then
1408.372 -> we'll make this. And now we'll update
1412.138 -> our mutate to actually take some inputs.
1416.062 -> So we need to import Z for
1420.008 -> Zod. Oh, Zod. What would I do without you?
1423.4 -> Wrong page on here.
1426.71 -> How do I not have it here either? Sometimes you can't win a more Z.
1431.29 -> So if you've never seen Zod before, let's talk
1435.148 -> about it. So the way that Zod works is it's
1439.794 -> this great feature, I did a piece on it recently. But what
1443.008 -> it does is essentially allows you to do some really great stuff.
1445.936 -> So you can basically do something like, here is a schema. My schema should be
1450.016 -> at least a string, right? If it's a string,
1453.334 -> then this would pass and you
1457.028 -> could continue on. If you did this, it would throw a Zod error, which you
1460.644 -> can then handle however you want. So if you wanted to throw an error
1464.202 -> or return an error back to handle on the front end, you could
1467.944 -> do that. And then you could do things like this, right? So you can say
1471.128 -> const user is an object and it should contain all of these things.
1474.856 -> A username, maybe it contains a password, maybe it contains a first name,
1478.092 -> last name, all those kinds of things. And you essentially
1481.682 -> get to infer that as a user and then use
1484.956 -> it wherever you need to as part of TypeScript, which gives you the
1488.508 -> ability to essentially keep user
1492.002 -> input validated and typesie before it even gets anywhere.
1496.31 -> And it does some really cool stuff. One of my favorite things is this.
1500.75 -> So if you know the limit of what your input should
1504.672 -> be, or maximum or length, or if it should be an email,
1507.828 -> or starts with or is a Uuid, all these kinds of things, right?
1511.044 -> And then you can return the message with the error message.
1514.804 -> So you could use that to then power the front end. For example, like you
1518.712 -> return that as an error message. You read that error message, you put toast up
1521.608 -> that says, hey, by the way, you input your email wrong.
1524.968 -> It should be this. This is what you entered or whatever you want to do.
1530.09 -> Giving the user the ability to update that and then try again,
1533.42 -> but also keeps everything safe and
1536.764 -> or secure. So how does
1540.128 -> that work with TrpC? That's a great question.
1542.91 -> So if we use create T three app because it's just easier and
1547.472 -> we say, I believe that they may have something oh God,
1551.87 -> trash is on my screen. Yeah, you do something like
1555.81 -> let's see if they have any examples. They usually
1559.556 -> are good for examples. It's usually where I find most of my examples to
1563.172 -> tell people about. Apparently not. Well,
1566.456 -> okay, then I'll just go to TrpC and look it up.
1569.672 -> But yeah, essentially what you can do here is use odd to create that
1573.288 -> piece in between allowing you
1576.952 -> to do something before you check. So this
1580.188 -> should be a string, this should be X, this should be Y.
1583.9 -> So that when you do a TrpC request you don't get the wrong
1587.452 -> information but let's just do
1590.992 -> it here. So input should
1596.208 -> go like this and then this
1599.536 -> will then into
1602.836 -> what we want. So for our example here we're saying
1606.34 -> there's an object and it contains these things.
1609.89 -> So we'll also have those things. There may be an extra one
1613.448 -> there and it will be oh, thank you very much.
1617.75 -> Becoming a follower super appreciate that. We would change this from
1621.608 -> text. It would be dev two and
1625.084 -> it could be null and it could be a string and this object
1628.844 -> in general could be null. And then we need
1633.85 -> hash node also to be
1639.31 -> Z string and it could also be null
1642.854 -> or hash node pub could
1647.952 -> also be a Z string nullish and
1652.692 -> that should be everything.
1655.81 -> We can fix that with some of this.
1659.57 -> And then if we hit save, then Prettier should fix all of my
1663.592 -> bad code skills. And we should have something fairly
1667.502 -> good here, and then we can take
1670.84 -> that and we can say we've
1674.638 -> checked this. It should always be one of these. And if
1678.124 -> it's not, then it will get messed up. And then we should be
1681.884 -> able to do yeah.
1684.73 -> Input question mark,
1687.63 -> hash node and then oh,
1691.28 -> hello there. Welcome to the subscribers.
1695.126 -> And that could also be knowledge and then the same down here
1699.136 -> too. Although thinking long
1702.756 -> term that this probably won't work the
1705.988 -> way that we want, we'll have to do something like if
1709.748 -> it's knowledge, give it back the old one. But that's fine, we can deal with
1713.544 -> that when it comes to it. But overall this should essentially work
1717.64 -> and our mutate now should have the ability to
1722.23 -> pass in our dev two,
1725.99 -> our hash node and our
1729.468 -> hash node pub. And what we
1732.524 -> can do here is do really bad code. So event
1737.79 -> target zero value.
1741.568 -> Don't do this kids,
1744.67 -> don't do this anywhere. But we'll do it right now. We'll set this to two
1749.23 -> and this to one and we'll put comma here and
1752.468 -> we'll hit save and then we'll go back
1755.812 -> to the local host version and we'll type some stuff
1759.716 -> in here. Yeah, I hate that a lot
1764.07 -> and it do be
1767.448 -> doing stuff. Let's see what it did in our set table.
1771.75 -> As you can see, my very technical EFF and
1776.652 -> then maybe even a reef has worked. So that now
1781.036 -> essentially gives us type safety and also everything
1784.796 -> that we need. This needs to change obviously, but it gives
1788.492 -> us the beginning parts to how someone can update their settings.
1791.97 -> One thing that we need to do is make this not type password. It's going
1795.504 -> to be like type text but like on
1799.312 -> blur will hide. But I think that's where we're going to end the stream
1803.254 -> for today because the input is now working like we're getting all of our data
1806.516 -> back. It's working as expected, which is nice. That doesn't normally
1810.266 -> happen on the first go, so yeah. So if you
1813.572 -> did enjoy the livestream, make sure that you're following me on Twitch.
1817.166 -> If you are a Twitch girl. If you're on YouTube, make sure you subscribe
1821.022 -> to the channel because I do weekly videos, if not,
1825.064 -> two a week at the moment. And we'll be live again on
1829.21 -> Thursday this week. And then if you're really interested in TrpC the
1833.612 -> next week on the 19th. On Thursday at 06:00 p.m.,
1837.138 -> we'll be live with two of the TrpC Corps members
1841.18 -> and Trash Dev talking all about TrpC.
1844.754 -> And I'll see you on the next Livestream on Thursday.
1849.01 -> See?

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