Foundation

Turning sketches into code

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To 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 Fullstack Typescript with TailwindCSS and tRPC Using Modern Features of PostgreSQL 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.

This video is available to students only
Unlock This Course

Get unlimited access to Fullstack Typescript with TailwindCSS and tRPC Using Modern Features of PostgreSQL, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course Fullstack Typescript with TailwindCSS and tRPC Using Modern Features of PostgreSQL
  • [00:00 - 00:11] So what is going to be the foundation of our UI? Well, when looking at our sketches from before, it looks like every page is going to have this box in the middle of it.

    [00:12 - 00:25] So let's try and create a component that creates this box for us as a wrapper and can have children that represents the contents inside of it. Let's start by creating a new booking component.

    [00:26 - 00:37] So we'll create a new file here in our front end source called new booking.tsx. And I will just paste this code in here.

    [00:38 - 00:43] We'll go over this in a minute, but let's for now try and use this in our app. tsx.

    [00:44 - 00:51] So our new booking component takes children. Let me just auto import that here.

    [00:52 - 01:07] So I can specify in here, say a div where it says page one. Like so.

    [01:08 - 01:25] Let's try and run that and see what it looks like. Let's try and refresh this.

    [01:26 - 01:35] There we go. So let's quickly try and break down the styling of our new component.

    [01:36 - 01:44] I will not be doing this for every class that we're going to be using, but this is just the introduction to tailwind. So let's just quickly go through what these classes do.

    [01:45 - 01:57] So the outer div is sort of a wrapper for the entire screen. And for that, we're setting the minimum height to be screen, which is actually, as you can see, 100 VH, which is short for view height.

    [01:58 - 02:07] So that specifies that this outer div will be as tall as the screen or taller if any content specifies. So it will have 100% width.

    [02:08 - 02:13] So it will just be as wide as the page. It will have a slightly gray background, very bright.

    [02:14 - 02:28] And then it will have a vertical padding of 12, which is 48 pixels, both at the top and at the bottom. So this py is a way to specify that we want the padding for both y dimensions applied.

    [02:29 - 02:43] The alternatives would be to specify either P12 if we wanted padding on all four sides, or PT for top or PB for bottom and so on. This inner div then specifies the box itself.

    [02:44 - 02:52] So we're setting MX to auto. That means that both margins on the horizontal level will be auto, which will centroid horizontally.

    [02:53 - 03:03] We will say that we want it to be display flex, and we want it to be flex column. That means that things will go underneath each other inside this div.

    [03:04 - 03:21] We want it to be maximum 768 pixels wide, which is sort of a standard for like that used to be a, well, I don't think it actually used to be a screen width, but that's sort of a standard for dimensions for a width for a website. Then we want to make sure it has a rounded border.

    [03:22 - 03:28] So we specify that it has a border, which is this light gray. It should have a white background.

    [03:29 - 03:40] Then it should have horizontal padding of 12 and a little bit of padding vertically, and then there should be a large shadow. So let's just take a look at it again to see if we can see all of those things.

    [03:41 - 03:49] We can see the vertical padding here. There's similar vertical padding down here, but that's invisible since the box itself is much shorter than this.

    [03:50 - 04:11] But the fact that we specified min height to be the viewport height, but just the min height, not the actual height, means that this box can be as tall as it wants, and we will still have the light gray background here covering the entire page. If this grows taller than that, we will get a scroll bar out on the right and we will still get the vertical padding at the bottom.

    [04:12 - 04:25] We have the padding here as we set it, and we have slightly rounded borders, and we have a drop shadow. So before we get into the contents of the first page, let's just quickly think about navigation.

    [04:26 - 04:33] There are basically two ways you can do navigation in a setup like this. You can use the browser history API, or you can use state.

    [04:34 - 04:56] Now if you want to use the browser history API, you get some obvious advantages , which is that each page lives on its own URL, and that means that the browser back button will work exactly like people will expect it to. It also means that you can take one page and bookmark it, or you can take the URL and share it, send it to a friend, whatever you might want to do.

    [04:57 - 05:12] However, I would argue that in our particular cases, this is a funnel, we don't actually want people to be able to bookmark or share a specific page. If you want to send somebody a friend to this flow, we want this friend to start at this start.

    [05:13 - 05:31] So for that particular reason, I'm going to be using state for this navigation setup. So since all this navigation will actually take place within this box, let's just move the logic into new booking component and change it from something that takes children to just contain its own navigation.

    [05:32 - 05:54] So instead of having this take children, let's delete this and this, and then we can create a state, we can call it current page. Let's see if I get autocomplete.

    [05:55 - 06:14] I don't know why it doesn't detect that right now. So this is now a number that just specifies, okay, the current page starts at zero.

    [06:15 - 06:23] And so instead of this children here, we need to specify what the current page is. Let's first create three pages.

    [06:24 - 06:36] I have some here that I'll just paste. So if you remember the flow, we're going to have a page where the user chooses the service type and then they will choose the date and then then the end they will enter their email.

    [06:37 - 06:49] And for now, we'll just make these components that just show what the page is and we'll expand on those later. So we can make a quick little statement in here that specifies this.

    [06:50 - 07:00] So if current page is zero, we'll show the choose type page and so on. Let's see if this has been updated nicely.

    [07:01 - 07:05] It says choose type. So that is page zero.

    [07:06 - 07:16] Actually we need to change our app.tx now because this is just a, this doesn't take any children. Like so.

    [07:17 - 07:22] There we go. With that in place, let's try and add some navigation.

    [07:23 - 07:36] So we go back to our new booking page here and underneath these, we will insert a div that has two buttons in it. So these buttons will set the current page to current page minus one and plus one.

    [07:37 - 07:46] And obviously there's no check if you go outside the legal range or anything, but let's just see what that looks like. Well done.

    [07:47 - 07:54] We can choose all of the three pages and what happens if I go to minus one, I get no page because nothing exists there.