Building a website - vonschappler/Ultimate-React GitHub Wiki

Website Application planning:

For this project we'll now build the customer website for the "The Wild Oasis" company, in which cients can lear about the hotel, browse cabins, reserve a cabin and be able to create and update their profile. Remember that we were "hired" by this company a while ago and we were responsible by creating their internal dashboard application to manage their hotel.

So that means that the same API and data that we used before should be the same for this website.

Project requirements:

  • Users of the application are potential and actual guests
  • Guests should be able to learn about the hotel
  • Guests should be able to get informatil about the cabins and see booked dates
  • Guests should be able to fulter cabins by their capacity
  • Resevations are not paid online
  • Guests should be able to view their past and future reservations
  • Guests should be able to update or delete a reservation
  • Guests need to sign up and login before they can reserve a cabin or perform a reservation
  • On sign up, guests should get a profile on the DataBase
  • Guests should be able to set up and update basic data on their profile, to make check-ins faster

Features categories:

  1. About
  2. Cabins
  3. Reservations
  4. Authentication
  5. Profile

Pages:

Categories Pages
Home (/)
About /about
Cabins /cabins
/cabins/:cabinId
Reservations /cabins/:cabinId
/account/reservations
/account/reservations/edit
Authentication /login
Profile /account/profile

Technologies to be used:

Category Technology
Framework Next.js
UI State management Context API
Database / API supabase
Styling tailwindcss

Project folder structure

To begin with, let's think about components which may be required globaly by our website. We know that creating any folder inside the /app folder will create new route and we surely would not like that.

There is a convention within Next.js in which, if we add an underscore to the folder name, that won't be treated a route for the application, and like so, we can store our components which will be used globally inside that with the name _components inside our main application root folder.

We are also adding two folders:

  1. To store any utilities/custom libraries files, a folder with the name _lib
  2. To sotre any styling (CSS) files, a folder with the name _styles

Setting up Tailwind on Next.js

Even though Tailwindcss was already installed when the initial project was created, we need to enable it by importing the file into our application.

Depending on your application you may or may not have multiple css files to be imported by components, but on our case, we have a single file, named globals.css and this one needs to be imported inside our root layout (/app/layout.js) file, like shown in the code below:

// other imports

import '@/app/_styles/globals.css';

// rest of the layout file

Adding pages metadata and FavIcon

As we already discussed, in order to add metadata to our application this can be done, as conventions, by exporting a named constant metadata as an object inside our root layout.

Any metadata inside that layout will be applied to the whole application, and so, if we want for example to customize individual pages metada, we can also use the same convention / technique on the page.js file present on each route (or even on their individual layouts in case they have nested layouts).

For full list or properties which can be passed inside the metadata object, check Next.js documentation.

As for adding favicons to your application, as per convention, all that you need to do is to add any image on the root of /app folder with the name icon.ext (where .ext is the extension that describes the file format).


Adding custom fonts

To add custom fonts to a Next.js application, we can use a package provided by the framework, which is next/font.

In this example we are going to use some google fonts, but it's possible to use localy/self hosted fonts with this package as well, as referenced on the documentation.

In order to use the package, we can edit our root layout file to something like:

// other imports

import { Roboto } from 'next/font/google';

const roboto = Roboto({
  subsets: ['latin'],
  display: 'swap',
});

// metadata and other definitions

export default function RootLayout({ children }) {
  return (
    <html lang='en'>
      <body className={`${roboto.className}`}>
        <main>{children}</main>
      </body>
    </html>
  );
}

Adding images to the website

Next.js also provides images optmization. This is important because images are one of the most important fact that contributes in increasing the chunk size to be fetched by the client.

The procces of images optmization can be done by using the Image component provided by Next.js, just like displayed in the following code.

// imports the Image component
import Image from 'next/image';

// imports the image for better accessiblity
import image from '@/public/image.ext';

function RenderImage() {
  return (
    <Image
      src={image}
      height='60'
      width='60'
      alt='The Wild Oasis logo'
      quality={100}
    />
  );
}

export default Logo;

Keep in mind that the way the image component was used above it's just one of the many different ways of adding images to any Next.js application in a optmized way. To learn more about image optmization, remember to check details on Next.js docs.


Nested Routes, Pages and Layouts:

As already discussed about the App router model for Next.js, new routes are created based on the folder structure of the project, in which:

  1. We can opt out sub-folders of /app not to be routes, by adding _ at the begin of the folder name, eg. _notRoute
  2. We need to add a page.js file in folders so those can be rendered on screen

So, to create nested routes / pages, all we need to do is to create sub-folders where we need those nested routes, in which they'll have a page.js file.

A similar concept also applies to layouts, with the convention to nested layouts is having the nested layout named as layout.js.

⚠️ **GitHub.com Fallback** ⚠️