Skip to content
Snippets Groups Projects
Commit 74be4fa3 authored by thibault.capt's avatar thibault.capt
Browse files

(feat): add modal for delete a todo

parent 01fa039c
Branches
No related tags found
No related merge requests found
...@@ -4,7 +4,7 @@ import { provideRouter } from '@angular/router'; ...@@ -4,7 +4,7 @@ import { provideRouter } from '@angular/router';
import { routes } from './app.routes'; import { routes } from './app.routes';
import { provideHttpClient } from '@angular/common/http'; import { provideHttpClient } from '@angular/common/http';
import { TodoService } from '@core/ports/todo.service'; 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 = { export const appConfig: ApplicationConfig = {
providers: [ providers: [
...@@ -14,7 +14,7 @@ export const appConfig: ApplicationConfig = { ...@@ -14,7 +14,7 @@ export const appConfig: ApplicationConfig = {
{ {
provide: TodoService, provide: TodoService,
useFactory: () => new HttpTodoService(), useFactory: () => new InMemoryTodoService(),
}, },
/*{ /*{
......
...@@ -8,12 +8,12 @@ import { FormsModule } from '@angular/forms'; ...@@ -8,12 +8,12 @@ import { FormsModule } from '@angular/forms';
<div class="flex space-x-2"> <div class="flex space-x-2">
<input <input
#todoInput #todoInput
class="input input-bordered w-full" class="input input-xl input-bordered w-full"
name="add todo" name="add todo"
placeholder="Ex : Tourner une vidéo sur Angular" placeholder="Ex : Tourner une vidéo sur Angular"
type="text" type="text"
/> />
<button class="btn btn-neutral" type="submit">Ajouter</button> <button class="btn btn-neutral btn-xl" type="submit">Ajouter</button>
</div> </div>
</form> </form>
`, `,
......
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);
}
import { Component, input, output } from '@angular/core'; import { Component, input, output, viewChild } from '@angular/core';
import { Todo } from '@core/models/todo'; import { Todo } from '@core/models/todo';
import { FaIconComponent } from '@fortawesome/angular-fontawesome'; import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { NgClass } from '@angular/common'; import { NgClass } from '@angular/common';
import { ModalConfirmComponent } from '@features/todo-list/components/modal-confirm.component';
@Component({ @Component({
selector: 'app-todo-list-item', selector: 'app-todo-list-item',
template: ` 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"> <label class="fieldset-label">
<input type="checkbox" [checked]="todo().completed" class="checkbox" (change)="toggleCompleted.emit(todo())" /> <input type="checkbox" [checked]="todo().completed" class="checkbox" (change)="toggleCompleted.emit(todo())" />
<span [ngClass]="{ 'line-through': todo().completed }">{{ todo().name }}</span> <span [ngClass]="{ 'line-through': todo().completed }" class="flex-grow ml-1">{{ todo().name }}</span>
<button class="btn btn-ghost btn-error" (click)="remove.emit(todo())">
<fa-icon [icon]="['fas', 'trash']"></fa-icon>
</button>
</label> </label>
<button class="btn btn-ghost btn-error ml-auto" (click)="modal()?.open()">
<fa-icon [icon]="['fas', 'trash']"></fa-icon>
</button>
</li> </li>
<app-modal-confirm #confirmModal (confirm)="remove.emit(todo())" />
`, `,
imports: [FaIconComponent, NgClass], imports: [FaIconComponent, NgClass, ModalConfirmComponent],
}) })
export class TodoListItemComponent { export class TodoListItemComponent {
todo = input.required<Todo>(); todo = input.required<Todo>();
toggleCompleted = output<Todo>(); toggleCompleted = output<Todo>();
remove = output<Todo>(); remove = output<Todo>();
modal = viewChild<ModalConfirmComponent>('confirmModal');
} }
<div class="flex items-center justify-center min-h-screen bg-gray-100"> <div class="flex items-center justify-center min-h-screen bg-gray-100 p-8">
<div class="w-full max-w-md bg-white p-6 rounded-lg shadow-lg"> <div class="w-full max-w-2xl bg-white p-8 rounded-lg shadow-lg">
<h1 class="text-center text-3xl font-bold mb-4">Check-list</h1> <h1 class="text-center text-4xl font-bold mb-6">Check-list</h1>
<!-- Input et bouton --> <!-- Input et bouton -->
<app-add-todo-form (add)="addTodo($event)" /> <app-add-todo-form (add)="addTodo($event)" />
<!-- Liste des tâches --> <!-- Liste des tâches -->
<div class="flex-grow flex items-center justify-center py-5"> <div class="py-5">
@if (!store.isLoading()) { @if (!store.isLoading()) {
<span class="loading loading-spinner loading-xl"></span> <span class="loading loading-spinner loading-xl"></span>
} @else { } @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(); @let todos = store.todos();
@for (todo of todos; track todo.id) { @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> </ul>
@if (!todos?.length) { @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> </div>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment