Laravel E-Commerce Application Development – Frontend Login & Registration

Laravel E-Commerce Application Development – Frontend Login & Registration

Laravel E-Commerce Application Development ( 27 Lessons )

In this course, you’ll learn how to create an E-Commerce Website from scratch in Laravel. The process has never been easier I’ll take you from the very beginning stages of setting up Laravel till the last steps of adding products to the cart. If you’ve good understanding & experience in PHP & MySQL then this course is for you.

see full series
  1. Laravel E-Commerce Application Development – Introduction
  2. Laravel E-Commerce Application Development – Initial Project Setup
  3. Laravel E-Commerce Application Development – Assets Setup Using Laravel Mix
  4. Laravel E-Commerce Application Development – Admin Model and Migration
  5. Laravel E-Commerce Application Development – Backend Admin Authentication
  6. Laravel E-Commerce Application Development – Base Controller and Repository
  7. Laravel E-Commerce Application Development – Settings Section Part 1
  8. Laravel E-Commerce Application Development – Settings Section Part 2
  9. Laravel E-Commerce Application Development – Categories Section Part 1
  10. Laravel E-Commerce Application Development – Categories Section Part 2
  11. Laravel E-Commerce Application Development – Attributes Section Part 1
  12. Laravel E-Commerce Application Development – Attributes Section Part 2
  13. Laravel E-Commerce Application Development – Attributes Section Part 3
  14. Laravel E-Commerce Application Development – Brands Section
  15. Laravel E-Commerce Application Development – Products Section Part 1
  16. Laravel E-Commerce Application Development – Products Section Part 2
  17. Laravel E-Commerce Application Development – Products Section Part 3
  18. Laravel E-Commerce Application Development – Products Section Part 4
  19. Laravel E-Commerce Application Development – Frontend Login & Registration
  20. Laravel E-Commerce Application Development – Categories Navigation
  21. Laravel E-Commerce Application Development – Catalog Listing
  22. Laravel E-Commerce Application Development – Product Details Page
  23. Laravel E-Commerce Application Development – Shopping Cart
  24. Laravel E-Commerce Application Development – Checkout
  25. Laravel E-Commerce Application Development – Payment Processing
  26. Laravel E-Commerce Application Development – Order Management
  27. Laravel E-Commerce Application Development – Wrap Up

This is part 18 of the Laravel E-Commerce Application Development series. In this part, we will add the Frontend Login & Registration pages to our application.

I assume you should have the e-commerce application project on your machine or you can grab it from Laravel E-Commerce Application repository, we will start from where we left it in the last part.

In one of our previous post, we added the admin authentication manually. For frontend authentication, we will use the default authentication provided by the Laravel.

If you open your routes/web.php file, you will find that we have already added the authentication routes using Auth::routes();. If not, then added this to your web.php file.

Updating User Migration File

First thing as we will be using the default User model provided by Laravel for the customers, so they can create their account on our website and place orders.

Open the CreateUsersTable from your migration folder and update it with the below one.

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('first_name');
            $table->string('last_name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->string('address', 255)->nullable();
            $table->string('city')->nullable();
            $table->string('country')->nullable();
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}

As you can see, instead of keeping the name field for our users I have replaced it with two new fields like first_name and last_name. Next we added some extra fields to store the customer address details such as address, city and country.

Now, we want to migrate our users table changes to our database, but if you run the command php artisan migrate you will get the error something like users table already exists.

Here you have two ways to migrate these changes to the database.

First, you can run php artisan migrate:refresh --seed command which will remove all database tables and rerun the migrations with seed classes.

Second, remove the users table manually from the database table and then remove the create_users_table record from the migrations table. Then you can run the php artisan migrate command.

I recommend, to use the first option.

Updating User Model

Once you have migrated the changes to database, it’s time to update the user model. Open the app/Models/User.php model class file and update the $fillable array to below:

/**
 * The attributes that are mass assignable.
 *
 * @var array
 */
protected $fillable = [
    'first_name', 'last_name', 'email', 'password', 'address', 'city', 'country'
];

Next, we will add a new accessor method to get the full name of the user/customer. So add the below method, which simply concatenates the first name and last name.

/**
 * @return string
 */
public function getFullNameAttribute()
{
    return $this->first_name. ' '. $this->last_name;
}

Creating Frontend Layout and Partials

In the previous post, we have already added the frontend assets using the Laravel Mix. Just on the safe side check if you have the frontend folder inside public folder.

Before start making the layout for our website, let’s change the root url to load the home page which we will create later on. Open the routes/web.php file and change the:

Route::get('/', function () {
    return view('welcome');
});

To this:

Route::view('/', 'site.pages.homepage');

Now we will create one layout file and some partial files. Inside your views folder add two new folders site and auth. Inside the auth folder add two files:

  1. login.blade.php
  2. register.blade.php

Now inside the site folder, add two new folders and one file:

  1. pages
  2. partials
  3. app.blade.php

Now inside, pages folder, we will add a new file named homepage.blade.php. Next, we will create five new files inside the partials folder.

  1. footer.blade.php
  2. header.blade.php
  3. nav.blade.php
  4. scripts.blade.php
  5. styles.blade.php

Until now we have created all the files required for this post, now we will start adding the markup in each file.

Open the app.blade.php file from site folder and add the below content.

<!DOCTYPE HTML>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>@yield('title') - {{ config('app.name') }}</title>
    @include('site.partials.styles')
</head>
<body>
@include('site.partials.header')
@yield('content')
@include('site.partials.footer')
@include('site.partials.scripts')
</body>
</html>

In the app.blade.php file, we have added the required HTML markup which is including different partials.

Open the styles.blade.php file from resources/views/site/partials folder and add the below markup.

<link rel="shortcut icon" type="image/x-icon" href="{{ asset('frontend/images/favicon.ico') }}">
<link href="{{ asset('frontend/css/bootstrap.css') }}" rel="stylesheet" type="text/css" />
<link href="{{ asset('frontend/fonts/fontawesome/css/fontawesome-all.min.css') }}" type="text/css" rel="stylesheet">
<link href="{{ asset('frontend/plugins/fancybox/fancybox.min.css') }}" type="text/css" rel="stylesheet">
<link href="{{ asset('frontend/plugins/owlcarousel/assets/owl.carousel.min.css') }}" rel="stylesheet">
<link href="{{ asset('frontend/plugins/owlcarousel/assets/owl.theme.default.css') }}" rel="stylesheet">
<link href="{{ asset('frontend/css/ui.css') }}" rel="stylesheet" type="text/css" />
<link href="{{ asset('frontend/css/responsive.css') }}" rel="stylesheet" media="only screen and (max-width: 1200px)" />

Simply add the required CSS files for our frontend website look.

Open the scripts.blade.php file from the partials folder and add below:

<script src="{{ asset('frontend/js/jquery-2.0.0.min.js') }}" type="text/javascript"></script>
<script src="{{ asset('frontend/js/bootstrap.bundle.min.js') }}" type="text/javascript"></script>
<script src="{{ asset('frontend/plugins/fancybox/fancybox.min.js') }}" type="text/javascript"></script>
<script src="{{ asset('frontend/plugins/owlcarousel/owl.carousel.min.js') }}"></script>
<script src="{{ asset('frontend/js/script.js') }}" type="text/javascript"></script>

Added the required JS files for our site.

Next, we will update the header.blade.php file, so open this file and add below.

<header class="section-header">
    <section class="header-main">
        <div class="container">
            <div class="row align-items-center">
                <div class="col-lg-3">
                    <div class="brand-wrap">
                        <a href="{{ url('/') }}">
                            <img class="logo" src="{{ asset('frontend/images/logo-dark.png') }}" alt="logo">
                        </a>
                    </div>
                </div>
                <div class="col-lg-6 col-sm-6">
                    <form action="#" class="search-wrap">
                        <div class="input-group">
                            <input type="text" class="form-control" placeholder="Search">
                            <div class="input-group-append">
                                <button class="btn btn-primary" type="submit">
                                    <i class="fa fa-search"></i>
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
                <div class="col-lg-3 col-sm-6">
                    <div class="widgets-wrap d-flex justify-content-end">
                        <div class="widget-header">
                            <a href="#" class="icontext">
                                <div class="icon-wrap icon-xs bg2 round text-secondary"><i
                                        class="fa fa-shopping-cart"></i></div>
                                <div class="text-wrap">
                                    <small>3 items</small>
                                </div>
                            </a>
                        </div>
                        @guest
                            <div class="widget-header">
                                <a href="{{ route('login') }}" class="ml-3 icontext">
                                    <div class="icon-wrap icon-xs bg-primary round text-white"><i class="fa fa-user"></i></div>
                                    <div class="text-wrap"><span>Login</span></div>
                                </a>
                            </div>
                            <div class="widget-header">
                                <a href="{{ route('register') }}" class="ml-3 icontext">
                                    <div class="icon-wrap icon-xs bg-success round text-white"><i class="fa fa-user"></i></div>
                                    <div class="text-wrap"><span>Register</span></div>
                                </a>
                            </div>
                        @else
                            <ul class="navbar-nav ml-auto">
                                <li class="nav-item dropdown">
                                    <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                                        {{ Auth::user()->full_name }} <span class="caret"></span>
                                    </a>
                                    <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
                                        <a class="dropdown-item" href="{{ route('logout') }}"
                                           onclick="event.preventDefault();
                                                     document.getElementById('logout-form').submit();">
                                            {{ __('Logout') }}
                                        </a>
                                        <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
                                            @csrf
                                        </form>
                                    </div>
                                </li>
                            </ul>
                        @endguest
                    </div>
                </div>
            </div>
        </div>
    </section>
    @include('site.partials.nav')
</header>

In the last part of this file, we are using @guest() blade directive just to check if the current visitor is a guest or an authenticated user. If current visitor is guest, we will show the login and register button if not then we show the logout link.

Then we are including the nav.blade.php partial file which is actually the main website’s navigation menu. Open the nav.blade.php file and add below:

<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <div class="container">
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#main_nav"
                aria-controls="main_nav" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="main_nav">
            <ul class="navbar-nav">
                <li class="nav-item">
                    <a class="nav-link pl-0" href="#"> <strong>All category</strong></a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Fashion</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Supermarket</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Electronics</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Baby &amp Toys</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Fitness sport</a>
                </li>
                <li class="nav-item dropdown">
                    <a class="nav-link dropdown-toggle" href="http://example.com" id="dropdown07"
                       data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">More</a>
                    <div class="dropdown-menu" aria-labelledby="dropdown07">
                        <a class="dropdown-item" href="#">Foods and Drink</a>
                        <a class="dropdown-item" href="#">Home interior</a>
                        <div class="dropdown-divider"></div>
                        <a class="dropdown-item" href="#">Category 1</a>
                        <a class="dropdown-item" href="#">Category 2</a>
                        <a class="dropdown-item" href="#">Category 3</a>
                    </div>
                </li>
            </ul>
        </div>
    </div>
</nav>

As you can see that it is basically bootstrap navigation, we will populate the categories to this navigation in our next post.

Now, open the homepage.blade.php file from pages folder and add the below content.

@extends('site.app')
@section('title', 'Homepage')

@section('content')
    <h2>Homepage</h2>
@stop

Now if you visit / route then you will have something like below:

Home Page - E commerce Application
Home Page – E commerce Application

Creating Login Page

If you visit the /login url, you will get the empty view. Now, we will create the login page template. Open the resources/views/auth/login.blade.php file and add the below markup in it.

@extends('site.app')
@section('title', 'Login')
@section('content')
    <section class="section-pagetop bg-dark">
        <div class="container clearfix">
            <h2 class="title-page">Login</h2>
        </div>
    </section>
    <section class="section-content bg padding-y">
        <div class="container">
            <div class="col-md-6 mx-auto">
                <div class="card">
                    <header class="card-header">
                        <h4 class="card-title mt-2">Sign In</h4>
                    </header>
                    <article class="card-body">
                        <form action="{{ route('login') }}" method="POST" role="form">
                            @csrf
                            <div class="form-group">
                                <label for="email">E-Mail Address</label>
                                <input type="email" class="form-control @error('email') is-invalid @enderror" name="email" id="email" value="{{ old('email') }}">
                                @error('email')
                                <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                            <div class="form-group">
                                <label for="password">Password</label>
                                <input type="password" class="form-control @error('password') is-invalid @enderror" name="password" id="password">
                                @error('password')
                                <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                            <div class="form-group row mr-auto">
                                <div class="col-md-6">
                                    <div class="form-check">
                                        <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
                                        <label class="form-check-label" for="remember">
                                            {{ __('Remember Me') }}
                                        </label>
                                    </div>
                                </div>
                            </div>
                            <div class="form-group">
                                <button type="submit" class="btn btn-success btn-block"> Login </button>
                            </div>
                        </form>
                    </article>
                    <div class="border-top card-body text-center">Don't have an account? <a href="{{ route('register') }}">Sign Up</a></div>
                </div>
            </div>
        </div>
    </section>
@stop

In this view, we have a form with an email and password input box. Form is pointing to the login route which is already defined in Auth::routes();. If you now refresh your page and you will be presented with a login form like below.

Login Page - E commerce Application
Login Page – E commerce Application

Updating Login Controller

When we submit our form, on successful authentication it will redirect to /home route which is defined in the app/Http/Controllers/Auth/LoginController class.

On successful login we want to redirect user back to the homepage, for that open the LoginController and change the below:

/**
 * Where to redirect users after login.
 *
 * @var string
 */
protected $redirectTo = '/home';

To this:

/**
 * Where to redirect users after login.
 *
 * @var string
 */
protected $redirectTo = '/';

Now, if you submit the login form it will work perfectly.

Creating Registeration Page

In this section, we will add the registration page for our customer. Open the resources/views/auth/register.blade.php file and add the below HTML markup in it.

@extends('site.app')
@section('title', 'Register')
@section('content')
    <section class="section-pagetop bg-dark">
        <div class="container clearfix">
            <h2 class="title-page">Register</h2>
        </div>
    </section>
    <section class="section-content bg padding-y">
        <div class="container">
            <div class="col-md-6 mx-auto">
                <div class="card">
                    <header class="card-header">
                        <h4 class="card-title mt-2">Sign up</h4>
                    </header>
                    <article class="card-body">
                        <form action="{{ route('register') }}" method="POST" role="form">
                            @csrf
                            <div class="form-row">
                                <div class="col form-group">
                                    <label for="first_name">First name</label>
                                    <input type="text" class="form-control @error('first_name') is-invalid @enderror" name="first_name" id="first_name" value="{{ old('first_name') }}">
                                    @error('first_name')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                    @enderror
                                </div>
                                <div class="col form-group">
                                    <label for="last_name">Last name</label>
                                    <input type="text" class="form-control @error('last_name') is-invalid @enderror" name="last_name" id="last_name" value="{{ old('last_name') }}">
                                    @error('last_name')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                    @enderror
                                </div>
                            </div>
                            <div class="form-group">
                                <label for="email">E-Mail Address</label>
                                <input type="email" class="form-control @error('email') is-invalid @enderror" name="email" id="email" value="{{ old('email') }}">
                                @error('email')
                                <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                            <div class="form-group">
                                <label for="password">Password</label>
                                <input type="password" class="form-control @error('password') is-invalid @enderror" name="password" id="password">
                                @error('password')
                                <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                            <div class="form-group">
                                <label for="password_confirmation">Confirm Password</label>
                                <input type="password" class="form-control @error('password_confirmation') is-invalid @enderror" name="password_confirmation" id="password_confirmation">
                                @error('password_confirmation')
                                <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                            <div class="form-group">
                                <label for="address">Address</label>
                                <input class="form-control" type="text" name="address" id="address" value="{{ old('address') }}">
                            </div>
                            <div class="form-row">
                                <div class="form-group col-md-6">
                                    <label for="city">City</label>
                                    <input type="text" class="form-control" name="city" id="city" value="{{ old('city') }}">
                                </div>
                                <div class="form-group col-md-6">
                                    <label for="country">Country</label>
                                    <select id="country" class="form-control" name="country">
                                        <option> Choose...</option>
                                        <option value="United Kingdom">United Kingdom</option>
                                        <option value="France">France</option>
                                        <option value="United States" selected="">United States</option>
                                    </select>
                                </div>
                            </div>
                            <div class="form-group">
                                <button type="submit" class="btn btn-success btn-block"> Sign Up </button>
                            </div>
                            <small class="text-muted">By clicking the 'Sign Up' button, you confirm that you accept our <br> Terms of use and Privacy Policy.</small>
                        </form>
                    </article>
                    <div class="border-top card-body text-center">Have an account? <a href="{{ route('login') }}">Log In</a></div>
                </div>
            </div>
        </div>
    </section>
@stop

In this registration form we have the customer name fields, email, password and customer address fields. This form is pointing to the register route which again defined in the Auth::routes();.

Now visit the /register route and you will have your registration page something like below.

Register Page - E commerce Application
Register Page – E commerce Application

Updating Registration Controller

Before submitting the registration form we will need to make some changes to our RegisterController controller. Open the RegisterController and make the below changes.

  1. Change the use App\User; to use App\Models\User;
  2. Update the $redirect property.
    /**
     * Where to redirect users after registration.
     *
     * @var string
     */
    protected $redirectTo = '/';
  3. Update the validator() method to below:
    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'first_name' => ['required', 'string', 'max:255'],
            'last_name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ]);
    }
  4. Finally update the create() method.
    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return \App\User
     */
    protected function create(array $data)
    {
        return User::create([
            'first_name' => $data['first_name'],
            'last_name' => $data['last_name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
            'address' => $data['address'],
            'city' => $data['city'],
            'country' => $data['country'],
        ]);
    }

Now if you visit the /register route and try to register a customer, you will be redirected back to the homepage after a successful registration.

What’s Next

In the next post, we will start populating the navbar with our categories and will create the category page.

Code Repository

You can find the code base of this series on Laravel eCommerce Application repository.

If you have any question about this post, please leave a comment in the comment box below.

6 comments on “Laravel E-Commerce Application Development – Frontend Login & Registration

    1. In the backend, you can create a form to update the password. One field for the current password and then new password with password confirmation. Then in the validation, you can use the same rule to validate the current password. After validation simply update the admin’s new password using bcrypt($newPassword) helper function.

      Hope to answer the question.

      Thanks

  1. When i run cmd “php artisan migrate:refresh –seed” i got this error

    Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‘) default character set utf8mb4 collate ‘utf8mb4_unicode_ci” at line 1 (SQL: create table `product_attributes` () default character set utf8mb4 collate ‘utf8mb4_unicode_ci’)

    Please help me to fix error, tks all

    1. Try
      $table->collation = 'utf8_general_ci';
      $table->charset = 'utf8';

      In your migration file. I assume you are having charset problem, also I recommend to use MySQL instead of MariaDB.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

When sharing a code snippet please wrap you code with pre tag and add a class code-block to it like below.
<pre class="code-block">you code here</pre>

*
*

This site uses Akismet to reduce spam. Learn how your comment data is processed.