
Join the Conversation!
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
"Please login to view comments"
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
Complete source code for this lesson is available at
By logging in, you'll unlock full access to this and other free tutorials on JSM Pro.
Why? Logging in lets us personalize your learning experience, track your progress, and keep you in the loop with new workshops, coding tips, and platform updates.
You'll also be the first to know about upcoming launches, events, and exclusive discounts.
No spam—just helpful content to level up your skills.
If that sounds fair, go ahead and log in to continue →
Enter your name and email to get instant access
##Looks like we found a thief monkey By the way, I liked the trick how you reached till here. You have a good sense of humor. You will improve a lot if you join our course with this passion.
var
(function-scoped, outdated)let
(block-scoped, modern and recommended)const
(block-scoped, cannot be reassigned)_
, or $
let let = 5;
is invalid)myVar
and myvar
are different)string
, number
, boolean
, null
, undefined
, bigint
, symbol
Objects
, Arrays
, Functions
Subscribing gives you access to a brief, insightful summary of each lecture to stay on track.
00:00:02 Before we develop the UI to show all the users, let's actually render an empty state that we're going to show if there are no users.
00:00:10 We can do that by heading over into states.ts where we had default errors, empty tags, empty collections, and so on.
00:00:18 And we can add another one, export const empty underscore users.
00:00:25 where it'll have a title of no users found and a message saying something like, you're alone.
00:00:35 The only one here.
00:00:36 More users are coming soon.
00:00:38 Now head over to app.
00:00:41 root, community, and pageDSX.
00:00:44 And here we can put that getUsers function to use.
00:00:47 Doing that is super simple.
00:00:49 First, I will make it an asynchronous function, and I will destructure the search params from the props, which will be of a type route params.
00:01:00 What are those search params?
00:01:01 Well, if you have a URL and you have something like page is equal to one, and then an end sign, and then something like sort is equal to hot.
00:01:10 Stuff like that.
00:01:11 You can get access to all of those search params just by destructuring search params from the props in Next.js.
00:01:17 Once we get that, we can destructure them.
00:01:19 Const page, page size, maybe a query and a filter.
00:01:25 And this will be equal to await search params.
00:01:29 And let me show you what I mean.
00:01:31 I'll add two different H1s right here.
00:01:34 One that'll render the page information and one that'll render the page size.
00:01:39 And I'll give both of them a class name of Text-White and Text-Excel.
00:01:45 Also, at the start, we can say what they are.
00:01:48 So this one is a page and this one is a page size.
00:01:51 Now, if you go back, you can see both the page and the page size are empty.
00:01:55 But if you add a question mark and say something like page is two, you can see that we get the number two here.
00:02:03 And you say, and page size is three, you get page size three.
00:02:07 So no dark magic here.
00:02:09 We can simply and easily extract search parameters from the URL.
00:02:14 Now let's put those parameters to use by calling our fetchUsers.
00:02:19 I'll destructure the success, the data, and the error by calling await getUsers, coming from lib actions, user action.
00:02:31 And I'll pass over a page equal to a number version of a page.
00:02:37 Now, why do we have to turn this into a number, you might think?
00:02:41 Isn't page a number on its own?
00:02:43 Well, no.
00:02:44 If you type off of any specific search param and go back, you'll see that all search params are strings, even though you specify the number here,
00:02:54 because a URL is a string.
00:02:56 So once you extract it, it'll still continue being a string.
00:03:01 So what do you have to do?
00:03:02 Well, you have to actually wrap it in a number to make it a number.
00:03:07 I'll say page or a number one by default.
00:03:10 We can do page size will be a number of the page size search param or 10. And then we can pass the query and filter, which are strings by default anyway.
00:03:22 Now out of that data, we can extract the users by saying const users is equal to data or an empty object, just so we don't have any errors later on.
00:03:33 And now we can display those users.
00:03:35 Let me show you just how simple that is now that we have access to our data renderer component.
00:03:42 I'll render an H1 that'll have a class name of H1 bold, text-dark100, light 900, and I'll say all users.
00:03:54 I'll actually collapse it so you can see what's happening on the right side.
00:03:59 Below it, I'll run the right div that'll have a class name equal to margin top of 11. And within it, I will render a local search.
00:04:10 Coming from components, search, local search.
00:04:14 To it, I'll pass a route that we're searching through, and that'll be a routes.community.
00:04:22 So let's just import routes from constants routes and say community.
00:04:27 We need to define the icon position, which in this case will be left.
00:04:32 An image source, which will be forward slash icons, forward slash search dot SVG.
00:04:39 A placeholder, search some great devs and other classes, which will be equal to flex dash one.
00:04:48 There we go.
00:04:49 I'll say something like, there are some great devs here.
00:04:54 Now, below this div, we can render our most important component, which is the data renderer component.
00:05:01 If you take anything from this course, besides of how amazing Next.js is and everything that it offers, you can take the way in which we constructed this
00:05:10 beautiful masterpiece of a data renderer component.
00:05:13 that shows some states.
00:05:16 Like, I mean, check this out.
00:05:17 I just rendered data renderer without providing the data, and it says something went wrong.
00:05:22 But once we do pass some data, it'll actually render it in an appropriate way.
00:05:26 But check this out.
00:05:28 If I pass an empty state of empty underscore users, which we created in constants, and then for the data, you pass an empty array,
00:05:40 and you pass the success, equal to success, as well as the error is equal to error.
00:05:45 Now it'll know that it succeeded, but there are no users.
00:05:49 So it says, you're alone, the only one here, more users coming soon.
00:05:54 But in this case, we're going to pass real users because we know that there are some users here.
00:05:59 So I'll simply pass users as data.
00:06:01 And now we can choose how each one of these users will be rendered.
00:06:06 So I'll extract the users here.
00:06:09 And I'll render a div, and within it, I'll map over the users by saying users.map, give me each individual user, and for each one of these users,
00:06:20 I will render a p tag with that user's name.
00:06:24 In this case, it looks like it still says the users are empty.
00:06:27 Oh, you know why that is?
00:06:29 I think that's because I changed the URL right here.
00:06:32 It says page size three and page two.
00:06:35 We want to remove the URL query, so we are on the first page.
00:06:39 And there we go.
00:06:40 Then it works.
00:06:41 Looks like there's a Sujata here, an Adrian, and another Adrian.
00:06:45 We can easily fix this error by providing each p tag a key equal to user.name, and we can style it a bit.
00:06:54 By giving this div a class name equal to margin top of 12, flex, flex dash wrap, and a gap of five.
00:07:04 There we go.
00:07:04 Now they're in some kind of a grid layout.
00:07:07 And we can give each p tag a class name of body dash regular, text dash dark 500, light 500. And if we save this, this is looking good.
00:07:21 But now, of course, we want it to look like this, to actually show the user's avatar, name, and a username.
00:07:29 So to do that, let's develop a user card.
00:07:33 I'll do it right here within the components folder, within cards, and I'll call it a user card.tsx.
00:07:43 I'll run RAFCE and very quickly import it within the community page instead of the speed tag.
00:07:53 So I'll simply render a user card.
00:07:58 There we go.
00:08:00 Now to this user card, we can pass over all the user information, such as a key of user dot underscore ID, as well as we'll spread the entire user information.
00:08:11 So now we can just see three user cards.
00:08:14 So let's develop it within this user card.
00:08:17 I'll first destructure all the props that I know we'll have an underscore ID, a name, an image, a username, and all of these are of a type user.
00:08:29 And within it, we can have an immediate return.
00:08:32 So just parentheses of a div.
00:08:36 That'll have a class name of shadow-light100, dark none, w full, on extra large devices, w of 330 pixels, which will be the width of the card.
00:08:52 Within it, let's render an article, typically used for like a singular element, and we can give it a class name of background-light100.
00:09:00 900, underscore dark 200, light dash border, flex, w fool, flex dash call, items dash center, justify dash center, rounded dash 2xl,
00:09:18 border, and a padding of eight.
00:09:21 There we go.
00:09:21 Now we can see three little cards right here.
00:09:23 Right within it, I'll render a user avatar coming from dot dot slash user avatar.
00:09:30 We created it before and I'll pass it an ID equal to underscore ID, a name equal to name, an image URL equal to image.
00:09:43 a class name of size-100 pixels, rounded-full and object cover, as well as a fullback class name equal to text-3xl and tracking widest.
00:10:00 And that'll show three different avatar icons.
00:10:03 And now we can see some kind of half circles and circles.
00:10:07 That's pretty interesting.
00:10:08 We want to show circles for all of them.
00:10:10 But just before we do that, let's create a new link component coming from next link and give it an href pointing to routes.profile.
00:10:22 And to that profile, we want to pass an ID.
00:10:25 So this will be an underscore ID of the profile that we want to go to.
00:10:30 And within it, we can have a div that'll have a class name equal to margin top of four and text dash center with an H3 that'll render the name.
00:10:41 And then a p tag below it that'll render the at username so that it looks something like this.
00:10:49 We show both the name and the username and we can style them a bit.
00:10:52 The name should be more prominent.
00:10:54 So let's give it a class name of h3 bold.
00:10:58 Text dash dark 200, light 900, line clamp 1. There we go.
00:11:06 And for the username, let's give it a class name of body dash regular, text dash dark 500, light 500, and a margin top of 2. There we go.
00:11:18 That's better.
00:11:19 And as I said, you might notice that the user avatar is not working as expected, even though we're passing some class names.
00:11:26 So let's head over into it and let's fix it by adding a CN right here.
00:11:32 So we can provide more classes.
00:11:34 I'll always give it a relative class.
00:11:37 And then I'll also add the class names we're providing into it.
00:11:41 And you can see that the only one that is working well is this one for Adrian, which is actually not a real image, but a fallback.
00:11:49 So we know that this one is not working.
00:11:52 So instead of giving it a fixed width and height, let's simply give it a fill property so it takes the space of its container.
00:12:00 There we go.
00:12:01 That's better.
00:12:02 And with that, now that we're using our user card, the data renderer is doing the rest.
00:12:07 So if we check it out in full screen, this is looking amazing.
00:12:11 I can search for Sujata and I get only her.
00:12:14 Or if I search for Adrian, I should get the other two.
00:12:17 Maybe JavaScript mastery.
00:12:19 Yep.
00:12:19 You can see that the search by username works as well.
00:12:23 Also, is it responsive?
00:12:25 Well, of course it is.
00:12:26 I mean, just check this out.
00:12:27 It works great up to this point.
00:12:29 Then we get tablet devices to still show three in a single line.
00:12:34 And then on the phone, it looks like this.
00:12:38 Looking good.
00:12:39 So great job on implementing the community section.
00:12:43 You can see that it's actually much easier now that we have the data renderer, the search.
00:12:48 And just the whole infrastructure of the application set up to be super flexible to allow us to display different pieces of data.
00:12:57 Whether that's user profiles or collections of questions, it all follows the same principles.
00:13:04 So let's go ahead and commit it by saying something along the lines of implement.
00:13:09 display all users, commit and sync, and great job on coming to the end of this short but sweet community module.