Il est de plus en plus évident que la TALL stack, dont j'ai déjà parlé dans cet article, se présente comme une sérieuse alternative aux approches classiques. On peut ne pas aimer la verbosité de Tailwind, et j'en fais partie, ou le mélange des genres de Livewire, et j'en fais encore partie, il faut reconnaître à ces technologies une redoutable efficacité.
J'ai déjà évoqué plusieurs fois Livewire dans le présent blog, une fois pour en faire une introduction, une autre fois pour découvrir un datatable fondé sur Livewire, et enfin une implémentation de FullCalendar avec le même Livewire.
Dans cette série d'articles je vous propose de faire une synthèse de tout ça avec un site très simplifié (on ne va gérer que la partie utilisateur et oublier l'administration du site) de réservation de gîtes avec l'utilisation de FullCalendar, de datatable et d'autres packages de Livewire. Le but est de voir comment organiser le codage avec ces nouvelles technologies. On oublie les contrôleurs et autres éléments classiques de Laravel pour utiliser des composants qui vivent leur vie à cheval entre le client et le serveur. C'est un peu dépaysant, mais on s'y habitue vite parce que le codage est rapide et très simplifié.
Dans ce premier article on va s'occuper principalement de l'intendance et on rentrera dans le vif du sujet dans le prochain.
Vous pouvez télécharger le code final de cet article ici.Installation
Laravel
On fait une nouvelle installation de Laravel :composer create-project laravel/laravel mesvacances --prefer-dist
On crée une base de données et on informe le fichier .env :
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=mesvacances
DB_USERNAME=root
DB_PASSWORD=
Breeze
On va utiliser Breeze pour l'authentification :composer require laravel/breeze --dev
php artisan breeze:install
npm install
npm run dev
Maintenant on a l'authentification en place et par la même occasion on a installé Tailwind.
Livewire
On installe aussi Livewire :composer require livewire/livewire
On a maintenant notre Laravel tout prêt !
Les données
homes
Pour notre site de réservation de gîtes on va avoir une première tables homes pour mémoriser les informations des gîtes :
php artisan make:model Home -ms
Dans la migration on supprime les timestamps et on prévoit ces colonnes :
public function up()
{
Schema::create('homes', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('text1');
$table->string('text2');
$table->string('text3');
$table->string('image');
});
}
Donc un titre, quelques textes de présentation et le lien vers une image (vous pouvez récupérer les images dans le dossier ZIP joint). Récupérez ces trois images en créant le dossier :
Dans le modèle Home on précise qu'on n'a plus les timestamps et on renseigne $fillable :
public $timestamps = false;
protected $fillable = ['id', 'text1', 'text2', 'text3', 'image'];
Pour la population (HomeSeeder) on prévoit deux gîtes :
public function run()
{
Home::insert([
[
'id' => 1,
'title' => 'Les rondins du lac',
'text1' => 'Un emplacement de rêve',
'text2' => 'Une vue inégalée',
'text3' => 'Un calme absolu',
'image' => 'gite1.jpg',
],
[
'id' => 2,
'title' => 'L\'avenir est déjà là',
'text1' => 'Une architecture unique',
'text2' => 'Une piscine langoureuse',
'text3' => 'Une lumière enchanteresse',
'image' => 'gite2.jpg',
],
]);
}
events
On crée ensuite la table des réservations :
php artisan make:model Event -ms
Là aussi on oublie les timestamps :
public function up()
{
Schema::create('events', function (Blueprint $table) {
$table->id();
$table->date('start');
$table->date('end');
$table->date('limit');
$table->boolean('rented')->default(false);
$table->foreignId('user_id')->constrained();
$table->foreignId('home_id')->constrained();
});
}
On a ces colonnes :
- start : date de départ de la réservation
- end : date de la réservation
- limit : date limite de paiement
- rented : indique si la réservation est effectuée
- user_id : clé étrangère pour les utilisateurs (un utilisateur a plusieurs réservations)
- home_id : clé étrangère pour les gîtes (un gîte a plusieurs réservations)
public $timestamps = false;
protected $fillable = ['user_id', 'home_id', 'start', 'rented', 'end', 'limit'];
Pour la population (EventSeeder) on prévoit 6 réservations :
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\Event;
use Illuminate\Support\Str;
use Carbon\Carbon;
class EventSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Event::insert([
[
'user_id' => 1,
'home_id' => 1,
'rented' => false,
'limit' => Carbon::now()->addDays(4)->toDateTimeString(),
'start' => Carbon::now()->addDays(5)->toDateTimeString(),
'end' => Carbon::now()->addDays(6)->toDateTimeString(),
],
[
'user_id' => 1,
'home_id' => 1,
'rented' => true,
'limit' => Carbon::now()->addDays(3)->toDateTimeString(),
'start' => Carbon::now()->addDays(10)->toDateTimeString(),
'end' => Carbon::now()->addDays(11)->toDateTimeString(),
],
[
'user_id' => 2,
'home_id' => 1,
'rented' => true,
'limit' => Carbon::now()->addDays(9)->toDateTimeString(),
'start' => Carbon::now()->addDays(16)->toDateTimeString(),
'end' => Carbon::now()->addDays(18)->toDateTimeString(),
],
[
'user_id' => 1,
'home_id' => 2,
'rented' => false,
'limit' => Carbon::now()->addDays(4)->toDateTimeString(),
'start' => Carbon::now()->addDays(5)->toDateTimeString(),
'end' => Carbon::now()->addDays(6)->toDateTimeString(),
],
[
'user_id' => 1,
'home_id' => 2,
'rented' => true,
'limit' => Carbon::now()->addDays(4)->toDateTimeString(),
'start' => Carbon::now()->addDays(11)->toDateTimeString(),
'end' => Carbon::now()->addDays(15)->toDateTimeString(),
],
[
'user_id' => 2,
'home_id' => 2,
'rented' => true,
'limit' => Carbon::now()->addDays(9)->toDateTimeString(),
'start' => Carbon::now()->addDays(16)->toDateTimeString(),
'end' => Carbon::now()->addDays(17)->toDateTimeString(),
],
]);
}
}
payments
Pour finir on ajoute une table pour mémoriser les paiements :php artisan make:model Payment -m
Ça sera assez symbolique parce qu'on va se contenter d'une clé étrangère pour faire le lien avec les réservations :
public function up()
{
Schema::create('payments', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->foreignId('event_id')->constrained();
});
}
On ne prévoit pas de population pour les paiements.
Par contre, il faut renseigner DatabaseSeeder pour activer les seeders qu'on a créés et on va par ailleurs utiliser le factory des users pour en créer 5 :
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\User;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
User::factory()->count(5)->create();
$this->call([HomeSeeder::class,]);
$this->call([EventSeeder::class,]);
}
}
On finit en créant les tables et en les remplissant :
php artisan migrate --seed
Vérifiez dans la base que vous avez les 7 tables :
Et aussi qu'elles sont bien remplies.La page d'accueil
Sue la page d'accueil du site on veut une présentation générale, une description de chaque gîte avec sa photo, un calendrier pour chacun d'eux pour effectuer les réservations. Pour le moment on va oublier les calendriers et crée l'infrastructure globale.
Contrôleur et route
Pour ouvrir la page d'accueil en envoyant les informations des gîtes on crée un contrôleur :
php artisan make:controller HomeController --invokable
Avec ce simple code :
<?php
namespace App\Http\Controllers;
use App\Models\Home;
class HomeController extends Controller
{
public function __invoke()
{
$homes = Home::all();
return view('home', compact('homes'));
}
}
On ajoute la route (en supprimant la route de base pour la racine du site) :
use App\Http\Controllers\HomeController;
Route::get('/', HomeController::class)->name('home');
La vue
On ajoute la vue : Vous pouvez aussi supprimer dashboard et welcome qui ne nous serviront pas.Pour pas me compliquer la vie, je suis parti d'un template gratuit que j'ai allégé et adapté à la situation. Comme le code est assez long je ne le copie pas ici, vous pouvez récupérer le fichier dans le ZIP.
On a une partie supérieure avec titre, illustration, bouton de connexion ou inscription :
Ensuite je me suis un peu amusé avec du texte est des images SVG :
On a ensuite les deux gîtes, voici par exemple le premier :
En bas de page, il y a quelques liens classiques. On ajoutera les calendriers dans le prochain article.Les pages de l'authentification
Pour le moment on a les pages standards qui arrivent avec Brezze. On va un peu les customiser pour les faire cadrer avec l'aspect du site. D'autre part tout y est en anglais alors on va arranger ça.
Les langues
Déjà dans config.app on change la locale :'locale' => 'fr',
Ensuite on va chercher les fichiers de langue ici et on copie le dossier du français au bon endroit :
D'autre part allez récupérer dans le ZIP le fichier JSON qui comporte plein de traductions pour l'ensemble du projet :
Les vues
Pour les vues on a un fond grisâtre et le logo de Laravel :
Pour le logo ça se passe dans ce composant :
On change le SVG :<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" {{ $attributes }}>
<path
d="M312.638,378.443c-1.499-5.581-3.861-13.796-6.783-23.958c-49.456-171.839-45.944-205.524-39.593-210.25
c20.202-5.073,52.617,39.627,65.101,62.07c1.532,2.742,4.48,4.188,7.641,4.236c3.145-0.169,5.927-2.105,7.165-5.002
c21.226-49.524-20.798-92.038-41.758-109.306c16.697-6.315,30.883-1.935,31.556-1.724c3.46,1.169,7.29-0.105,9.387-3.105
c2.093-3.01,1.96-7.024-0.327-9.889C316.46,45.814,256.875,49,232.246,52.113c3.226-15.468,12.98-25.565,13.077-25.661
c2.625-2.619,3.177-6.675,1.347-9.909c-1.823-3.226-5.565-4.863-9.19-3.935c-26.855,6.71-48.282,23.339-57.197,31.111
l-44.46-22.232c-2.992-1.494-6.573-1.048-9.105,1.145c-2.524,2.194-3.48,5.685-2.423,8.853l13.44,40.325
c-70.815,14.895-71.669,96.587-71.669,97.452c0,4.242,3.218,7.798,7.444,8.218c4.181,0.363,8.077-2.435,8.911-6.597
c3.573-17.865,24.214-29.226,43.964-35.807c-32.673,46.339-3.464,124.081-1.964,127.992c1.496,3.893,5.669,6.048,9.718,5.04
c4.048-1.016,6.706-4.887,6.186-9.032c-6.061-48.486,48.899-88.744,70.169-102.379c18.526,55.411,26.693,185.076,28.565,219.262
C103.701,379.774,0,429.102,0,491.359c0,4.564,3.698,8.292,8.258,8.292h495.484c4.56,0,8.258-3.728,8.258-8.292
C512,435.345,428.055,389.792,312.638,378.443z M222.298,141.236c-0.915-2.139-2.689-3.79-4.887-4.557
c-2.194-0.742-4.613-0.558-6.657,0.557c-3.081,1.685-60.786,33.702-80.718,81.887c-5.214-31.718-4.552-74.47,30.56-92.026
c3.577-1.79,5.359-5.885,4.226-9.724c-1.129-3.831-4.827-6.3-8.831-5.873c-2.29,0.258-40.548,4.766-66.637,23.322
c0.569-1.532,1.181-3.081,1.847-4.637c11.073-25.831,30.706-40.482,58.355-43.554c2.48-0.274,4.702-1.661,6.044-3.758
c1.343-2.105,1.665-4.696,0.879-7.064l-10.214-30.639l31.718,15.863c3.193,1.607,7.024,0.97,9.532-1.548
c0.173-0.167,13.056-12.911,32.153-22.572c-2.831,7.01-4.96,15.451-4.96,24.992c0,2.476,1.109,4.815,3.024,6.389
c1.911,1.565,4.423,2.168,6.855,1.71c0.637-0.145,53.669-10.405,88.681,7.03c-8.77,1.236-18.79,4.349-28.819,11.034
c-2.298,1.532-3.678,4.113-3.678,6.869c0,2.758,1.379,5.339,3.678,6.871c0.605,0.403,53.181,36.043,50.79,79.317
c-15.488-23.194-44.968-59.928-72.988-52.903c-3.113,0.774-7.5,2.877-10.722,8.468c-14.141,24.54,5.145,106.637,38.448,222.363
c2.017,7.008,3.757,13.05,5.13,17.946c-12.726-0.845-25.783-1.284-39.11-1.284c-0.135,0-0.268,0-0.402,0.002
C253.685,339.651,244.688,193.471,222.298,141.236z M17.383,483.135C27.907,433.586,132.899,392.296,256,392.296
s228.093,41.29,238.617,90.839H17.383z"
/>
</svg>
Ca fait déjà plus vacances :
On va maintenant homogénéiser le fond avec celui du site. On va commencer par enlever le gris du fond, ça se passe dans le composant auth-card.blade.php :
<div class="min-h-screen flex flex-col sm:justify-center items-center pt-6 sm:pt-0">
...
Ensuite on met le dégradé dans le layout guest.blade.php :
<body class="bg-gradient-to-r from-indigo-900 to-indigo-300">
On a bien le dégradé mais notre logo doit changer de couleur pour être visible :
Malheureusement la couleur du texte pour ce logo est définie dans toutes les vues de l'authentification, ce qui est un peu dommage :
<x-application-logo class="w-20 h-20 fill-current text-gray-500" />
On doit donc les passer une par une pour changer la couleur :
<x-application-logo class="w-20 h-20 fill-current text-white" />
Et ça devrait être bon :
On peut finir en faisant du ménage dans les vues :
Conclusion
C'était un peu laborieux mais maintenant on va pouvoir utiliser Livewire pour ajouter les calendriers pour les deux gîtes dans le prochain article.
Par bestmomo
Nombre de commentaires : 7