Nous avons dans le précédent article terminé la gestion des commentaires. Nous avons donc l'essentiel du frontend de notre blog mais nous sommes encore loin d'en avoir terminé ! Dans le présent article nous allons changer les vues de l'authentification pour les adapter à notre thème. Ca va être un peu laborieux parce qu'il nous faut pas mal de vues, mais on va s'arranger pour rester suffisamment DRY pour que ça se passe bien !
Vous pouvez télécharger le code final de cet article ici.Un petit point
Avec Breeze on a installé un dossier avec toutes les vues de l'authentification : On va conserver ces vues, à part confirm-password et verify-email qui ne nous serviront pas, et juste en changer le code. On a aussi installé de nombreux composants :Là on va être sans pitié et on va tous les supprimer (attention à ne pas supprimer le dossier front où on a déjà créé des composants).
On a aussi ces vues : Ce sont les layouts, la page d'accueil et le dashboard. Là aussi on va se débarrasser de tout ça ! Après ces différentes purges vous devriez n'avoir plus que ces vues : Vérifiez quand même que votre blog fonctionne encore ! On va aussi supprimer des assets générés pour Breeze (app.css et app.js) :Cinq composants
On va créer 5 composants pour mutualiser du code et simplifier les vues :
- une alerte pour le statut
- une alerte pour la liste des erreurs de validation
- un input pour l'email
- un input pour le mot de passe
- le bouton de soumission
@props(['status'])
@if ($status)
<div class="alert-box alert-box--info">
<p>{{ $status }}</p>
<span class="alert-box__close"></span>
</div>
@endif
Pour validation-errors :
@props(['errors'])
@if ($errors->any())
<div class="alert-box alert-box--error">
<div style="padding-bottom:1rem">@lang('Whoops! Something went wrong.')</div>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
<span class="alert-box__close"></span>
</div>
@endif
Pour input-email :
@props(['email' => ''])
<div>
<label for="email">@lang('Email')</label>
<input
id="email"
class="h-full-width"
type="email"
name="email"
placeholder="@lang('Your email')"
value="{{ old('email', $email) }}"
required
autofocus>
</div>
Pour input-password :
<div>
<label for="password">@lang('Password')</label>
<input
id="password"
class="h-full-width"
type="password"
name="password"
placeholder="@lang('Your password')"
required>
</div>
Et enfin pour submit :
@props(['title'])
<input class="btn--primary h-full-width" type="submit" value="@lang($title)">
La connexion
On va commencer par la page de connexion.
On va changer ainsi le code :@extends('front.layout')
@section('main')
<div class="row row-x-center s-styles">
<div class="column large-6 tab-12">
<!-- Session Status -->
<x-auth.session-status :status="session('status')" />
<!-- Validation Errors -->
<x-auth.validation-errors :errors="$errors" />
<h3 class="h-add-bottom">@lang('Login')</h3>
<form class="h-add-bottom" method="POST" action="{{ route('login') }}">
@csrf
<!-- Email Address -->
<x-auth.input-email />
<!-- Password -->
<x-auth.input-password />
<!-- Remember Me -->
<label class="h-add-bottom">
<input
id="remember_me"
type="checkbox"
name="remember_me"
{{ old('remember_me') ? 'checked' : '' }}>
<span class="label-text">@lang('Remember me')</span>
</label>
<x-auth.submit title="Login" />
<label class="h-add-bottom">
<a href="{{ route('password.request') }}">
@lang('Forgot Your Password?')
</a>
<a href="{{ route('register') }}" style="float: right;">
@lang('Not registered?')
</a>
</label>
</form>
</div>
</div>
@endsection
Avec l'url monblog.ext/login on obtient maintenant cet aspect :
C'est pas mal mais un chose me gêne : le formulaire est trop collé au footer. On va un peu espacer ça.
On ajoute un règle de style dans public.styles.css :
.s-styles {
padding-bottom: var(--vspace-4);
}
J'ai déjà ajouté cette classe dans la vue. Du coup c'est plus aéré :
Normalement on doit avoir une alerte en cas de problème :
Et en cas de d'authentification réussie vous tombez maintenant sur une erreur :
Ce qui est logique puisqu'on a supprimé la vue. On voudrait à présent une redirection sur l'accueil du blog. Ca se passe dans RouteServiceProvider, il suffit de changer la valeur de HOME :
public const HOME = '/';
Et ça doit être bon maintenant !
Mais ce qui serait encore mieux c'est de disposer d'un lien vers la page de connexion dans notre barre de navigation. Il faudrait également prévoir la possibilité de se déconnecter. On va compléter le code dans front.layout :
<ul class="s-header__nav">
...
@guest
<li {{ currentRoute('login') }}>
<a href="{{ route('login') }}">@lang('Login')</a>
</li>
@else
<li>
<form action="{{ route('logout') }}" method="POST" hidden>
@csrf
</form>
<a
href="{{ route('logout') }}"
onclick="event.preventDefault(); this.previousElementSibling.submit();">
@lang('Logout')
</a>
</li>
@endguest
</ul>
On a maintenant un lien pour la connexion :
Et quand on est connecté un lien pour se déconnecter :
L'enregistrement
On va s'intéresser à présent à la vue pour l'enregistrement :@extends('front.layout')
@section('main')
<div class="row row-x-center s-styles">
<div class="column large-6 tab-12">
<!-- Validation Errors -->
<x-auth.validation-errors :errors="$errors" />
<h3 class="h-add-bottom">@lang('Register')</h3>
<form class="h-add-bottom" method="POST" action="{{ route('register') }}">
@csrf
<!-- Name -->
<div>
<label for="name">@lang('Name')</label>
<input
id="name"
class="h-full-width"
type="text"
name="name"
placeholder="@lang('Your name')"
value="{{ old('name') }}"
required
autofocus>
</div>
<!-- Email Address -->
<x-auth.input-email />
<!-- Password -->
<x-auth.input-password />
<!-- Confirm Password -->
<div>
<label for="password_confirmation">@lang('Confirm Password')</label>
<input
id="password_confirmation"
class="h-full-width"
type="password"
name="password_confirmation"
placeholder="@lang('Confirm your Password')"
required>
</div>
<x-auth.submit title="Register" />
</form>
</div>
</div>
@endsection
On profite évidemment largement des composants qu'on a créés précédemment. On se retrouve avec un formulaire dans le même style :
La validation devrait fonctionner :On va également compléter la barre de navigation. mais dans un premier temps on ajoute une commande à Blade (dans AppServiceProvider) :
use Illuminate\Support\Facades\{ Blade, View };
...
public function boot()
{
...
Blade::if('request', function ($url) {
return request()->is($url);
});
}
On se sert de cette commande pour compléter le menu :
@guest
@request('register')
<li class="current">
<a href="{{ request()->url() }}">@lang('Register')</a>
</li>
@endrequest
<li {{ currentRoute('login') }}>
<a href="{{ route('login') }}">@lang('Login')</a>
</li>
@else
J'ai choisi de ne pas faire apparaître systématiquement ce lien d'enregistrement mais juste lorsqu'on affiche le formulaire qui est accessible à partir du formulaire de connexion :
Dès qu'on affiche la page d'enregistrement le lien apparaît dans le menu :Le renouvellement du mot de passe
La demande
Pour le renouvellement on va remplacer le code de la vue forgot-password :
@extends('front.layout')
@section('main')
<div class="row row-x-center s-styles">
<div class="column large-6 tab-12">
<!-- Session Status -->
<x-auth.session-status :status="session('status')" />
<!-- Validation Errors -->
<x-auth.validation-errors :errors="$errors" />
<p class="h-add-bottom">@lang('Forgot your password? No problem. Just let us know your email address and we will email you a password reset link that will allow you to choose a new one.')</p>
<form class="h-add-bottom" method="POST" action="{{ route('password.email') }}">
@csrf
<!-- Email Address -->
<x-auth.input-email />
<x-auth.submit title="Email Password Reset Link" />
</form>
</div>
</div>
@endsection
On va envoyer un email. Pour vos tests le plus efficace est d'utiliser un service comme Mailtrap. Il suffit de renseigner le fichier .env pour que ça fonctionne :
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=xxx
MAIL_PASSWORD=xxx
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=admin@monblog.fr
MAIL_FROM_NAME="${APP_NAME}"
On présente un message pour confirmer l'envoi :
Par défaut l'email se présente ainsi :
Pour le moment tout est en anglais mais mettra tout en français à la fin. Comme j'ai bien prévu dans le code la syntaxe adéquate il nous suffira de créer un fichier de traduction global en plus des fichiers de base (validation, pagination, mots de passe...).
Le renouvellement
Pour le renouvellement on va changer le code de la vue reset-password :
@extends('front.layout')
@section('main')
<div class="row row-x-center s-styles">
<div class="column large-6 tab-12">
<!-- Validation Errors -->
<x-auth.validation-errors :errors="$errors" />
<h3 class="h-add-bottom">@lang('Password reset')</h3>
<form class="h-add-bottom" method="POST" action="{{ route('password.update') }}">
@csrf
<!-- Password Reset Token -->
<input type="hidden" name="token" value="{{ $request->route('token') }}">
<!-- Email Address -->
<x-auth.input-email :email="$request->email" />
<!-- Password -->
<x-auth.input-password />
<!-- Confirm Password -->
<div>
<label for="password_confirmation">@lang('Confirm Password')</label>
<input
id="password_confirmation"
class="h-full-width"
type="password"
name="password_confirmation"
placeholder="@lang('Confirm your Password')"
required>
</div>
<x-auth.submit title="Reset Password" />
</form>
</div>
</div>
@endsection
Dans le formulaire l'email est déjà renseigné :
Là aussi la validation doit fonctionner :Si le mot de passe est bien renouvelé on renvoie sur la page de connexion avec un message :
Le renouvellent fonctionne bien mais je trouve dommage de ne pas avoir une indication de cette opération dans le menu. On va donc le compléter (front.layout) :
@guest
...
@request('forgot-password')
<li class="current">
<a href="{{ request()->url() }}">@lang('Password')</a>
</li>
@endrequest
@request('reset-password/*')
<li class="current">
<a href="{{ request()->url() }}">@lang('Password')</a>
</li>
@endrequest
@else
Ainsi on aura un repère dans le menu pendant cette opération :
Conclusion
Voilà on est à jour pour la partie authentification. Le frontend est maintenant bien avancé. Il nous reste peu de chose à code : le formulaire de contact, la partie CMS avec les pages et aussi les liens sociaux. Il nous faudra compléter notre base de données pour gérer tout ça.
Par bestmomo
Nombre de commentaires : 16