Laravel AdminLTE 3 Admin Dashboard Integration Step By Step Guide

1 year ago

Laravel full stack development empowers developers to build dynamic and scalable applications with ease, combining Laravel’s robust backend with modern frontend tools like Vue.js, React, or AdminLTE with Bootstrap. AdminLTE, with its rich UI components and Bootstrap foundation, allows you to create professional and responsive dashboards effortlessly. By integrating these tools, you can simplify complex tasks like routing, database management, and UI design, making it an ideal choice for building full-featured web applications. Dive in and let Laravel streamline your development process while boosting your skills!


AdminLTE 3 is a popular open-source dashboard template based on Bootstrap 4. It comes with various UI components, responsive layouts, and pre-built widgets, making it ideal for creating admin dashboards. Integrating AdminLTE 3 with Laravel helps you build powerful admin panels with ease. In this tutorial, I’ll walk you through the process of integrating AdminLTE 3 in a Laravel application.

Step 1: Create a New Laravel Project

If you haven't already, create a new Laravel project. Run the following command to do so:
composer create-project --prefer-dist laravel/laravel adminlte-app

OR

Follow the post below to set up secure authentication using Laravel Breeze, which provides a simple yet secure login and registration system. Once you've completed the authentication setup, come back here to continue integrating AdminLTE 3 into your project for a fully functional admin dashboard.

Build Secure Authentication with Laravel Breeze in Minutes | Laravel 11

Step 2: Download AdminLTE3

Download the adminLTE3 from official website and Extract the zip file. You can follow this link to download: Download AdminLTE3.


Step 3: Copy AdminLTE Resources to Laravel Public Folder

After downloading and extracting AdminLTE 3, you will have the files and folders mentioned earlier. Copy the dist folder from the extracted files and paste it into the public directory of your Laravel project.


Now It’s time to integrate AdminLTE3 in Laravel Project. Open the laravel project in VS Code code editor. Open new terminal and run the app by using following command.

php artisan serve

Browse the app in brows http://127.0.0.1:8000


Step 4: Start Integrating Login Page

Lets integrate login page first. Navigate to the resource/views folder and create a folder named ‘backend’. Inside the ‘backend’ folder create a folder ‘auth’ and inside ‘auth’ folder create a file named ‘login.blade.php’ file. In ‘login.blade.php’ file write a following code.



login.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.min.css" integrity="sha256-Qsx5lrStHZyR9REqhUF8iQt73X06c8LGIUPzpOhwRrI=" crossorigin="anonymous">
    <link rel="stylesheet" href="{{ asset('dist/css/adminlte.css') }}">
</head>

<body class="login-page bg-body-secondary">
    <div class="login-box">
        <div class="login-logo"> Login</a> </div>
        <div class="card">
            <div class="card-body login-card-body">
                <p class="login-box-msg">Sign in to start your session</p>
                <form action="{{ route('login') }}" method="post">
                    @csrf
                    <div class="input-group mb-3">
                        <input type="email" class="form-control" name="email" placeholder="Email">
                        <div class="input-group-text"> <span class="bi bi-envelope"></span> </div>
                    </div>
                    @if ($errors->has('email'))
                        <span class="mt-2 text-danger">{{ $errors->first('email') }}</span>
                    @endif

                    <div class="input-group mb-3">
                        <input type="password" class="form-control" name="password" placeholder="Password">
                        <div class="input-group-text"> <span class="bi bi-lock-fill"></span> </div>
                    </div>
                    @if ($errors->has('password'))
                        <span class="mt-2 text-danger">{{ $errors->first('password') }}</span>
                    @endif

                    <div class="row">
                        <div class="col-8">
                            <div class="form-check"> <input class="form-check-input" type="checkbox" value="" id="flexCheckDefault">
                                <label class="form-check-label" for="flexCheckDefault">
                                    Remember Me
                                </label>
                            </div>
                        </div>
                        <div class="col-4">
                            <div class="d-grid gap-2"> <button type="submit" class="btn btn-primary">Sign In</button> </div>
                        </div>
                    </div>
                </form>
                <div class="social-auth-links text-center mb-3 d-grid gap-2">
                    <p>- OR -</p>
                    <a href="/register" class="btn btn-primary"> Register </a>
                </div>
            </div>
        </div>
    </div>
</body>
</html>


Now, Navigate to app/Http/Controllers/Auth/AuthenticatedSessionController.php file. You will find a function called create(): View. Replace that function with following code and leave other codes as it is.

public function create(): View
{
    return view('backend.auth.login');
    // return view('auth.login');
}

Browse http://127.0.0.1:8000/login, you will fond beautiful Login Page. Enter username and password and click on login. You will land on the default Breeze dashboard. Lets Integrate AdminLTE3 Dashboard in it.


Step 5: Create a Layouts and Inherit Master Template

Navigate to resources/views/backend and create a folder named ‘layouts’ inside layouts create a following files.

masterlayout.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title> @yield('title') </title>
    @include('backend.layouts.styles')
    @yield('style')
</head>

<body class="layout-fixed sidebar-expand-lg bg-body-tertiary">
    <div class="app-wrapper">

        {{-- Top Navbar --}}
        @include('backend.layouts.navbar')

        {{-- Sidebar --}}
        @include('backend.layouts.sidebar')

        <main class="app-main">
            <div class="app-content-header">
                <div class="container-fluid">
                    <div class="row">
                        <div class="col-sm-6">
                            <h3 class="mb-0">
                                {{-- page title --}}
                                @yield('page')
                            </h3>
                        </div>
                    </div>
                </div>
            </div>

            <div class="app-content">
                <div class="container-fluid">
                    {{-- for page content --}}
                    @yield('content')
                </div>
            </div>
        </main>
    </div>

    {{-- Scripts --}}
    @include('backend.layouts.scripts')
    @yield('script')

</body>
</html>


navbar.blade.php

<nav class="app-header navbar navbar-expand bg-body">
    <div class="container-fluid">
        <ul class="navbar-nav">
            <li class="nav-item"> <a class="nav-link" data-lte-toggle="sidebar" href="#" role="button"> <i class="bi bi-list"></i> </a> </li>
            <li class="nav-item d-none d-md-block"> <a href="#" class="nav-link">Home</a> </li>
        </ul>
        <ul class="navbar-nav ms-auto">
            <li class="nav-item dropdown">
                <a class="nav-link" data-bs-toggle="dropdown" href="#">
                    <i class="bi bi-bell-fill"></i>
                    <span class="navbar-badge badge text-bg-warning">2</span>
                </a>
                <div class="dropdown-menu dropdown-menu-lg dropdown-menu-end"> <span class="dropdown-item dropdown-header">1 Notifications</span>
                    <div class="dropdown-divider"></div> <a href="#" class="dropdown-item"> <i class="bi bi-bell me-2"></i> Notification title
                        <span class="float-end text-secondary fs-7">2 days</span> </a>
                    <div class="dropdown-divider"></div> <a href="#" class="dropdown-item dropdown-footer">
                        See All Notifications
                    </a>
                </div>
            </li>
            <li class="nav-item dropdown user-menu">
                <a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown">
                    <img src="{{ asset('dist/assets/img/user2-160x160.jpg') }}" class="user-image rounded-circle shadow" alt="User Image">
                    <span class="d-none d-md-inline"> {{ Auth::user()->name }} </span>
                </a>
                <ul class="dropdown-menu dropdown-menu-lg dropdown-menu-end">
                    <li class="user-header text-bg-primary">
                        <img src="{{ asset('dist/assets/img/user2-160x160.jpg') }}" class="rounded-circle shadow" alt="User Image">
                        <p>
                            {{ Auth::user()->name }} - Web Developer
                        </p>
                    </li>
                    <li class="user-footer">

                        <form method="POST" action="{{ route('logout') }}">
                            @csrf
                            <a href="{{ route('logout') }}" class="btn btn-default btn-flat float-end"
                               onclick="event.preventDefault(); this.closest('form').submit();">
                                Log Out
                            </a>
                        </form>
                    </li>
                </ul>
            </li>
        </ul>
    </div>
</nav>


sidebar.blade.php

<aside class="app-sidebar bg-body-secondary shadow" data-bs-theme="dark">
    <div class="sidebar-brand">
        <a href="/dashboard" class="brand-link">
            <img src="{{ asset('dist/assets/img/AdminLTELogo.png') }}" alt="Logo" class="brand-image opacity-75 shadow">
            <span class="brand-text fw-light"> App Name </span>
        </a>
    </div>
    <div class="sidebar-wrapper">
        <nav class="mt-2">
            <ul class="nav sidebar-menu flex-column" data-lte-toggle="treeview" role="menu" data-accordion="false">
                <li class="nav-item">
                    <a href="/dashboard" class="nav-link active">
                        <i class="nav-icon bi bi-speedometer"></i>
                        <p> Dashboard </p>
                    </a>
                </li>
                <li class="nav-item">
                    <a href="#" class="nav-link">
                        <i class="nav-icon bi bi-clipboard-fill"></i>
                        <p>
                            Menu
                            <i class="nav-arrow bi bi-chevron-right"></i>
                        </p>
                    </a>
                    <ul class="nav nav-treeview">
                        <li class="nav-item"> <a href="#" class="nav-link">
                            <i class="nav-icon bi bi-circle"></i>
                                <p> Menu Option One </p>
                            </a>
                        </li>
                        <li class="nav-item"> <a href="#" class="nav-link">
                            <i class="nav-icon bi bi-circle"></i>
                                <p> Menu Option Two </p>
                            </a>
                        </li>
                    </ul>
                </li>
            </ul>
        </nav>
    </div>
</aside>


styles.blade.php

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/source-sans-3@5.0.12/index.css" integrity="sha256-tXJfXfp6Ewt1ilPzLDtQnJV4hclT9XuaZUKyUvmyr+Q=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/overlayscrollbars@2.3.0/styles/overlayscrollbars.min.css" integrity="sha256-dSokZseQNT08wYEWiz5iLI8QPlKxG+TswNRD8k35cpg=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.min.css" integrity="sha256-Qsx5lrStHZyR9REqhUF8iQt73X06c8LGIUPzpOhwRrI=" crossorigin="anonymous">
<link rel="stylesheet" href="{{ asset('dist/css/adminlte.css') }}">

scripts.blade.php

<script src="https://cdn.jsdelivr.net/npm/overlayscrollbars@2.3.0/browser/overlayscrollbars.browser.es6.min.js" integrity="sha256-H2VM7BKda+v2Z4+DRy69uknwxjyDRhszjXFhsL4gD3w=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha256-whL0tQWoY1Ku1iskqPFvmZ+CHsvmRWx/PIoEvIeWh4I=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.min.js" integrity="sha256-YMa+wAM6QkVyz999odX7lPRxkoYAan8suedu4k2Zur8=" crossorigin="anonymous"></script>
<script src="{{ asset('dist/js/adminlte.js') }}"></script>


Next, go to resources/views/backend and create a file named dashboard.blade.php. Add the following code to this file:

dashboard.blade.php

@extends('backend.layouts.masterlayout')

@section('page', 'Dashboard')
@section('title', 'Dashboard')

@section('content')
<div class="row">
    <div class="col-lg-3 col-6">
        <div class="small-box text-bg-primary">
            <div class="inner">
                <h3>10</h3>
                <p>New Orders</p>
            </div>
            <svg class="small-box-icon" fill="currentColor" viewBox="0 0 24 24" xmlns="#" aria-hidden="true">
                <path d="M2.25 2.25a.75.75 0 000 1.5h1.386c.17 0 .318.114.362.278l2.558 9.592a3.752 3.752 0 00-2.806 3.63c0 .414.336.75.75.75h15.75a.75.75 0 000-1.5H5.378A2.25 2.25 0 017.5 15h11.218a.75.75 0 00.674-.421 60.358 60.358 0 002.96-7.228.75.75 0 00-.525-.965A60.864 60.864 0 005.68 4.509l-.232-.867A1.875 1.875 0 003.636 2.25H2.25zM3.75 20.25a1.5 1.5 0 113 0 1.5 1.5 0 01-3 0zM16.5 20.25a1.5 1.5 0 113 0 1.5 1.5 0 01-3 0z"></path>
            </svg>
            <a href="#" class="small-box-footer link-light link-underline-opacity-0 link-underline-opacity-50-hover">
                More info
                <i class="bi bi-link-45deg"></i>
            </a>
        </div>
    </div>
    <div class="col-lg-3 col-6">
        <div class="small-box text-bg-success">
            <div class="inner">
                <h3>35<sup class="fs-5">%</sup></h3>
                <p>Bounce Rate</p>
            </div>
            <svg class="small-box-icon" fill="currentColor" viewBox="0 0 24 24" xmlns="#" aria-hidden="true">
                <path d="M18.375 2.25c-1.035 0-1.875.84-1.875 1.875v15.75c0 1.035.84 1.875 1.875 1.875h.75c1.035 0 1.875-.84 1.875-1.875V4.125c0-1.036-.84-1.875-1.875-1.875h-.75zM9.75 8.625c0-1.036.84-1.875 1.875-1.875h.75c1.036 0 1.875.84 1.875 1.875v11.25c0 1.035-.84 1.875-1.875 1.875h-.75a1.875 1.875 0 01-1.875-1.875V8.625zM3 13.125c0-1.036.84-1.875 1.875-1.875h.75c1.036 0 1.875.84 1.875 1.875v6.75c0 1.035-.84 1.875-1.875 1.875h-.75A1.875 1.875 0 013 19.875v-6.75z"></path>
            </svg>
            <a href="#" class="small-box-footer link-light link-underline-opacity-0 link-underline-opacity-50-hover">
                More info
                <i class="bi bi-link-45deg"></i>
            </a>
        </div>
    </div>
    <div class="col-lg-3 col-6">
        <div class="small-box text-bg-warning">
            <div class="inner">
                <h3>350</h3>
                <p>User Registrations</p>
            </div> <svg class="small-box-icon" fill="currentColor" viewBox="0 0 24 24" xmlns="#" aria-hidden="true">
                <path d="M6.25 6.375a4.125 4.125 0 118.25 0 4.125 4.125 0 01-8.25 0zM3.25 19.125a7.125 7.125 0 0114.25 0v.003l-.001.119a.75.75 0 01-.363.63 13.067 13.067 0 01-6.761 1.873c-2.472 0-4.786-.684-6.76-1.873a.75.75 0 01-.364-.63l-.001-.122zM19.75 7.5a.75.75 0 00-1.5 0v2.25H16a.75.75 0 000 1.5h2.25v2.25a.75.75 0 001.5 0v-2.25H22a.75.75 0 000-1.5h-2.25V7.5z"></path>
            </svg>
            <a href="#" class="small-box-footer link-dark link-underline-opacity-0 link-underline-opacity-50-hover">
                More info
                <i class="bi bi-link-45deg"></i>
            </a>
        </div>
    </div>
    <div class="col-lg-3 col-6">
        <div class="small-box text-bg-danger">
            <div class="inner">
                <h3>689</h3>
                <p>Unique Visitors</p>
            </div>
            <svg class="small-box-icon" fill="currentColor" viewBox="0 0 24 24" xmlns="#" aria-hidden="true">
                <path clip-rule="evenodd" fill-rule="evenodd" d="M2.25 13.5a8.25 8.25 0 018.25-8.25.75.75 0 01.75.75v6.75H18a.75.75 0 01.75.75 8.25 8.25 0 01-16.5 0z"></path>
                <path clip-rule="evenodd" fill-rule="evenodd" d="M12.75 3a.75.75 0 01.75-.75 8.25 8.25 0 018.25 8.25.75.75 0 01-.75.75h-7.5a.75.75 0 01-.75-.75V3z"></path>
            </svg>
            <a href="#" class="small-box-footer link-light link-underline-opacity-0 link-underline-opacity-50-hover">
                More info
                <i class="bi bi-link-45deg"></i>
            </a>
        </div>
    </div>
</div>
@endsection


{{-- extra css for this page --}}
@section('style')

@endsection

{{-- extra javascript for this page --}}
@section('script')

@endsection


Step 6: Create a Controller and Route for Dashboard

To redirect users to a dashboard after login, it’s best to set up a separate route and controller for the dashboard. Laravel provides a command to generate a controller. Run the following command to create a new controller:

php artisan make:controller DashboardController

After generating the controller, navigate to app/Http/Controllers/DashboardController.php and modify it to include the index method. You’ll also need to define a route for the dashboard. Here's an example of what you might add to the DashboardController:

dashboardController.php

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class DashboardController extends Controller
{
    public function index(){
        return view('backend.dashboard');
    }
}


The index() function will return the view located at backend/dashboard.blade.php. After setting up the controller and view, you need to define a route to access this function and open the newly created dashboard.

Open the routes/web.php file and add the following line to create a route for the dashboard. This route will point to the DashboardController and its index() function:

web.php

<?php

use App\Http\Controllers\ProfileController;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\DashboardController;

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

Route::middleware('auth')->group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
    Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
    Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
    Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
});

require __DIR__.'/auth.php';

Step 7: Start Integrating Register Page

The registration part still needs to be integrated! While it's not essential for standalone web apps or those where user creation is managed by a superadmin or admin, you might want to integrate it if needed. If you prefer to disable the registration function, you can block, remove, or comment out the registration code in the app/Http/Controllers/RegisteredUserController.php file. For this tutorial, however, we'll go ahead and include the registration page as well.

Goto resource/views/backend/auth directory and create a file named ‘register.blade.php’ and write a following code.

register.blade.php

<!DOCTYPE html>
<html lang="en">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title> Register </title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/source-sans-3@5.0.12/index.css" integrity="sha256-tXJfXfp6Ewt1ilPzLDtQnJV4hclT9XuaZUKyUvmyr+Q=" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/overlayscrollbars@2.3.0/styles/overlayscrollbars.min.css" integrity="sha256-dSokZseQNT08wYEWiz5iLI8QPlKxG+TswNRD8k35cpg=" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.min.css" integrity="sha256-Qsx5lrStHZyR9REqhUF8iQt73X06c8LGIUPzpOhwRrI=" crossorigin="anonymous">
    <link rel="stylesheet" href="{{ asset('dist/css/adminlte.css') }}">
</head>

<body class="register-page bg-body-secondary">
    <div class="register-box">
        <div class="register-logo"> Registration </div>
        <div class="card">
            <div class="card-body register-card-body">
                <p class="register-box-msg">Do no have an account? Register now.</p>
                <form action="{{ route('register') }}" method="post">
                    @csrf
                    <div class="input-group mb-3">
                        <input type="text" name="name" id="name" class="form-control" placeholder="Name">
                        <div class="input-group-text">
                            <span class="bi bi-person"></span>
                        </div>
                    </div>
                    @if ($errors->has('name'))
                        <div class="text-danger mt-2">{{ $errors->first('name') }}</div>
                    @endif

                    <div class="input-group mb-3">
                        <input type="email" name="email" id="email" class="form-control" placeholder="Email">
                        <div class="input-group-text">
                            <span class="bi bi-envelope"></span>
                        </div>
                    </div>
                    @if ($errors->has('email'))
                        <div class="text-danger mt-2">{{ $errors->first('email') }}</div>
                    @endif

                    <div class="input-group mb-3">
                        <input type="password" name="password" id="password" class="form-control" placeholder="Password">
                        <div class="input-group-text">
                            <span class="bi bi-lock-fill"></span>
                        </div>
                    </div>
                    @if ($errors->has('password'))
                        <div class="text-danger mt-2">{{ $errors->first('password') }}</div>
                    @endif

                    <div class="input-group mb-3">
                        <input type="password" name="password_confirmation" id="password_confirmation" class="form-control" placeholder="Confirm Password">
                        <div class="input-group-text">
                            <span class="bi bi-lock-fill"></span>
                        </div>
                    </div>
                    @if ($errors->has('password_confirmation'))
                        <div class="text-danger mt-2">{{ $errors->first('password_confirmation') }}</div>
                    @endif


                    <div class="row">
                        <div class="col-4 offset-8">
                            <div class="d-grid gap-2">
                                <button type="submit" class="btn btn-primary">Register</button>
                            </div>
                        </div>
                    </div>
                </form>
                <div class="social-auth-links text-center mb-3 d-grid gap-2">
                    <p>- OR -</p>
                    <span> Already have an account? </span>
                    <a href="{{ route('login') }}" class="btn btn-primary">
                        Sign in
                    </a>
                </div>
            </div>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/overlayscrollbars@2.3.0/browser/overlayscrollbars.browser.es6.min.js" integrity="sha256-H2VM7BKda+v2Z4+DRy69uknwxjyDRhszjXFhsL4gD3w=" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha256-whL0tQWoY1Ku1iskqPFvmZ+CHsvmRWx/PIoEvIeWh4I=" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.min.js" integrity="sha256-YMa+wAM6QkVyz999odX7lPRxkoYAan8suedu4k2Zur8=" crossorigin="anonymous"></script>
    <script src="{{ asset('dist/js/adminlte.js') }}"></script>
</body>
</html>

Now, Navigate to app/Http/Controllers/Auth/RegisterUserController.php file. You will find a function called create(): View. Replace that function with following code and leave other codes as it is.

public function create(): View
    {
        return view('backend.auth.register');
        // return view('auth.register');
    }

Visit http://127.0.0.1:8000/register to access the registration page and create a new user account. With this, the AdminLTE 3 Bootstrap admin dashboard has been successfully integrated. You can now customize it further by adding additional menus and features as needed.


  961
Please Login to Post a Comment