« Previous Tutorial Next Tutorial »

You guys wanna build a log in page? Well, let’s get right to it.

We’re going to create a new page component, then use some Reactstrap to make it look pretty. We’re also going to add some custom Sass into our build so that we have a little more control over margins and similar.

Let’s start by hitting our command prompt or terminal window and adding the packages we’ll need to process Sass. Here’s the command:

yarn add sass-loader node-sass

Let that do its thing, switch back to Sublime, and open webpack.config.js. We’ll need to add a rule for Sass files, which use the .scss extension, just like we did for jsx and css files. It will go below the two other rules, and look like this:

      {
        test: /\.scss$/,
        use: ExtractTextPlugin.extract({
          use: [
            {
              loader: 'css-loader',
            },
            {
              loader: 'sass-loader',
            },
          ],
          fallback: 'style-loader',
        }),
      },

Save that file and you’re good to go. Now under /src, create a folder called “css” and in it, create a file called “musiclist.scss”. This will be where we put our own custom styles and overrides. For now, all we need is the following:

header {
  margin-bottom: 1rem;
}

This will give a little padding between our header and our content, which is always nice. Of course, right now, nothing is telling Webpack where that scss file is, so open /src/index.jsx and just below line 4, where we’re importing Bootstrap’s css, let’s add the following:

import './css/musiclist.scss';

Save this file. Now the style.css file that Webpack is serving from its dev server includes our custom styles. Unfortunately, thought, styles don’t reload, so you have to refresh to see visual changes. Do that, and your margin should show up. Great!

Let’s move on to the login page. Create a file in /src/components/account called LoginPage.jsx. At the top of the file, we’ll need to import React and a few Reactstrap components, with these two lines:

import React from 'react';
import { Button, Form, FormGroup, Label, Input } from 'reactstrap';

We’re going to create this component as an ES6 class, just like our Header, because we’re eventually going to need some state manipulation for form validation (among other things). So, here’s the code for that:

export default class LoginPage extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <p>this is the log in page</p>
    );
  }
}

Exiting, right? Don’t worry, we’ll improve it. Also, ESLint is going to complain like crazy about this file, because we’re not using all of those components we imported from Reactstrap, and because we’re using a class to do something that, right now, could be done with a pure function instead. That’s OK. Sometimes you just have to let ESLint errors show up for a while until future work makes them go away.

We need to add a route to our template, so open /src/components/template.jsx and underneath line 5, add the following:

import LoginPage from './account/LoginPage';

… I like to keep my imports in alphabetical order, but it’s up to you. Order doesn’t matter, here. Now add a route under like 15, like this:

          <Route exact path="/account/login" component={LoginPage} />

Save that file, and let’s check our page real quick and make sure we can actually see it. If your server is up and running, you should be able to just click the “Log In” link in your header. If not, fire up your server and check.

Working? Cool. Let’s add a form to the Log In page. Replace &lt;p&gt;this is the log in page&lt;/p&gt; with the following code:

      <div className="row justify-content-center">
        <div className="col-10 col-sm-7 col-md-5 col-lg-4">
          <Form>
            <FormGroup>
              <Label for="exampleEmail">Email</Label>
              <Input
                type="email"
                name="email"
                id="exampleEmail"
                placeholder="noreply@musiclist.com"
              />
            </FormGroup>
            <FormGroup>
              <Label for="examplePassword">Password</Label>
              <Input
                type="password"
                name="password"
                id="examplePassword"
                placeholder="password"
              />
            </FormGroup>
            <Button>Log In</Button>
          </Form>
        </div>
      </div>

This looks longer than it really is, because for a couple of long input tags, we’ve broken them down into multiple lines. This is a common standard for React development—in fact, ESLint will complain to you if any line is longer than 100 characters—so you’re going to see it a lot. It may feel awkward at first, but it can be really helpful when dealing with a component that has a lot of props.

Anyway, as you can see all we’re really doing is creating a centered column, with no sidebar, that stays at a reasonable width in any resolution. At extreme high resolutions, the input boxes will get a little big, but I guess we’ll live with that.

Save the file. Your hot-reloader should’ve hot-reloaded, and you should now be able to see our fancy new Log In page (note: log in page may be less fancy than advertised by the previous sentence). I think Bootstrap’s default placeholder text is way too dark, and makes the forms look already filled in, so let’s quickly add the following to musiclist.scss:

.form-control::-webkit-input-placeholder { color: #EEE; }
.form-control::-moz-placeholder { color: #EEE; }
.form-control:-ms-input-placeholder { color: #EEE; }
.form-control:-moz-placeholder { color: #EEE; }

Save that, and then refresh … unfortunately our CSS doesn’t hot reload, so to see style changes, that’s how it’s gotta be.

So, there we have it. We’ve built log in page. By the way, now would be a good time to commit all of your changes to your repo. In the next tutorial, we’re heading back into Express to create the API endpoints we’ll need to log a user in and out. See you there!

« Previous Tutorial Next Tutorial »