Event Page
Create the events list timeline page for the event management application
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
This lesson preview is part of the Sleek Next.JS Applications with shadcn/ui course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to Sleek Next.JS Applications with shadcn/ui, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

[00:00 - 00:07] In the previous lesson you have built the site layout another. In this lesson you are going to build the event list page.
[00:08 - 00:16] The first step would be to add the page title. As you can see here, we can reuse the typography components from the new site model.
[00:17 - 00:28] Copy and paste its content into a new file in Component/Typography. You can also find it in the course text below.
[00:29 - 00:46] Now go to app/page.tsx and replace its content with the h1 title. Your site should now look similar to this.
[00:47 - 00:59] We want to make sure that the content of the page catches the full width. So remove the class name from the section tag.
[01:00 - 01:08] Great! The second step is to create the events list component. This is what it should look like at the end.
[01:09 - 01:19] This part is the event list component. It is responsible for fetching and rendering upcoming events and letting users view and register for them.
[01:20 - 01:46] So start by creating the data model. Create a new file in types, call it events.tsx, and add the event type, expert type event, equal an id, title, description, location, date, image, and a user.
[01:47 - 02:03] Then create a new component called event list. We're going to use the SWR library for fetching data from a pre-made API that will help us create, manage, and register for events.
[02:04 - 02:11] Let's install the library. In your terminal one, npm is stdoshs SWR.
[02:12 - 02:43] Import the library, the library default export the hook that we can use, and import the event type we've just created. The used SWR hook accepts a key, which is the URL that we will call, and a feature function, which is a function that requests and returns data from the API based on disk.
[02:44 - 03:13] So let's create a new feature function in lib, create a new file, call it feature, export const feature equal, a function that receives a URL, which is string, and call the fetch function, the native fetch function. Import it in the event list component.
[03:14 - 03:28] And now we add the API URL in your .env file. Create a new file, call .env file, and add the NEXT_PUBLIC_API_URL key.
[03:29 - 03:54] I'm currently running the API locally, but the deployed version of it will be available to you through the course text. Go back to the event list component, and let's create the component and fetch the data, expert cons to events list, equal a component function, and we want to call the use SWR hook.
[03:55 - 04:14] It returns an object with the data error and loading states, uses SWR, and we want to type it, so we want to give it an object with the return value from the API call. In our case, the API returns events, which is an array of the event type.
[04:15 - 04:27] And we want to pass the URLs, so we'll use the ENV key of just created. And we want to call the event route, and we'll also pass the fetcher function.
[04:28 - 04:36] Looking again at the component UI, we can see the events are grouped by date. We showcase the date and the day of the week.
[04:37 - 04:41] And then we render the actual events list on the other side. This is two side left.
[04:42 - 04:53] So under the hook function, let's write a reduced function that will group the events by date. It will make it easier for us to render the data side by side.
[04:54 - 05:04] The date and the event list. Const grouped by date equal the return data, the return events array.
[05:05 - 05:13] With a reduced function, the reduced function receives two parameters. The previous value, which we returned, we also call it accumulated.
[05:14 - 05:28] And the current item that we mapped through the event, the current event. We want to use dayjs for the function, so install it as well in your terminal.
[05:29 - 05:42] Then go back to the code, and let's save the date, the actual date that we will display here. We will create a new object that will save the date and the events list.
[05:43 - 05:53] So const date equal dayjs with the event date. And then we're going to form a date to MMM DD.
[05:54 - 06:02] Let's import dayjs as well. Let's also pass the initial value.
[06:03 - 06:12] So it will be easier to understand how this object looks like. So the returned value will be a record of a string, which is the date.
[06:13 - 06:21] And then an object with the day, the day name, and the actual events. Don't forget to close that.
[06:22 - 06:35] And then if we don't have a property, which is this date on the return value, we're going to create one. We're going to format the date to the day of the week.
[06:36 - 06:44] And we're going to create an empty array event. Then we're going to push the event into the events array.
[06:45 - 06:55] And we'll must return the previous value as well. Now run the app.
[06:56 - 07:09] And let's return null from the function, but console log the group by date object. Turn the component into a client component.
[07:10 - 07:23] Now go to app/page.tsx and render the event list component. Now navigate to your browser.
[07:24 - 07:26] And we can see an arrow. Let's check it out.
[07:27 - 07:37] Looking at the code, we can see that our condition was wrong. So if there is no date property on the results object, then one to create it.
[07:38 - 07:46] Now navigate back to the browser. And if you refresh the page and go to the console tab, you can see that the created object is logged to the console.
[07:47 - 07:58] It's constructed from the day, which we will render soon in the event list. And then inside of it there is an object with the day name and the events list.
[07:59 - 08:03] The structure makes it really easy for us to render it on the page. Let's do it.
[08:04 - 08:09] Go back to the editor and let's create the event item component. We'll do it in the same file as the event list.
[08:10 - 08:13] It's a sort of a media object. We can look at the design.
[08:14 - 08:30] Media on one side, the image, and text and details on the other side. Start by installing the card component from shadcn/ui, npx shadcn-ui@latest add card.
[08:31 - 08:35] Re-run the app. And let's implement the event item component.
[08:36 - 08:48] Export const to event item receives an event as a prop. And we can immediately return.
[08:49 - 09:05] We return a card with a class name of bejim muted with a 25% opacity and full with don't forget to import a card. Then render the card header.
[09:06 - 09:14] And let's add some style to it. We want the content of it to be aligned.
[09:15 - 09:31] Render a container div. And add a card description component.
[09:32 - 09:42] Add some margin bottom to it. We want to show the hours and minutes of the date.
[09:43 - 10:11] Under the description render the title, which is the event title. And then let's render another container div with a margin top and we'll make it a grid.
[10:12 - 10:26] Let's render the location. We're going to add the muted full-gown text class and a small medium text size.
[10:27 - 10:37] And we're going to render the map P icon with a size 4 class name. And right next to it, we're going to render the event location.
[10:38 - 10:55] And we're going to copy the icon and the text and replace the map pin with a user icon and save the event user, the creator of the event. Perfect. This is the first side.
[10:56 - 11:02] Now for the second side, we want to render the image. Remember the aspect ratio component.
[11:03 - 11:16] We're going to install it as well. Rerun the app.
[11:17 - 11:26] Import the aspect ratio component. Add a 4 divided by 3 ratio.
[11:27 - 11:41] Wrap the component with a container div and make it width 64. And then let's render an image from next image package.
[11:42 - 11:47] Add a fill attribute to it. Render the alt, which is the event title.
[11:48 - 11:55] The class name will be Object Cover. And we want to make it rounded on medium and larger screens.
[11:56 - 12:02] Of course, render the image source or the events. Let's format it.
[12:03 - 12:13] Now there are three more components we need to get a full experience. The first is the separator between the date lines and the event list items.
[12:14 - 12:18] This part. The second is the date itself.
[12:19 - 12:24] This component. And the last one is the dot on the separator.
[12:25 - 12:32] We're going to add a sticky position to the date and the date dot. So that when the user scroll, the dot will scroll as well.
[12:33 - 12:40] Now create the date separator. Navigate to the events list page.
[12:41 - 12:48] And let's start with the date separator. Export const DateSeparator.
[12:49 - 12:55] Div with a class name. Border foreground with 10% opacity.
[12:56 - 12:59] Absolute position. Left.
[13:00 - 13:03] 116 pixels. Top 2.
[13:04 - 13:06] Full height. Border.
[13:07 - 13:17] And let's make the border dashed. Now let's create the date component, which will render the actual date.
[13:18 - 13:31] We want to pass the date, any date. As props, both are strings.
[13:32 - 13:37] And return. We can immediately return.
[13:38 - 13:44] Add div with a width 32 class name. Then another div, which is the sticky part that we talked about.
[13:45 - 13:52] Top 4. Render the date dot that we will create in a second.
[13:53 - 14:07] And inside of it, render another div, which will be agreed. And render a simple span with a font bold class name.
[14:08 - 14:22] With the date, enemy to the component with the date. And the last part is the date dot, which will also simply return.
[14:23 - 14:43] Add a border foreground. Now all the building blocks are ready.
[14:44 - 15:03] Let's map through the group by date of the keys and render the items. Instead of returning null, return a div with some top margin.
[15:04 - 15:16] And then run over the group by date object keys. We also want to make sure that when there is no events, we still pass an object .
[15:17 - 15:28] And then map through an array, which will return us the date. And the events render a container div with a key.
[15:29 - 15:38] Don't forget to add a relative class name, so the sticky component will work. Add a long gap and some padding bottom.
[15:39 - 15:46] Now render the date. And the date as well.
[15:47 - 15:59] The date separator and create a container for the event items. You now want to loop through the events themselves.
[16:00 - 16:09] And render an event item, of course, with a key. The title is a good key for this component.
[16:10 - 16:16] And the actual event. Great, let's format it.
[16:17 - 16:24] We actually want to loop through the object entries and other object keys. Now go back to the app.
[16:25 - 16:34] And we get an invalid source prop. If you remember it from the previous model, we need to configure the next.con fig.js image property.
[16:35 - 16:41] Now, on the previous model, we didn't know where images are going to come from. But in this model, we do know.
[16:42 - 16:54] So where the image is property, which receives an object and then remote patterns, which is in array. And then at the next name, which is re.cloudinary.com.
[16:55 - 17:00] The protocol should be HTTPS. And that should be enough.
[17:01 - 17:18] Rewind the app. Rew protocol.
[17:19 - 17:25] Refresh the app. And we can now see the event list being rendered.
[17:26 - 17:40] We don't have a full width on the event list item, so let's check why. We forgot to style the event item containers.
[17:41 - 17:44] Go back to the site. And now the item's catch their full width.
[17:45 - 17:50] Now try to scroll and see how the date dot and the date are being scrolled as well. And are kind of switched between them.
[17:51 - 18:01] This is a call transition to show the user what date it looks at. The last part for the event list to work fully is adding a loading state.
[18:02 - 18:12] When events are loading, you can show a loading state to the user. So let's install the skeleton component first, which we also used in the previous models.
[18:13 - 18:41] Rewind the app. like this part, under the object entries loop.
[18:42 - 18:32] And go back to the event list component. There are two components that we need for the loading state.
[18:33 - 18:45] And then the event item skeleton. So let's start with the event item.
[18:46 - 18:56] We can copy paste the event items to keep the same structure. And create another component called event item skeleton.
[18:57 - 19:03] Now we can replace every occurrence of the content with a skeleton component. Should look something like that.
[19:04 - 19:17] Under the card description. Should actually render a card title for the title.
[19:18 - 19:30] And we don't necessarily have to render the dates on the skeleton. So let's just replace the card title with a skeleton.
[19:31 - 19:45] It can have like a simple height and 64 width. Now let's do the same under the location.
[19:46 - 19:55] It can actually make it one height. And we can do the same for the image.
[19:56 - 20:11] We can just make it catch its full width and height. Now for the event section skeleton.
[20:12 - 20:16] It can also simply return. And here I've already prepared the actual skeleton.
[20:17 - 20:32] So you can copy and paste it from the course text below. And now add an ease loading rendering if the ease loading state is set to true.
[20:33 - 20:58] Simply return a date with the margin at the top and render an event section skeleton. If you go to your browser and open the app, you can see it a bit more clearly.
[20:59 - 21:17] You can also make the network to throttle and you'll see it much better. Here is the skeleton and it will be replaced with the data as soon as it's coming back.
[21:18 - 21:22] In the next lesson, you're going to add the event detail sheet.