This video is available to students only

Building the UI of the Homepage

📝 The cancun.jpg image asset used in this lesson can be found - here.
📝 The dubai.jpg image asset used in this lesson can be found - here.
📝 The london.jpg image asset used in this lesson can be found - here.
📝 The los-angeles.jpg image asset used in this lesson can be found - here.
📝 The map-background.jpg image asset used in this lesson can be found - here.
📝 The san-fransisco.jpg image asset used in this lesson can be found - here.
📝 The toronto.jpg image asset used in this lesson can be found - here.

The homepage we're going to build is to be to mostly presentational and aims to serve the purpose of telling the user what our app does as well as provide useful links to direct them elsewhere. There will be two child components we're going to create as part of the homepage:

  • The <HomeHero /> component which is would be the upper portion of the homepage that is to have the search functionality and the different visual cards to help direct users to certain specific cities.
  • The <HomeListings/> component which is the list of the highest priced listings we'll display to the user.

Everything else in the homepage will just be part of the <Home /> parent component.

The first thing we'll do as part as part of this lesson is to focus on the more presentational parts of the page while in the next lesson or so, we'll look to make the query for the recently added root level listings field to give us the four highest priced listings.

Note: There are a couple of static image assets we'll need for the homepage that is to be kept in an assets/ folder in the src/sections/Home/ directory. At the top of this lesson manuscript, you'll be able to find links to each of the image assets sources.

<HomeHero />

<HomeHero /> - Cards

We'll work in the src/sections/Home/index.tsx file to create the <Home /> component that's rendered in the index route of our app. The first thing we'll do is create the <HomeHero /> component file and an index.ts file in a components/ folder within the src/sections/Home/ directory.

client/
  src/
    // ...
    sections/
      // ...
      Home/
        components/
          HomeHero/
            index.tsx
          index.ts
      // ...
  // ...

In the src/sections/Home/components/index.ts file, we'll re-export the <HomeHero /> component function we'll soon create.

client/src/sections/Home/components/index.ts
export * from "./HomeHero";

In the src/sections/Home/components/HomeHero/index.tsx file, we'll import the React library and everything else we might need. We'll import all the components we'll need from Ant Design such as the <Card />, <Col />, <Input />, <Row />, and <Typography /> components. We'll import the image assets we'll use in this <HomeHero /> component from the assets/ directory in the parent Home / directory - which is the image assets of the cities of toronto, dubai, los angeles, and london.

We'll destruct the <Title /> sub-component from <Typography /> and we'll destruct the <Search /> sub-component from <Input />. And we'll export a component function named HomeHero.

import React from "react";
import { Card, Col, Input, Row, Typography } from "antd";

import torontoImage from "../../assets/toronto.jpg";
import dubaiImage from "../../assets/dubai.jpg";
import losAngelesImage from "../../assets/los-angeles.jpg";
import londonImage from "../../assets/london.jpg";

const { Title } = Typography;
const { Search } = Input;

export const HomeHero = () => {};

In the <HomeHero /> component return statement, we'll return a parent <div /> element with two children - another <div /> element and the Ant Design <Row /> component. We'll apply a gutter spacing between each columns that is to be shown within the <Row />.

import React from "react";
import { Card, Col, Input, Row, Typography } from "antd";

import torontoImage from "../../assets/toronto.jpg";
import dubaiImage from "../../assets/dubai.jpg";
import losAngelesImage from "../../assets/los-angeles.jpg";
import londonImage from "../../assets/london.jpg";

const { Title } = Typography;
const { Search } = Input;

export const HomeHero = () => {
  return (
    <div className="home-hero">
      <div className="home-hero__search"></div>
      <Row gutter={12} className="home-hero__cards"></Row>
    </div>
  );
};

The .home-hero__search <div /> element will be responsible in displaying the <Title /> as well as the Search <Input /> where users will be able to search for listings in a certain city. The <Input /> component from Ant Design is fairly straightforward and essentially provides a text input where we can specify some additional variations. The <Search /> sub-component gives us the ability to have a search button alongside the input and gives us the capability to use a onSearch() callback prop which gets triggered either when the user presses the "Enter" key or clicks the search button.

With that said, in the <HomeHero /> component, let's add a <Title /> that says "Find a place you'll love to stay at" and a <Search /> input that is to have a placeholder that says "Search San Fransisco" (we're using San Fransisco as an example of a location that can be searched). In the <Search /> input, we'll provide a size placeholder with a value of "large" which helps specify we want a visibly large input. We'll also pass an "enterButton" prop which helps display the search button alongside the input.

import React from "react";
import { Card, Col, Input, Row, Typography } from "antd";

import torontoImage from "../../assets/toronto.jpg";
import dubaiImage from "../../assets/dubai.jpg";
import losAngelesImage from "../../assets/los-angeles.jpg";
import londonImage from "../../assets/london.jpg";

const { Title } = Typography;
const { Search } = Input;

export const HomeHero = () => {
  return (
    <div className="home-hero">
      <div className="home-hero__search">
        <Title className="home-hero__title">Find a place you'll love to stay at</Title>
        <Search placeholder="Search 'San Fransisco'" size="large" enterButton className="home-hero__search-input" />
      </div>
      <Row gutter={12} className="home-hero__cards"></Row>
    </div>
  );
};

Next, we'll build out a row of cards for the different cities we'll want the user to see in the home hero section. We'll essentially set up four separate columns and in md and greater viewports, we'll want each of the columns to take 1/4th of the entire width of the viewport.

import React from "react";
import { Card, Col, Input, Row, Typography } from "antd";

import torontoImage from "../../assets/toronto.jpg";
import dubaiImage from "../../assets/dubai.jpg";
import losAngelesImage from "../../assets/los-angeles.jpg";
import londonImage from "../../assets/london.jpg";

const { Title } = Typography;
const { Search } = Input;

export const HomeHero = () => {
  return (
    <div className="home-hero">
      <div className="home-hero__search">