Add and edit recipes (#3)
Co-authored-by: clfreville2 <clement.freville2@etu.uca.fr> Reviewed-on: #3pull/4/head
parent
91b8780d1d
commit
13059ca8d1
@ -1,10 +1,12 @@
|
|||||||
import { ApplicationConfig } from '@angular/core';
|
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
|
||||||
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
|
|
||||||
import { provideRouter } from '@angular/router';
|
import { provideRouter } from '@angular/router';
|
||||||
import { withComponentInputBinding } from '@angular/router';
|
import { withComponentInputBinding } from '@angular/router';
|
||||||
|
|
||||||
import { routes } from './app.routes';
|
import { routes } from './app.routes';
|
||||||
|
|
||||||
export const appConfig: ApplicationConfig = {
|
export const appConfig: ApplicationConfig = {
|
||||||
providers: [provideRouter(routes, withComponentInputBinding()), provideAnimationsAsync()],
|
providers: [
|
||||||
|
provideZoneChangeDetection({ eventCoalescing: true }),
|
||||||
|
provideRouter(routes, withComponentInputBinding()),
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
@ -1 +1,25 @@
|
|||||||
<p>recipe-add works!</p>
|
<form [formGroup]="createForm" (ngSubmit)="onSubmit()">
|
||||||
|
<div>
|
||||||
|
<label for="name">Nom</label>
|
||||||
|
<input id="name" type="text" formControlName="name" required>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="description">Description</label>
|
||||||
|
<textarea id="description" type="text" formControlName="description" required></textarea>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="description">Ingrédients</label>
|
||||||
|
<ul>
|
||||||
|
@for (ingredient of ingredientEntries; track ingredient.idIngredient) {
|
||||||
|
<li>#{{ ingredient.idIngredient }} <input [(ngModel)]="ingredient.quantity" type="number" [ngModelOptions]="{standalone: true}"></li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
<select id="selectedIngredient" formControlName="selectedIngredient">
|
||||||
|
@for (ingredient of ingredients; track ingredient.id) {
|
||||||
|
<option [ngValue]="ingredient.id">{{ ingredient.name }}</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
<button type="button" (click)="onAddIngredient()">Add</button>
|
||||||
|
</div>
|
||||||
|
<button class="button" type="submit">Ajouter</button>
|
||||||
|
</form>
|
||||||
|
@ -1,10 +1,77 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
|
import { FormBuilder, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { Ingredient, IngredientEntry, Recipe } from '../../cookbook/type';
|
||||||
|
import { RecipeService } from '../recipe.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-recipe-add',
|
selector: 'app-recipe-add',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [],
|
imports: [ReactiveFormsModule, FormsModule],
|
||||||
templateUrl: './recipe-add.component.html',
|
templateUrl: './recipe-add.component.html',
|
||||||
})
|
})
|
||||||
export class RecipeAddComponent {
|
export class RecipeAddComponent {
|
||||||
|
createForm = this.formBuilder.group({
|
||||||
|
name: ['', Validators.maxLength(256)],
|
||||||
|
description: ['', Validators.maxLength(512)],
|
||||||
|
selectedIngredient: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
ingredientEntries: IngredientEntry[] = [];
|
||||||
|
ingredients: Ingredient[] = [{
|
||||||
|
id: 1,
|
||||||
|
name: 'Paprika',
|
||||||
|
}];
|
||||||
|
|
||||||
|
#recipeId: number = -1;
|
||||||
|
@Input()
|
||||||
|
set recipeId(recipeId: string) {
|
||||||
|
if (recipeId === undefined) return;
|
||||||
|
this.#recipeId = parseInt(recipeId);
|
||||||
|
const recipe = this.recipes.get(this.#recipeId);
|
||||||
|
if (recipe === null) {
|
||||||
|
this.router.navigateByUrl('404');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.createForm.patchValue({
|
||||||
|
name: recipe.name,
|
||||||
|
description: recipe.description,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(private formBuilder: FormBuilder, private recipes: RecipeService, private router: Router) {}
|
||||||
|
|
||||||
|
onSubmit(): void {
|
||||||
|
if (this.createForm.invalid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const value = this.createForm.value;
|
||||||
|
const partial: Omit<Recipe, 'id'> = {
|
||||||
|
name: value.name!,
|
||||||
|
description: value.description!,
|
||||||
|
image: '',
|
||||||
|
ingredients: this.ingredientEntries,
|
||||||
|
};
|
||||||
|
if (this.#recipeId === -1) {
|
||||||
|
this.recipes.add(partial);
|
||||||
|
} else {
|
||||||
|
this.recipes.edit({ id: this.#recipeId, ...partial });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onAddIngredient(): void {
|
||||||
|
const value = this.createForm.value;
|
||||||
|
if (!value.selectedIngredient) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const id = parseInt(value.selectedIngredient!);
|
||||||
|
if (this.ingredientEntries.find((ingredient) => ingredient.idIngredient === id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.ingredientEntries.push({
|
||||||
|
idIngredient: id,
|
||||||
|
idRecipe: -1,
|
||||||
|
quantity: 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in new issue