From 74be4fa3866de88c36a1d12bd7e25102833435b8 Mon Sep 17 00:00:00 2001
From: "thibault.capt" <thibault.capt@etu.hesge.ch>
Date: Sun, 23 Feb 2025 14:34:43 +0100
Subject: [PATCH] (feat): add modal for delete a todo

---
 todo-workspace/frontend/src/app/app.config.ts |  4 +--
 .../components/add-todo-form.component.ts     |  4 +--
 .../components/modal-confirm.component.ts     | 30 +++++++++++++++++++
 .../todo-list/components/todo-list-item.ts    | 18 ++++++-----
 .../todo-list/todo-list.component.html        | 19 +++++++-----
 5 files changed, 57 insertions(+), 18 deletions(-)
 create mode 100644 todo-workspace/frontend/src/app/features/todo-list/components/modal-confirm.component.ts

diff --git a/todo-workspace/frontend/src/app/app.config.ts b/todo-workspace/frontend/src/app/app.config.ts
index dbe76fd..44e7ba1 100644
--- a/todo-workspace/frontend/src/app/app.config.ts
+++ b/todo-workspace/frontend/src/app/app.config.ts
@@ -4,7 +4,7 @@ import { provideRouter } from '@angular/router';
 import { routes } from './app.routes';
 import { provideHttpClient } from '@angular/common/http';
 import { TodoService } from '@core/ports/todo.service';
-import { HttpTodoService } from '@core/adapters/http-todo.service';
+import { InMemoryTodoService } from '@core/adapters/in-memory-todo.service';
 
 export const appConfig: ApplicationConfig = {
   providers: [
@@ -14,7 +14,7 @@ export const appConfig: ApplicationConfig = {
 
     {
       provide: TodoService,
-      useFactory: () => new HttpTodoService(),
+      useFactory: () => new InMemoryTodoService(),
     },
 
     /*{
diff --git a/todo-workspace/frontend/src/app/features/todo-list/components/add-todo-form.component.ts b/todo-workspace/frontend/src/app/features/todo-list/components/add-todo-form.component.ts
index eb54bc7..0fb0f8b 100644
--- a/todo-workspace/frontend/src/app/features/todo-list/components/add-todo-form.component.ts
+++ b/todo-workspace/frontend/src/app/features/todo-list/components/add-todo-form.component.ts
@@ -8,12 +8,12 @@ import { FormsModule } from '@angular/forms';
       <div class="flex space-x-2">
         <input
           #todoInput
-          class="input input-bordered w-full"
+          class="input input-xl input-bordered w-full"
           name="add todo"
           placeholder="Ex : Tourner une vidéo sur Angular"
           type="text"
         />
-        <button class="btn btn-neutral" type="submit">Ajouter</button>
+        <button class="btn btn-neutral btn-xl" type="submit">Ajouter</button>
       </div>
     </form>
   `,
diff --git a/todo-workspace/frontend/src/app/features/todo-list/components/modal-confirm.component.ts b/todo-workspace/frontend/src/app/features/todo-list/components/modal-confirm.component.ts
new file mode 100644
index 0000000..a909c92
--- /dev/null
+++ b/todo-workspace/frontend/src/app/features/todo-list/components/modal-confirm.component.ts
@@ -0,0 +1,30 @@
+import { Component, HostListener, output, signal } from '@angular/core';
+
+@Component({
+  selector: 'app-modal-confirm',
+  template: `
+    @if (isOpen()) {
+      <dialog id="modal" class="modal modal-open modal-bottom sm:modal-middle">
+        <div class="modal-box">
+          <h3 class="font-bold text-lg">Confirmation</h3>
+          <p class="py-4">Êtes-vous sûr de vouloir supprimer cette tâche ?</p>
+          <div class="modal-action">
+            <form method="dialog">
+              <button class="btn btn-outline mr-2" (click)="close()">Annuler</button>
+              <button class="btn btn-error" (click)="confirm.emit(); this.close()">Supprimer</button>
+            </form>
+          </div>
+        </div>
+      </dialog>
+    }
+  `,
+})
+export class ModalConfirmComponent {
+  isOpen = signal(false);
+  confirm = output<void>();
+
+  open = () => this.isOpen.set(true);
+
+  @HostListener('document:keydown.escape')
+  close = () => this.isOpen.set(false);
+}
diff --git a/todo-workspace/frontend/src/app/features/todo-list/components/todo-list-item.ts b/todo-workspace/frontend/src/app/features/todo-list/components/todo-list-item.ts
index 4e0fbd9..000b107 100644
--- a/todo-workspace/frontend/src/app/features/todo-list/components/todo-list-item.ts
+++ b/todo-workspace/frontend/src/app/features/todo-list/components/todo-list-item.ts
@@ -1,25 +1,29 @@
-import { Component, input, output } from '@angular/core';
+import { Component, input, output, viewChild } from '@angular/core';
 import { Todo } from '@core/models/todo';
 import { FaIconComponent } from '@fortawesome/angular-fontawesome';
 import { NgClass } from '@angular/common';
+import { ModalConfirmComponent } from '@features/todo-list/components/modal-confirm.component';
 
 @Component({
   selector: 'app-todo-list-item',
   template: `
-    <li class="py-2 w-full">
+    <li class="w-full bg-gray-50 p-3 rounded-lg shadow flex items-center justify-between gap-3">
       <label class="fieldset-label">
         <input type="checkbox" [checked]="todo().completed" class="checkbox" (change)="toggleCompleted.emit(todo())" />
-        <span [ngClass]="{ 'line-through': todo().completed }">{{ todo().name }}</span>
-        <button class="btn btn-ghost btn-error" (click)="remove.emit(todo())">
-          <fa-icon [icon]="['fas', 'trash']"></fa-icon>
-        </button>
+        <span [ngClass]="{ 'line-through': todo().completed }" class="flex-grow ml-1">{{ todo().name }}</span>
       </label>
+      <button class="btn btn-ghost btn-error ml-auto" (click)="modal()?.open()">
+        <fa-icon [icon]="['fas', 'trash']"></fa-icon>
+      </button>
     </li>
+
+    <app-modal-confirm #confirmModal (confirm)="remove.emit(todo())" />
   `,
-  imports: [FaIconComponent, NgClass],
+  imports: [FaIconComponent, NgClass, ModalConfirmComponent],
 })
 export class TodoListItemComponent {
   todo = input.required<Todo>();
   toggleCompleted = output<Todo>();
   remove = output<Todo>();
+  modal = viewChild<ModalConfirmComponent>('confirmModal');
 }
diff --git a/todo-workspace/frontend/src/app/features/todo-list/todo-list.component.html b/todo-workspace/frontend/src/app/features/todo-list/todo-list.component.html
index 44302be..cc2f8a3 100644
--- a/todo-workspace/frontend/src/app/features/todo-list/todo-list.component.html
+++ b/todo-workspace/frontend/src/app/features/todo-list/todo-list.component.html
@@ -1,23 +1,28 @@
-<div class="flex items-center justify-center min-h-screen bg-gray-100">
-  <div class="w-full max-w-md bg-white p-6 rounded-lg shadow-lg">
-    <h1 class="text-center text-3xl font-bold mb-4">Check-list</h1>
+<div class="flex items-center justify-center min-h-screen bg-gray-100 p-8">
+  <div class="w-full max-w-2xl bg-white p-8 rounded-lg shadow-lg">
+    <h1 class="text-center text-4xl font-bold mb-6">Check-list</h1>
     <!-- Input et bouton -->
     <app-add-todo-form (add)="addTodo($event)" />
 
     <!-- Liste des tâches -->
-    <div class="flex-grow flex items-center justify-center py-5">
+    <div class="py-5">
       @if (!store.isLoading()) {
         <span class="loading loading-spinner loading-xl"></span>
       } @else {
-        <ul class="list text-gray-600 text-lg">
+        <ul class="grid grid-cols-1 gap-4 text-gray-600 text-lg">
           @let todos = store.todos();
           @for (todo of todos; track todo.id) {
-            <app-todo-list-item [todo]="todo" (toggleCompleted)="toggleCompleted($event)" (remove)="remove($event)" />
+            <app-todo-list-item
+              class="w-full"
+              [todo]="todo"
+              (toggleCompleted)="toggleCompleted($event)"
+              (remove)="remove($event)"
+            />
           }
         </ul>
 
         @if (!todos?.length) {
-          <p class="text-gray-600 text-lg">Ajoute ta première tâche 👆</p>
+          <p class="text-gray-600 text-lg text-center mt-4">Ajoute ta première tâche 👆</p>
         }
       }
     </div>
-- 
GitLab