Aller au contenu

1. Projet ToDo Initialisation⚓︎

Dans ce TP nous allons réaliser une application web, « TODO » ou aussi appelé liste de tâches.
Une TODO List est un procédé qui se veut simple et efficace pour gérer les tâches d'un projet. Ces tâches peuvent être indépendantes ou devoir, au contraire, être accomplies dans un certain ordre. Ces tâches pourront également être catégorisées (pro, perso, famille, ...).
Voilà la liste des fonctionnalités de l’application que l'on va créer :
- Lister les tâches.
- Ajouter une tâche.
- Marquer comme terminé une tâche.
- Suppression d'une tâche.

Technologie

Dans ce TP nous allons utiliser les technologies suivantes :
- Laravel (Framework PHP)
- ORM Eloqent
- Bootstrap 4 (Framework HTML / CSS / JS)
- NodeJS (Utilisation de Webpack)

1.1 Initialiser le projet⚓︎

La première étape lors d'un projet Laravel est la création de la structure avec une simple ligne de commande, dans notre cas : ✋ Attention, le projet va être créé dans le dossier todo2024 dans le dossier courant.

📋 Texte
composer create-project --prefer-dist laravel/laravel todo2024 

Question

Où sont les librairies ?

Les vendor représentent les bibliothèques tierce qui sont nécessaires au projet mais qui sont des ressources externe, c'est notamment le nom utiliser par le dossier ou sont stocker les dépendances téléchargées via le package manager le plus utiliser de php : composer

Question

Quel est l'intérêt à votre avis d'utiliser un outil pour initialiser un projet ?

Gain de temps, d’efficacité, non redondance des taches, automatisation de ce qui peut l’être.

Configurer le projet

Configurer le projet : .env
Le projet qui vient d'être créé est « générique » c'est à dire qu'il ne possède aucune personnalisation et peut donc servir de base quelques soit votre développement.
La première étape est donc d'éditer le fichier .env pour configurer les options de base de votre projet tel que :
- Le nom : ToDoList
- Le type de base de données
- …

Sécurité

🚧 Créer une base de données todo2024 sous MySQL
💥 créer un user de base de données à périmètre restreint pour votre application
↪️ Mettre à jour le .env

🐬 SQL
CREATE USER 'nouveau_utilisateur'@'%' IDENTIFIED BY 'mot_de_passe';
GRANT ALL PRIVILEGES ON `todo2024`.* TO 'nouveau_utilisateur'@'%s'; 
FLUSH PRIVILEGES

Le reste du fichier .env : Nous n'allons pas toucher aux autres paramètres mais certains sont tout de même intéressants. Je vous laisse donc consulter la documentation en ligne de laravel.

1.2 Conception de la base de données⚓︎

modélisation Todo

Ce qui donnera le calcul du MPD suivant :
TODO (id, texte, termine,important timestamp)
CATEGORIE(idcat, libelle)
CATEGORIES_TODOS (id,idcat)

1.2.1 Création de la « migration »⚓︎

Laravel utilise un ORM pour manipuler la base de données. Pour rappel un ORM est Un mapping objet-relationnel (en anglais object-relational mapping) est une technique de programmation informatique qui crée l'illusion d'une base de données orientée objet à partir d'une base de données relationnelle en définissant des correspondances entre cette base de données et les objets du langage utilisé.
L'ORM utilisé par Laravel est Eloquent, il est à la fois puissant et relativement simple. Autrement dit avec un ORM dans la plus part des cas vous n'écrivez plus de requête SQL mais vous manipulez des objets représentant la base de données.

Comme pour la création du projet, la création de la définition de vos table va se faire via une requête dans votre terminal en utilisant Artisan.

📋 Texte
php artisan make:migration create_todos_table --create=todos
📋 Texte
INFO  Migration [C:\wamp64\www\todo2024\database\migrations/2023_11_21_084423_create_todos_table.php] created successfully.

L’option --create=todos dans la première méthode permet d’indiquer le nom du modèle de la table à créer.
La commande vient de créer un nouveau fichier dans le dossier database/migration. Dans mon cas le fichier se nomme : /todo2024/database/migrations/2023_11_21_084423_create_todo_table.php

contenu du fichier
PHP
<?php

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

    return new class extends Migration
    {
        /**
         * Run the migrations.
         */
        public function up(): void
        {
            Schema::create('todos', function (Blueprint $table) {
                $table->id();
                $table->timestamps();
            });
        }

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

✋ Le contenu du fichier créé est fictif, il est là pour illustrer comment travailler. Nous allons le modifier pour mettre les informations relatives à notre table.

Questions

Il y a d'autres fichiers dans votre répertoire de migration. A quoi servent ils ? migration)

  • table users : c’est une migration de base pour créer une table des utilisateurs,
  • table password_resets : c’est une migration liée à la précédente qui permet de gérer le renouvellement des mots de passe en toute sécurité.

Questions

Quels sont les champs par défaut dans la création d’une table simple ?

Id et timestamp

PHP
$table->integer('id');
$table->timestamps();
les deux champs ont une syntaxe particulière. Ce sont des fonctions propres à Laravel. Il en existe beaucoup dans la documentation.

Nous allons définir notre schéma pour y ajouter les 3 colonnes qui nous serons utiles texte, termine et important. L'ORM étant une librairie objet, la définition de nouveaux champs se fait via une méthode, dans notre cas :

📋 Texte
```php
$table->integer('id');
$table->string('texte');
$table->boolean('termine')->default(0);
$table->boolean('important')->default(0);
#Déclaraction de la clé primaire
$table->primary('id');
```

Ajouter les champs dans la méthode up du fichier.

fonction up
PHP
public function up(): void
{
    Schema::create('todos', function (Blueprint $table) {
        $table->integer('id')
        $table->string('texte');
        $table->boolean('termine')->default(0);
        $table->boolean('important')->default(0);
        #Déclaraction de la clé primaire
        $table->primary('id');
        $table->timestamps();
    });
}

1.2.3 Création en base⚓︎

Maintenant que le script est terminé, nous allons indiquer à Laravel d'effectuer « la migration » c'est-à-dire de transformer votre définition PHP en instruction SQL pour créer réellement la base de données.

💥

Remplacer dans config/database.php

PHP
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
#Par 
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
PHP
'engine' => null,
#par
'engine' => 'InnoDB',

Checklist

  • Terminal : C:\wamp64\www\todo2024>
  • base de données todo2024 créée
  • user base de donnée créé
  • .env mis à jour
  • métode up de la migration mise à jour

Retour dans la ligne de commande :

📋 Texte
C:\wamp64\www\todo2024>php artisan migrate:fresh  

  Dropping all tables ..................................................................................................... 146ms DONE

   INFO  Preparing database.

  Creating migration table ................................................................................................. 16ms DONE  

   INFO  Running migrations.

  2014_10_12_000000_create_users_table ..................................................................................... 21ms DONE  
  2014_10_12_100000_create_password_reset_tokens_table ..................................................................... 13ms DONE  
  2019_08_19_000000_create_failed_jobs_table ............................................................................... 22ms DONE  
  2019_12_14_000001_create_personal_access_tokens_table .................................................................... 21ms DONE  
  2023_11_21_084423_create_todo_table ...................................................................................... 21ms DONE  
Vérifier votre console et votre travail dans phpMyAdmin.

A faire

Faites la même chose avec les tables CATEGORIES et CATEGORISE Sachant que CATEGORISE possède également deux clés étrangères.

La difficulté ici est de créer la bonne relation entre clés primaires et clés étrangères.
Pour rappel, en Base de données, on ne peut référencer un champ en clé étrangère vers une clé primaire que si les deux champs sont exactement du MEME type. or ici, si on utilise id() pour catégorie, on aura du mal à construire la clé étrangère dans la table CATEGORISE

PHP
public function up(): void
{
    Schema::create('categories', function (Blueprint $table) {
        $table->integer('id');
        $table->string('libelle');
        $table->primary('id');
        $table->timestamps();
    });
}
public function up(): void
{
    Schema::create('categories_todos', function (Blueprint $table) {
        $table->integer('categories_id');
        $table->integer('todos_id');

        $table->foreign('categories_id')->references('id')->on('categories');
        $table->foreign('todos_id')->references('id')->on('todos');

        $table->primary(['categories_id', 'todos_id']);
        $table->timestamps();
    });
}

Votre base de données est maintenant prête à être utilisée. Vous pouvez aller voir le contenu grâce à phpMyAdmin. Verifier votre structures et vos contraintes.

Cours

L’ORM eloquent permet de créer une correspondance entre les classes PHP et la base de données. On peut créer une classemaTable associée à une table maTable. On pourra accéder aux colonnes de la table au travers des propriétés de la classe et bénéficier de méthodes pour charger un élément ou une liste d’éléments, enregistrer, mettre à jour …

Exemple

Exemple de commande pour manipuler facilement des retours de requêtes en base de données. Tout est Objet !

PHP
$user = User ::find(5) ;
Echo $user->name ;
$user->age=32 ;
$user->save() ;

piloter la création de la base

Il est rare de réussir sa migration du premier coup. Il faut donc lancer plusieurs fois la migration. En utilisant fresh, vous aurez une erreur, puisque vos tables existent déjà.
Mais vous avez d'autres commandes à disposition :
▶️ Réinitialiser les migrations (rollback de toutes les migrations) : php artisan migrate:reset
▶️ Migrer et réinitialiser en même temps : php artisan migrate:refresh
▶️ Voir l'historique des migrations exécutées : php artisan migrate:status
▶️ Créer une nouvelle migration de modification de table : php artisan make:migration add_nom_de_la_colonne_to_nom_de_la_table --table=nom_de_la_table

1.3 Le modèle⚓︎

Maintenant que nous avons fait le script de création / migration, nous allons définir notre model.

📋 Texte
$ php artisan make:model Todos
▶️ La commande va créer le fichier Todos.php dans le dossier app/.

Ajouter dans la class Todos.php :

📋 Texte
```php
protected $fillable = ['texte', 'termine', 'important'];
```

⚠️ Cette propriété est optionnelle, elle permet vous autorisera plus tard à faire du « mass-assignment » c'est à dire à créer un objet « Todos » depuis par exemple le POST HTTP.

A faire

Faites la même chose avec les tables CATEGORIE

Inutile d'ajouter des attributs fillable pour cette table puisque nous ne créerons pas de catégorie via l'interface Web.

1.4 Le controller⚓︎

1.4.1 Création du controller⚓︎

Maintenant que nous avons la migration et le model de notre base de données, nous allons créer le controller. Pour rappel le controller va faire « le lien » entre la base de données et les appels HTTP. C’est ici que nous allons mettre la logique métier de notre application.

Rôle

La tâche d'un contrôleur est de réceptionner une requête (qui a déjà été triée par une route) et de définir la réponse appropriée, rien de moins et rien de plus. Voici une illustration du processus : controller illustration

  • Les contrôleurs servent à réceptionner les requêtes triées par les routes et à fournir une réponse au client.
  • Artisan permet de créer facilement un contrôleur.
  • Il est facile d'appeler une méthode de contrôleur à partir d'une route.
  • On peut nommer une route qui pointe vers une méthode de contrôleur.

▶️ Pour commencer nous allons créer « la structure de base » de notre controller.

📋 Texte
php artisan make:controller TodosController
php artisan make:controller CategoriesController

Le fichier TodosController.php viens d'être créé dans le chemin suivant app/Http/Controllers/.

⚠️ Dans la version Laravel 10, les controllers sont créés automatiquement (toujours dans app/Http/Controllers/).

Notre code est prêt. Nous allons créer les méthodes permettant la manipulation de notre base de données tout en répondant à nos problématique d'interface (liste, création, terminer, suppression➡️CRUD).

Nous allons écrire une méthode pour chaque action. Avec les différentes conditions nécessaires au bon fonctionnement de l'application.

1.4.2 La méthode « Liste »⚓︎

La méthode liste est certainement la plus simple, nous allons faire appel à la méthode all() de Eloquent. ✋ Dans un premier temp nous n'allons pas integrer la base de données, mais uniquement définir notre méthode. Et tester l'interface de notre projet.

PHP
public function liste(){
    return "Liste";
}
▶️ Nous allons tester la route / (page d'acccueil du projet), pour ça nous allons remplacer le contenu du fichier routes/web.php par :
PHP
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TodosController;

Route::get('/', [TodosController::class, 'liste']);

serveur de test

📋 Texte
php artisan serve
🌐 http://localhost:8000/

Vous pouvez relancer votre serveur de test, vous devez maintenant voir afficher « Liste ».

1.5 Créer les templates⚓︎

1.5.1 Structure⚓︎

Nous avons donc maintenant :
- [ ] La structure Laravel.
- [ ]La définition de notre base de données.
- [ ] Une page d'accueil valide
- [ ] Un controller un peu vide

Nous allons donc pouvoir commencer la création des vues. L'organisation du code est quelques choses d'important, elle n'est pas à négliger. Un code organisé est un code agréable à rédiger. Notre vue va être découpée en 3 partie :

découpage

Pourquoi le découpage en « 3 templates » est-il important ?

On retrouve les besoins de découpage que l’on pouvait avoir avec un PHP brut avec les fonctions include ou require. On peut vouloir inclure une portion de code blade pour gérer les affichages d’erreurs liés aux formulaires dans chaque page qui en possèdera un. Ici on mutualisera le code statique commun à plusieurs pages.

Quelle est l'avantage pour le développeur ?

Réutilisation de code, maintenabilité.

1.5.2 Le template principal⚓︎

Nous allons commencer par définir notre « Template principal » celui-ci va contenir l'ensemble des éléments partagés sur toutes nos pages à savoir :
• Les JS
• Les CSS
• La structure commune

template.blade.php
PHP
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="csrf-token" content="{{ csrf_token() }}">

        <title>@yield('title')</title>

        <link href="{{ asset('css/app.css') }}" rel="stylesheet">
        <script type="text/javascript" src="{{ asset('js/app.js') }}"></script>
    </head>
    <body>
        <nav class="navbar navbar-expand-md navbar-dark bg-dark">
            <a class="navbar-brand" href="#">Ma Todo List</a>
        </nav>

        @yield('content')

    </body>
</html>
Pourquoi le fichier est-il nommé ….blade.php ?

Il utilise le moteur de template blade. Contrairement aux autres moteurs de templates PHP populaires, Blade ne vous empêche pas d'utiliser du code PHP simple dans vos vues. En fait, toutes les vues Blade sont compilées dans du code PHP brut et mises en cache jusqu'à ce qu'elles soient modifiées, ce qui signifie que Blade n'ajoute pratiquement aucune surcharge à votre application.

À quoi correspond {{ asset('…') }} ?

The asset function generates a URL for an asset using the current scheme of the request (HTTP or HTTPS):

PHP
    $url = asset('css/style.css ');
essaiera de charger /mon-site/ma/route/web/web/css/style.css

À quoi correspond la directive « yield »? En quoi est-ce très important ?

Mot clé permet de déterminer la partie ou placé le code à sustituer.
Il permet de gérer l’héritage et l’inclusion de modèle.

Est-il possible de définir une « zone » où d'autre ressources JS/CSS seront insérées lors de l'exécution ?

Voir la documentation Blade Blade propose un système pour ajouter des éléments de plusieurs endroits dans une pile avant l’affichage. Il faut utiliser les directives @push, @endpush, @stack.

1.5.3 Composant VITE⚓︎

petit aparté pour détailler l'utilisation des assets front-end (JavaScript / CSS) dans le cadre de Laravel. Lorsque l'on commence à travailler sur du JavaScript on a très rapidement besoin d'outils comme des bundlers pour travailler efficacement. Malheureusement ces outils sont souvent pensés pour des sites web statiques et l'intégration avec une application backend n'est pas forcément évident.

Lors de son installation Laravel dispose déjà d'une configuration permettant d'utiliser le bundler Vite avec un fichier package.json pré-rempli.

💥 Installer au préalable node.js ici

📋 Texte
composer require laravel/breeze --dev
php artisan breeze:install vue
npm install
npm install --save-dev vite laravel-vite-plugin
npm install --save-dev @vitejs/plugin-vue
vite

On trouve aussi un nouveau fichier de configuration Config VITE

1.5.4 Installation de Bootstrap 5⚓︎

📋 Texte
composer require laravel/ui
npm i --save bootstrap @popperjs/core
npm install bootstrap-icons
npm install
npm run build
dans app.js, ajouter
PHP
import './bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap-icons/font/bootstrap-icons.css';
import '@popperjs/core';

Dans votre template, ajouter dans le head la ligne @vite(['resources/js/app.js'])

👀 tester

pour tester vos manips, ajouer du code bootstrap dans votre template. - [ ] Mettre en commentaire la route vers le controller Todo - [ ] Créer une route vers la vue template Route :: view ('/test', 'template'); - [ ] Dans le template, mettre mettre le code ci dessous contenant du bootstrap

PHP
<nav class="navbar navbar-expand-md navbar-dark bg-dark">
    <a class="navbar-brand" href="/">Ma Todo List</a>
    <a class="navbar-brand btn btn-primary" href="liste"><i class="bi bi-app"></i>Liste</a>

    <a class="navbar-brand btn btn-danger" href="compteur">Compteur</a>
</nav>

1.6 Liste des todos⚓︎

1.6.1 Le template Home⚓︎

Maintenant que nous avons défini notre template de base nous allons pouvoir définir notre page principale, la page « liste des todos ». Une fois terminée celle-ci va ressembler à :

page d'accueil ToDo

Avant de commencer la réalisation de ce template, regardons ce que l'on peut y voir :
- Un formulaire « form »
- Une « liste »

Nous allons donc avoir besoin de composant bootstrap. Première étape regarder la documentation de bootsrap !

Quels composants (components) allons-nous avoir besoins ?

Gestion des messages d’erreur pour gérer la saisie dans le formulaire

Est-ce que ce sont les seuls ?

Définition du template « Liste » / « Home »

Nous allons créer un 2nd template celui qui va être chargé d'afficher la liste des todos. Créér un nouveau fichier resources/views/home.blade.php et y mettre le contenu suivant :

home.blade.php
PHP
@extends("template")

@section("title", "Ma Todo List")

@section("content")
<div class="container">
    <div class="card">
        <div class="card-body">
            <!-- Action -->
            <form action="{{ route('todo.save') }}" method="POST" class="add">
                @csrf <!-- <<L'annotation ici ! -->
                <div class="input-group">
                    <span class="input-group-addon" id="basic-addon1"><span class="oi oi-pencil"></span></span>
                    <input id="texte" name="texte" type="text" class="form-control" placeholder="Prendre une note..." aria-label="My new idea" aria-describedby="basic-addon1">
                    @if (session('message'))
                        <p class="alert alert-danger">{{ session('message') }}</p>
                    @endif
                </div>
                <div class="priority-choice">
                    Importance : 
                    <input type="radio" name="priority" id="lowpr" value="0" checked><label for="lowpr"><i class="bi bi-reception-1"></i></label>
                    <input type="radio" name="priority" id="highpr" value="1"><label for="highpr"><i class="bi bi-reception-4"></i></label>
                    <button type="submit" class="btn btn-primary"><i class="bi bi-save"></i></button>
                </div>
            </form>

            <!-- Liste -->
            <ul class="list-group">
                @forelse ($todos as $todo)
                    <li class="list-group-item">
                        <!-- Affichage de la priorité -->
                        @if ($todo->important == 0)
                            <i class="bi bi-reception-1"></i>
                        @elseif ($todo->important == 1)
                            <i class="bi bi-reception-4"></i>
                        @endif
                        <!-- Affichage du texte -->
                        <span>{{ $todo->texte }}</span>
                        <!-- Action à ajouter pour Terminer et supprimer -->
                        @if ($todo->termine === 0)
                            <!-- Si un ToDo n'est pas terminé, Action à ajouter pour terminer -->
                            <a href="{{ route('todo.done', ['id' => $todo->id]) }}" class="btn btn-success"><i class="bi bi-check2-square"></i></a>
                            <!--<button class="btn btn-primary btn-lg"><span class="fa fa-user"></span><br>Terminer</button>-->
                        @elseif ($todo->termine === 1)
                            <!-- Si un ToDo est terminé, Action à ajouter pour supprimer -->
                            <a href="{{ route('todo.delete', ['id' => $todo->id]) }}" class="btn btn-danger"><i class="bi bi-trash3"></i></i></a>
                            @if (session('validation'))
                                <p class="alert alert-success">{{ session('validation') }}</p>
                            @endif
                        @endif
                        @if ($todo->important == 0)
                            <!-- Action à ajouter pour monter la priorité -->
                            <a href="{{ route('todo.raise', ['id'=> $todo->id]) }}"><i class="bi bi-arrow-up-circle"></i></a>
                        @elseif ($todo->important == 1)
                            <!-- Action à ajouter pour descendre la priorité -->
                            <a href="{{ route('todo.lower', ['id' => $todo->id]) }}"><i class="bi bi-arrow-down-circle"></i></a>
                        @endif
                    </li>
                @empty
                    <li class="list-group-item text-center">C'est vide !</li>
                @endforelse
            </ul>
        </div>
    </div>
</div>
@endsection

tip

Vous n'aurez pas besoin de tout le contenu du home.blade.php dans un premier temps.
Je vous conseille de mettre de côté ce code et de dans le home.blade.php de supprimer de :

PHP
<!-- Action à ajouter pour Terminer et supprimer -->
@if ($todo->termine === 0)
à
PHP
    @elseif ($todo->important == 1)
    <!-- Action à ajouter pour descendre la priorité -->
    <a href="{{ route('todo.lower', ['id' => $todo->id]) }}"><i class="bi bi-arrow-down-circle"></i></a>
@endif

@extends ? À quoi sert cette directive, pourquoi « template »?

Modifier le titre affiché dans la barre.

À quoi correspond le @forelse … @empty … @endforelse?

Boucler sur la collection de Todos et afficher chaque Todo

Recap

Nous avons :
- Le modele.
- Le contrôleur.
- Les templates (template et home).
Il faut maintenant assembler l'ensemble pour que votre page s'affiche lors d'une requête HTTP.

1.6.2 Création des routes⚓︎

La définition des routes se fait dans le fichier routes/web.php,
décommenter Route::get('/', [TodosController::class, 'liste'])->name('todo.liste');

À quoi correspond la notation TodosController@liste ?

Lien vers le controller Todos

👀 Tester Vous voyez « Liste » ? C'est 🆗

1.6.3 Affichage de la liste⚓︎

On va modifier la méthode liste() pour qu'elle appelle la bonne vue ici home et qu'elle aille chercher la collection des todos en base :

Code de la fonction liste
PHP
use App\Models\Todos;
//Liste
public function liste()
{
    return view("home", ["todos" => Todos::all()]);
}
👀 Tester
  • Créer un todo dans la base de donnée ...
    🔂 Rafraichissez la page, vous devez maintenant voir votre texte 🎉

1.7 Sauvegarde du formulaire et enregistrement en base⚓︎

1.7.1 céer la fonction Save dans le controleur⚓︎

Pour utiliser les fonctionnalités Eloqent, vous pouvez consulter la documentation ici.

fonction save
PHP
 public function saveTodo(Request $request){

    $texte = $request->input('texte');

    if($texte){
        $todo = new Todos();
        $todo->texte = $texte;
        $todo->termine = 0;
        $todo->Important = 0;
        $todo->save();

        return redirect()->route('todo.liste');
    } else{
        return redirect()->route('todo.liste')->with('message', "Veuillez saisir une note à ajouter");
    }     
}

Vous prendrez le temps de remarquer que ce code gère les messages d'erreur avec Bootstrap.
On "attrape" l'erreur en testant le champ texte, qui doit ici être non vide et on ajoute un élément à la route. Element qui sera mappé avec la vue home et plus précisement avec le champ message

PHP
@if (session('message'))
    <p class="alert alert-danger">{{ session('message') }}</p>
@endif
Il manque encore un élément pour finaliser ce besoin : La route.
Il faut ajouter le lien vers la fonction saveTodo du controleur.

PHP
Route::post('/action/add', [TodosController::class, 'saveTodo'])->name('todo.save');
et encore faut il appeler cette route lorsque l'on clique sur le bouton "Save" ! Vérifier dans la vue home que vous ayez bien l'appel à votre route.

PHP
<form action="{{ route('todo.save') }}" method="POST" class="add">

Erreur à traiter

Il manque le champ 'id' dans la requete d'insertion.

Il faut passer le champ id en autoIncrément et relancer le fresh de migration.

PHP
$table->integer('id')->autoIncrement();
#$table->primary('id');
Dans ce cas, laravel créé un index sur le champ id, il devient inutile de le déclarer en primary key. Mais dans la base de donnée, le champ est bien clé primaire.

1.8 User Story⚓︎

1.8.1 User story 1 : save Todo : traiter le champ Important "Priorité haute/faible"⚓︎

▶️ Adaptez votre Controleur pour prendre en compte le champ Important.

solution

Modifier la fonction "Save" du contrôleur

PHP
 public function saveTodo(Request $request){
    $texte = $request->input('texte');
    $button = $request->input('priority');

    if($texte){
        $todo = new Todos();
        $todo->texte = $texte;
        $todo->termine = 0;
        #Gestion du bouton Important
        if($button=='1'){
            $todo->Important = 1;
        } elseif($button=='0'){
            $todo->Important = 0;
        }
        $todo->save();
        return redirect()->route('todo.liste');
    } else{
        return redirect()->route('todo.liste')->with('message', "Veuillez saisir une note à ajouter");
    }

}

1.8.2 User story 1 : Baisser l'importance d'un toDo.⚓︎

Besoin : A la saisie, on peut choisir l'importance d'un Todo.
Fonctionnalité : Pouvoir ajuster L'importance de chaque ToDo

1.8.3 User story 2 : Passer un ToDo à Terminé.⚓︎

Sur l'icone <i class="bi bi-check2-square"></i>, ajouter l'action de passer un Todo à Terminé

1.8.4 User Story 3 : Supprimer un ToDo⚓︎

🚫 On ne peut pas supprimer un Todo qui n'est pas terminé

1.8.5 User Story 4 : Compteur⚓︎

Ajouter une page qui dénombre les Todos Non terminés et les Todos terminés.