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