From c464a701c1e72f391264cdec80339a84bea13fd7 Mon Sep 17 00:00:00 2001 From: "thibault.capt" <thibault.capt@etu.hesge.ch> Date: Tue, 18 Feb 2025 11:32:15 +0100 Subject: [PATCH] (feat): add modal for adding a car --- .../garage-ui/src/app/app.component.ts | 10 +++- .../garage-ui/src/app/core/cars/car.store.ts | 2 - .../src/app/features/cars/cars.component.html | 17 ++++++- .../src/app/features/cars/cars.component.ts | 19 +++++++- .../components/modal/modal.component.html | 48 +++++++++++++++++++ .../cars/components/modal/modal.component.ts | 27 +++++++++++ .../garage-ui/src/app/shared/fa-icons.ts | 4 ++ .../garage/projects/garage-ui/src/main.ts | 4 +- 8 files changed, 122 insertions(+), 9 deletions(-) create mode 100644 garage-workspace/garage/projects/garage-ui/src/app/features/cars/components/modal/modal.component.html create mode 100644 garage-workspace/garage/projects/garage-ui/src/app/features/cars/components/modal/modal.component.ts create mode 100644 garage-workspace/garage/projects/garage-ui/src/app/shared/fa-icons.ts diff --git a/garage-workspace/garage/projects/garage-ui/src/app/app.component.ts b/garage-workspace/garage/projects/garage-ui/src/app/app.component.ts index 6a3f56ccb..9ab41086a 100644 --- a/garage-workspace/garage/projects/garage-ui/src/app/app.component.ts +++ b/garage-workspace/garage/projects/garage-ui/src/app/app.component.ts @@ -1,5 +1,7 @@ -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { RouterOutlet } from '@angular/router'; +import { FaIconLibrary } from '@fortawesome/angular-fontawesome'; +import { faIcons } from '@shared/fa-icons'; @Component({ selector: 'app-root', @@ -7,4 +9,8 @@ import { RouterOutlet } from '@angular/router'; template: `<router-outlet />`, styleUrl: './app.component.scss', }) -export class AppComponent {} +export class AppComponent { + constructor() { + inject(FaIconLibrary).addIcons(...faIcons); + } +} diff --git a/garage-workspace/garage/projects/garage-ui/src/app/core/cars/car.store.ts b/garage-workspace/garage/projects/garage-ui/src/app/core/cars/car.store.ts index 80a9d3eb8..64fbef2c4 100644 --- a/garage-workspace/garage/projects/garage-ui/src/app/core/cars/car.store.ts +++ b/garage-workspace/garage/projects/garage-ui/src/app/core/cars/car.store.ts @@ -39,9 +39,7 @@ export const CarStore = signalStore( })), withHooks((store) => ({ onInit() { - patchState(store, { loading: true }); store.getCars(); - patchState(store, { loading: false }); }, })), ); diff --git a/garage-workspace/garage/projects/garage-ui/src/app/features/cars/cars.component.html b/garage-workspace/garage/projects/garage-ui/src/app/features/cars/cars.component.html index 555630adf..1b75cded1 100644 --- a/garage-workspace/garage/projects/garage-ui/src/app/features/cars/cars.component.html +++ b/garage-workspace/garage/projects/garage-ui/src/app/features/cars/cars.component.html @@ -31,7 +31,19 @@ <td>{{ car.model }}</td> <td>{{ car.year }}</td> <td>{{ car.color }}</td> - <td>Modify | Delete</td> + <td> + <div class="tooltip" data-tip="Edit"> + <button class="btn btn-square btn-sm mr-1" (click)="onEdit(car.id)"> + <fa-icon [icon]="['fas', 'pen-nib']"></fa-icon> + </button> + </div> + + <div class="tooltip" data-tip="Delete"> + <button class="btn btn-square btn-sm" (click)="onDelete(car.id)"> + <fa-icon [icon]="['fas', 'trash']"></fa-icon> + </button> + </div> + </td> </tr> } } @@ -41,5 +53,8 @@ </tr> } </table> + <button (click)="onAdd()" class="btn btn-soft btn-primary mt-2">Add new car</button> </div> </div> + +<app-modal #modal /> \ No newline at end of file diff --git a/garage-workspace/garage/projects/garage-ui/src/app/features/cars/cars.component.ts b/garage-workspace/garage/projects/garage-ui/src/app/features/cars/cars.component.ts index 55fed316b..e8cece3f3 100644 --- a/garage-workspace/garage/projects/garage-ui/src/app/features/cars/cars.component.ts +++ b/garage-workspace/garage/projects/garage-ui/src/app/features/cars/cars.component.ts @@ -1,13 +1,28 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, viewChild } from '@angular/core'; import { CarStore } from '@core/cars/car.store'; +import { FaIconComponent } from '@fortawesome/angular-fontawesome'; +import { ModalComponent } from '@features/cars/components/modal/modal.component'; @Component({ selector: 'app-cars', - imports: [], + imports: [FaIconComponent, ModalComponent], templateUrl: './cars.component.html', styleUrl: './cars.component.scss', providers: [CarStore], }) export default class CarsComponent { readonly store = inject(CarStore); + modal = viewChild<ModalComponent>('modal'); + + onEdit(id: number) { + alert(`Edit car with id: ${id}`); + } + + onDelete(id: number) { + alert(`Delete car with id: ${id}`); + } + + onAdd() { + this.modal()!.open(); + } } diff --git a/garage-workspace/garage/projects/garage-ui/src/app/features/cars/components/modal/modal.component.html b/garage-workspace/garage/projects/garage-ui/src/app/features/cars/components/modal/modal.component.html new file mode 100644 index 000000000..30b39eb15 --- /dev/null +++ b/garage-workspace/garage/projects/garage-ui/src/app/features/cars/components/modal/modal.component.html @@ -0,0 +1,48 @@ +@if (isOpen()) { +<div class="modal modal-open"> + <div class="modal-box"> + <button (click)="close()" class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button> + <h3 class="text-lg font-bold">Adding a new car!</h3> + + <form (ngSubmit)="onSubmit()" class="mt-4 mb-4"> + <!-- Brand --> + <div class="mb-4"> + <label class="floating-label" for="brand"> + <span>Brand</span> + <input id="brand" name="brand" type="text" placeholder="Brand" class="input input-bordered" required> + </label> + </div> + + <!-- Model --> + <div class="mb-4"> + <label class="floating-label" for="model"> + <span>Model</span> + <input id="model" name="model" type="text" placeholder="Model" class="input input-bordered" required> + </label> + </div> + + <!-- Year --> + <div class="mb-4"> + <label class="floating-label" for="year"> + <span>Year</span> + <input id="year" name="year" type="number" min="1900" max="2025" placeholder="Year" class="input input-bordered" required> + </label> + </div> + + <!-- Color --> + <div class="mb-4"> + <label class="floating-label" for="brand"> + <span>Color</span> + <input id="color" name="color" type="text" placeholder="Color" class="input input-bordered" required> + </label> + </div> + + <!-- Actions du modal --> + <div class="modal-action"> + <button type="button" class="btn" (click)="close()">Cancel</button> + <button type="submit" class="btn btn-primary">Save</button> + </div> + </form> + </div> +</div> +} \ No newline at end of file diff --git a/garage-workspace/garage/projects/garage-ui/src/app/features/cars/components/modal/modal.component.ts b/garage-workspace/garage/projects/garage-ui/src/app/features/cars/components/modal/modal.component.ts new file mode 100644 index 000000000..fcdd0e0b0 --- /dev/null +++ b/garage-workspace/garage/projects/garage-ui/src/app/features/cars/components/modal/modal.component.ts @@ -0,0 +1,27 @@ +import { Component, input, signal } from '@angular/core'; +import { Car } from '@core/cars/models/car.model'; +import { FormsModule } from '@angular/forms'; + +@Component({ + selector: 'app-modal', + imports: [FormsModule], + templateUrl: './modal.component.html', +}) +export class ModalComponent { + isOpen = signal(false); + newCar = input.required<Car>(); + + open(): void { + this.isOpen.set(true); + } + + close(): void { + this.isOpen.set(false); + } + + onSubmit() { + alert('Submitted'); + } + + // TODO: continuer le add car +} diff --git a/garage-workspace/garage/projects/garage-ui/src/app/shared/fa-icons.ts b/garage-workspace/garage/projects/garage-ui/src/app/shared/fa-icons.ts new file mode 100644 index 000000000..209e7b4ea --- /dev/null +++ b/garage-workspace/garage/projects/garage-ui/src/app/shared/fa-icons.ts @@ -0,0 +1,4 @@ +import { IconDefinition } from '@fortawesome/angular-fontawesome'; +import { faPenNib, faTrash } from '@fortawesome/free-solid-svg-icons'; + +export const faIcons: IconDefinition[] = [faPenNib, faTrash]; diff --git a/garage-workspace/garage/projects/garage-ui/src/main.ts b/garage-workspace/garage/projects/garage-ui/src/main.ts index f3a7223da..bb8ead67f 100644 --- a/garage-workspace/garage/projects/garage-ui/src/main.ts +++ b/garage-workspace/garage/projects/garage-ui/src/main.ts @@ -1,6 +1,6 @@ import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; -import { appConfig } from './app/app.config'; +import { AppComponent } from '@app/app.component'; +import { appConfig } from '@app/app.config'; bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err), -- GitLab