Build Laravel 9 Follow Unfollow System Part 2
In the second part of this tutorial, we are going to add the register and the login pages, and finally, we will add the home page where we will display all the users and make them follow and unfollow each other, you can download the source code from here.
Create the app.blade.php
The structure of the views folder will be like this:
> views
> auth
login.blade.php
register.blade.php
> layouts
app.blade.php
navbar.blade.php
home.blade.php
The content of the file app.blade.php:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<title>Laravel Follow Unfollow</title>
</head>
<body class="bg-light">
<div class="container">
@include('layouts.navbar')
@yield('content')
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>
</html>
Create the navbar.blade.php
The content of the file navbar.blade.php:
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm rounded">
<div class="container-fluid">
<a class="navbar-brand" href="{{url('/')}}">Laravel Follow Unfollow</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="{{url('/')}}">Home</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Account
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
@guest
<li><a class="dropdown-item" href="{{route('register')}}">Register</a></li>
<li><a class="dropdown-item" href="{{route('login')}}">Login</a></li>
@endguest
@auth
<li><a class="dropdown-item" href="#">{{auth()->user()->name}}</a></li>
<li><a
onclick="document.getElementById('logoutForm').submit();"
class="dropdown-item" href="#">Logout</a></li>
<form id="logoutForm" action="{{route('logout')}}" method="post">@csrf</form>
@endauth
</ul>
</li>
</ul>
</div>
</div>
</nav>
Create the register.blade.php
The content of the file register.blade.php:
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center my-5">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Register') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('register') }}">
@csrf
<div class="row mb-3">
<label for="name" class="col-md-4 col-form-label text-md-end">{{ __('Name') }}</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>
@error('name')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email">
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="password-confirm" class="col-md-4 col-form-label text-md-end">{{ __('Confirm Password') }}</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
</div>
</div>
<div class="row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Register') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
Create the login.blade.php
The content of the file login.blade.php:
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center my-5">
<div class="col-md-8">
@if (session()->has('error'))
<div class="alert alert-danger my-3">
{{session()->get('error')}}
</div>
@endif
<div class="card">
<div class="card-header">{{ __('Login') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('login') }}">
@csrf
<div class="row mb-3">
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-0">
<div class="col-md-8 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Login') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
Create the home.blade.php
The content of the file home.blade.php:
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center my-5">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Users') }}</div>
<div class="card-body">
<ul class="list-group">
@foreach ($users as $user)
<li class="list-group-item d-flex flex-column">
<div class="d-flex justify-content-between align-items-center">
<span class="fw-bold">
{{$user->name}}
</span>
@if(auth()->user()->id !== $user->id)
@if(auth()->user()->followings->contains($user->id))
<a href="{{route('unfollow',['follower_id' => auth()->user()->id, 'following_id' => $user->id])}}" class="btn btn-sm btn-danger">unfollow</a>
@else
<a href="{{route('follow',['follower_id' => auth()->user()->id, 'following_id' => $user->id])}}" class="btn btn-sm btn-primary">follow</a>
@endif
@endif
</div>
<div class="my-2">
<span class="badge rounded-pill bg-light text-dark">
Followings: {{$user->followings()->count()}}
</span>
<span class="badge rounded-pill bg-light text-dark">
Followers: {{$user->followers()->count()}}
</span>
</div>
</li>
@endforeach
</ul>
</div>
</div>
</div>
</div>
</div>
@endsection