5

Building a Full Stack Application From Scratch with Svelte and Node (PART 6) — N...

 3 years ago
source link: https://tahazsh.com/fullstack-app-with-svelte-and-node-part-6
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

In this part, we'll focus on getting the signup and login pages created. Until they are connected to our backend server (which we haven't created yet), they'll just console log some message and redirect the user to the homepage.

We'll also create the nav bar so users can navigate to those pages.

Let's start with the nav bar.

Creating the nav bar component

For now, we'll just display the logo on the left, and the login and signup links on the right. In the future, we'll revisit this component to support showing the currently logged-in user along with the logout button.

Create Nav.svelte in src/routes/_components and put this into it:

<nav class="navbar">
  <div class="navbar-left">
    <a
      class="logo"
      href="/"
    >
      News App
    </a>
  </div>
  <div class="navbar-right">
    <a
      class="navbar-link"
      href="/login"
    >
      Log in
    </a>
    <a
      class="navbar-link"
      href="/signup"
    >
      Sign up
    </a>
  </div>
</nav>

Now let's display it at the top for all pages. To do that, open src/routes/_layout.svelte and add it at the top, like this:

<script>
  import Nav from './_components/Nav.svelte'
</script>

<Nav/>

<main>
  <slot></slot>
</main>

If you check your browser, you'll see it displayed at the top on all pages:

1.png

Creating the signup page

Like other pages, we create it inside src/routes but without the underscore prefix. So create src/routes/signup/index.svelte and add the following code into it (explained below):

<script>
  import { goto } from '@sapper/app'

  let user = { username: '', password: '' }
  let inProgress = false
  let error = null

  async function submit () {
    try {
      inProgress = true
      console.log('send a request to create the user')
      inProgress = false
      error = null
      user = { username: '', password: '' }
      goto('/')
    } catch (err) {
      error = err.response.data.message
      inProgress = false
    }
  }
</script>

<svelte:head>
  <title>Sign up</title>
</svelte:head>

<form
  class="signup-form"
  on:submit|preventDefault="{submit}"
>
  {#if error}
    <span class="error-message">
      {error}
    </span>
  {/if}
  <input
    class="text-input username-input"
    bind:value="{user.username}"
    type="text"
    placeholder="username"
    required
  >
  <input
    class="text-input password-input"
    bind:value="{user.password}"
    type="password"
    placeholder="password"
    required
  >
  <button
    class="signup-button primary-button"
    disabled="{inProgress}"
  >
    SIGN UP
  </button>
</form>

In the script section, we defined user, inProgress, and error variables. The user variable holds the current values for the signup form, username and password. The inProgress indicates whether the user creation request is being processed. And finally, the error variable would hold any error the server returns when trying to create the user.

When the submit function is called, we send the user creation request, reset the form, and redirect the user to the home page (that's what goto('/') is for). That's in case the request was successful. If the server returns an error, we put it in error to be displayed to the user.

In the HTML section, we're displaying the signup form with the username and password fields. Below those fields, we have the sign up button, which gets disabled if inProgress is true.

Note how we're displaying the server error above the fields in case the server returned one.

The signup page should look like this:

2.png

Creating the login page

The login page is almost the same as the signup page. So let's just copy this code into src/routes/login/index.svelte‌.

<script>
  import { goto } from '@sapper/app'

  let user = { username: '', password: '' }
  let inProgress = false
  let error = null

  async function submit () {
    try {
      inProgress = true
      console.log('send a request to login the user')
      inProgress = false
      error = null
      user = { username: '', password: '' }
      goto('/')
    } catch (err) {
      error = err.response.data.message
      inProgress = false
    }
  }
</script>

<svelte:head>
  <title>Login</title>
</svelte:head>

<form
  class="login-form"
  on:submit|preventDefault="{submit}"
>
  {#if error}
    <span class="error-message">
      {error}
    </span>
  {/if}
  <input
    class="text-input username-input"
    bind:value="{user.username}"
    type="text"
    placeholder="username"
    required
  >
  <input
    class="text-input password-input"
    bind:value="{user.password}"
    type="password"
    placeholder="password"
    required
  >
  <button
    class="login-button primary-button"
    disabled="{inProgress}"
  >
    LOG IN
  </button>
</form>

This page should look similar to the signup page except that it has "LOG IN" button instead of "SIGN UP".

What's next?

At this point, most of the UI components have been created. Let's now shift our focus to connecting those components to the backend server to display and update real data.

Our first step to this is to create the backend server with Node and Express. That's what our next part is about.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK