From 373e3525763350f3c1e89c22a6c3ef82caed558c Mon Sep 17 00:00:00 2001 From: "hugo.pradier2" Date: Sat, 29 Jun 2024 15:15:54 +0200 Subject: [PATCH] ajout edition d'une recette --- src/app/app.routes.ts | 2 + .../ingredient-edit.component.ts | 3 +- .../recipe-edit/recipe-edit.component.html | 117 +++++++++++++++ .../recipe-edit/recipe-edit.component.scss | 0 src/app/recipe-edit/recipe-edit.component.ts | 141 ++++++++++++++++++ .../recipe-list/recipe-list.component.html | 3 + src/app/recipe-list/recipe-list.component.ts | 4 + src/app/services/recipe.service.ts | 43 +++++- 8 files changed, 307 insertions(+), 6 deletions(-) create mode 100644 src/app/recipe-edit/recipe-edit.component.html create mode 100644 src/app/recipe-edit/recipe-edit.component.scss create mode 100644 src/app/recipe-edit/recipe-edit.component.ts diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index e677d69..44ac639 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -9,10 +9,12 @@ import { LogoutComponent } from './logout/logout.component'; import { authGuard } from './guards/auth.guard'; import { IngredientAddComponent } from './ingredient-add/ingredient-add.component'; import { IngredientEditComponent } from './ingredient-edit/ingredient-edit.component'; +import { RecipeEditComponent } from './recipe-edit/recipe-edit.component'; export const routes: Routes = [ { path: 'add', component: RecipeAddComponent }, { path: 'recipe/:id', component: RecipeComponent }, + { path: 'recipe/:id/edit', component: RecipeEditComponent }, { path: 'list', component: RecipeListComponent }, { path: 'ingredients', diff --git a/src/app/ingredient-edit/ingredient-edit.component.ts b/src/app/ingredient-edit/ingredient-edit.component.ts index 0dfb73a..1c34e4f 100644 --- a/src/app/ingredient-edit/ingredient-edit.component.ts +++ b/src/app/ingredient-edit/ingredient-edit.component.ts @@ -13,7 +13,7 @@ import { HttpClientModule } from '@angular/common/http'; standalone: true, imports: [CommonModule, MatFormFieldModule, MatButtonModule, FormsModule], templateUrl: './ingredient-edit.component.html', - styleUrls: ['./ingredient-edit.component.scss'] + styleUrls: ['./ingredient-edit.component.scss'], }) export class IngredientEditComponent implements OnInit { ingredient!: Ingredient; @@ -30,7 +30,6 @@ export class IngredientEditComponent implements OnInit { } save(): void { - // Implement save logic here this.router.navigate(['/ingredients']); } diff --git a/src/app/recipe-edit/recipe-edit.component.html b/src/app/recipe-edit/recipe-edit.component.html new file mode 100644 index 0000000..5a29d7d --- /dev/null +++ b/src/app/recipe-edit/recipe-edit.component.html @@ -0,0 +1,117 @@ +
+
+ + +
+
+ Name is required. +
+
+
+ +
+ + +
+ Characters left: {{ maxDescriptionLength - recipe.description.length }} +
+
+
+ Description is required. +
+
+
+ +
+
+ + +
+
+ + + Ingredients + + + {{ ingredient.name }} + + + + + +
+
+ {{ findIngredientName(ingredientId) }} + +
+
+
+ At least one ingredient is required. +
+ + +
diff --git a/src/app/recipe-edit/recipe-edit.component.scss b/src/app/recipe-edit/recipe-edit.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/recipe-edit/recipe-edit.component.ts b/src/app/recipe-edit/recipe-edit.component.ts new file mode 100644 index 0000000..fdbd175 --- /dev/null +++ b/src/app/recipe-edit/recipe-edit.component.ts @@ -0,0 +1,141 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { CommonModule } from '@angular/common'; +import { FormsModule, NgForm } from '@angular/forms'; +import { RecipeService } from '../services/recipe.service'; +import { IngredientService } from '../services/ingredient.service'; +import { Recipe } from '../models/recipe'; +import { IngredientRecipe } from '../models/ingredient-recipe'; +import { Ingredient } from '../models/ingredient'; +import { MatButtonModule } from '@angular/material/button'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatSelectModule } from '@angular/material/select'; + +@Component({ + selector: 'app-recipe-edit', + standalone: true, + templateUrl: './recipe-edit.component.html', + styleUrls: ['./recipe-edit.component.scss'], + imports: [ + CommonModule, + FormsModule, + MatButtonModule, + MatFormFieldModule, + MatSelectModule, + ], +}) +export class RecipeEditComponent implements OnInit { + recipe: Recipe = new Recipe(0, '', '', '', []); + ingredients: Ingredient[] = []; + ingredientQuantities: { [key: number]: number } = {}; + selectedIngredient: number | null = null; + imageError: string | null = null; + maxDescriptionLength: number = 200; + isSubmitting: boolean = false; + @ViewChild('recipeForm', { static: true }) recipeForm!: NgForm; + + constructor( + private route: ActivatedRoute, + private router: Router, + private recipeService: RecipeService, + private ingredientService: IngredientService + ) {} + + ngOnInit(): void { + this.ingredients = this.ingredientService.getIngredients(); + const id = this.route.snapshot.paramMap.get('id'); + if (id) { + const recipeId = parseInt(id, 10); + this.recipe = + this.recipeService.getRecipeById(recipeId) ?? + new Recipe(0, '', '', '', []); + this.loadIngredientQuantities(recipeId); + } + } + + onFileChange(event: any): void { + const file = event.target.files[0]; + if (file) { + const validImageTypes = [ + 'image/jpeg', + 'image/png', + 'image/gif', + 'image/jpg', + ]; + if (!validImageTypes.includes(file.type)) { + this.imageError = 'Invalid file type. Please select an image file.'; + return; + } + + this.imageError = null; + + const reader = new FileReader(); + reader.onload = () => { + this.recipe.image = reader.result as string; + }; + reader.readAsDataURL(file); + } + } + + loadIngredientQuantities(recipeId: number): void { + const ingredientRecipes = this.recipeService.getIngredientRecipes(recipeId); + ingredientRecipes.forEach((ingredientRecipe) => { + this.ingredientQuantities[ingredientRecipe.idIngredient] = + ingredientRecipe.quantity; + }); + } + + addIngredient(): void { + if ( + this.selectedIngredient !== null && + !this.ingredientQuantities[this.selectedIngredient] + ) { + this.ingredientQuantities[this.selectedIngredient] = 1; + this.selectedIngredient = null; + } + } + + removeIngredient(id: number): void { + delete this.ingredientQuantities[id]; + } + + getIngredientKeys(): number[] { + return Object.keys(this.ingredientQuantities).map((key) => + parseInt(key, 10) + ); + } + + findIngredientName(id: number): string { + const ingredient = this.ingredients.find( + (ingredient) => ingredient.id === id + ); + return ingredient ? ingredient.name : ''; + } + + onSubmit(): void { + if (this.isSubmitting) return; + + this.isSubmitting = true; + + this.recipe.ingredients = this.getIngredientKeys().map((id) => { + const ingredient = this.ingredientService.getIngredient(id); + return new Ingredient(id, ingredient.name); + }); + + this.recipeService.updateRecipe(this.recipe); + + this.getIngredientKeys().forEach((id) => { + const quantity = this.ingredientQuantities[id]; + const ingredientRecipe = new IngredientRecipe( + id, + this.recipe.id, + quantity + ); + this.recipeService.updateIngredientRecipe(ingredientRecipe); + }); + + this.router.navigate(['/list']).then(() => { + this.isSubmitting = false; + }); + } +} diff --git a/src/app/recipe-list/recipe-list.component.html b/src/app/recipe-list/recipe-list.component.html index 1373591..d26bbfd 100644 --- a/src/app/recipe-list/recipe-list.component.html +++ b/src/app/recipe-list/recipe-list.component.html @@ -51,6 +51,9 @@ + diff --git a/src/app/recipe-list/recipe-list.component.ts b/src/app/recipe-list/recipe-list.component.ts index a1eef9a..1d7e52f 100644 --- a/src/app/recipe-list/recipe-list.component.ts +++ b/src/app/recipe-list/recipe-list.component.ts @@ -57,4 +57,8 @@ export class RecipeListComponent implements OnInit { this.recipeService.orderRecipe(recipe); this.router.navigate(['/home']); } + + onEditRecipe(recipe: Recipe): void { + this.router.navigate(['/recipe', recipe.id, 'edit']); + } } diff --git a/src/app/services/recipe.service.ts b/src/app/services/recipe.service.ts index b6e8231..301c421 100644 --- a/src/app/services/recipe.service.ts +++ b/src/app/services/recipe.service.ts @@ -29,7 +29,6 @@ export class RecipeService { recipes = recipes.filter((recipe) => recipe.id !== recipeId); localStorage.setItem(this.localStorageKey, JSON.stringify(recipes)); - // Supprimer les IngredientRecipe associés let ingredientRecipes = this.getIngredientRecipes(recipeId); ingredientRecipes = ingredientRecipes.filter( (ir) => ir.idRecipe !== recipeId @@ -39,7 +38,6 @@ export class RecipeService { JSON.stringify(ingredientRecipes) ); - // Mettre à jour les commandes en cours let currentOrders = this.getCurrentOrders(); currentOrders = currentOrders.filter((order) => order.id !== recipeId); localStorage.setItem( @@ -57,8 +55,8 @@ export class RecipeService { } addIngredientRecipe(ingredientRecipe: IngredientRecipe): void { - const ingredientRecipes = this.getIngredientRecipes( - ingredientRecipe.idRecipe + const ingredientRecipes: IngredientRecipe[] = JSON.parse( + localStorage.getItem(this.ingredientRecipeKey) || '[]' ); ingredientRecipes.push(ingredientRecipe); localStorage.setItem( @@ -67,6 +65,29 @@ export class RecipeService { ); } + updateIngredientRecipe(updatedIngredientRecipe: IngredientRecipe): void { + let ingredientRecipes: IngredientRecipe[] = JSON.parse( + localStorage.getItem(this.ingredientRecipeKey) || '[]' + ); + + const index = ingredientRecipes.findIndex( + (ir) => + ir.idIngredient === updatedIngredientRecipe.idIngredient && + ir.idRecipe === updatedIngredientRecipe.idRecipe + ); + + if (index !== -1) { + ingredientRecipes[index] = updatedIngredientRecipe; + } else { + ingredientRecipes.push(updatedIngredientRecipe); + } + + localStorage.setItem( + this.ingredientRecipeKey, + JSON.stringify(ingredientRecipes) + ); + } + getIngredientQuantity( ingredientId: number, ingredientRecipes: IngredientRecipe[] @@ -89,4 +110,18 @@ export class RecipeService { const currentOrdersJson = localStorage.getItem(this.currentOrdersKey); return currentOrdersJson ? JSON.parse(currentOrdersJson) : []; } + + updateRecipe(recipe: Recipe): void { + let recipes = this.getRecipes(); + const index = recipes.findIndex((r) => r.id === recipe.id); + if (index !== -1) { + recipes[index] = recipe; + localStorage.setItem(this.localStorageKey, JSON.stringify(recipes)); + } + } + + getRecipeById(recipeId: number): Recipe | undefined { + const recipes = this.getRecipes(); + return recipes.find((recipe) => recipe.id === recipeId); + } }