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 6a3f56ccbc0fddf1d6db6652def585639e8cc883..9ab41086a4dc7d59b1d7d35b923684a023e7fd98 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 80a9d3eb8da4409d0b2af4122e88eb75fb20e5db..64fbef2c4578cd21e6580d88fb7789503edbdaec 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 555630adfdb85eeeaa733bd8c57f5b92620eda08..1b75cded1a50408f847e5e03f032b1c00df4c9ac 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 55fed316b4d29d4b1bc4b4fd9c14ab8a6580ff01..e8cece3f356968d7a9385a28796179d23e048cf3 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 0000000000000000000000000000000000000000..30b39eb15168ccc05cbcfb70072f90499f9e6d86 --- /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 0000000000000000000000000000000000000000..fcdd0e0b0ffd34a64543ac5178dae997814cb353 --- /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 0000000000000000000000000000000000000000..209e7b4ea84f09ac129b01f58ae4b228fe9c767d --- /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 f3a7223da6dfe8bb71515d18071d24bf49ad89d9..bb8ead67f87be5535fa45ca4e396cb329bad2648 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),