Merge pull request 'add-recipe-form' (#1) from add-recipe-form into master
Reviewed-on: #1pull/3/head
commit
2b64147432
@ -1,3 +1,6 @@
|
||||
<h1> App HTML </h1>
|
||||
<h1>Ratatouille</h1>
|
||||
|
||||
<app-recipe-list></app-recipe-list>
|
||||
<div class="wrapper">
|
||||
<app-recipe-list></app-recipe-list>
|
||||
<app-recipe-form></app-recipe-form>
|
||||
</div>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Ingredient } from "./ingredient";
|
||||
import { Ingredient } from "./ingredient.model";
|
||||
|
||||
export interface Recipe {
|
||||
id: number;
|
@ -0,0 +1,32 @@
|
||||
<h2>New Recipe</h2>
|
||||
<form [formGroup]="recipeForm" (ngSubmit)="onSubmit()">
|
||||
<label for="name">Name:</label>
|
||||
<input id="name" formControlName="name">
|
||||
<br>
|
||||
|
||||
<label for="description">Description:</label>
|
||||
<textarea id="description" formControlName="description"></textarea>
|
||||
<br>
|
||||
|
||||
<label for="image">Image URL:</label>
|
||||
<input id="image" type="file" formControlName="image" (change)="onFileChange($event)">
|
||||
<br>
|
||||
|
||||
<div formArrayName="ingredients">
|
||||
<h3>Ingredients</h3>
|
||||
<button type="button" (click)="addIngredient()">Add Ingredient</button>
|
||||
<div *ngFor="let ingredient of ingredients.controls; let i = index" [formGroupName]="i">
|
||||
<label for="ingredientName">Ingredient:</label>
|
||||
<select id="ingredientName" formControlName="name">
|
||||
<option *ngFor="let option of ingredientsOptions" [value]="option" [selected]="option === defaultOption">
|
||||
{{option}}</option>
|
||||
</select>
|
||||
<label for="ingredientQuantity">Quantity:</label>
|
||||
<input id="ingredientQuantity" formControlName="qty">
|
||||
<button type="button" (click)="removeIngredient(i)">Remove</button>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit">Add Recipe</button>
|
||||
</form>
|
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { RecipeFormComponent } from './recipe-form.component';
|
||||
|
||||
describe('RecipeFormComponent', () => {
|
||||
let component: RecipeFormComponent;
|
||||
let fixture: ComponentFixture<RecipeFormComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [RecipeFormComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(RecipeFormComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,83 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { Recipe } from '../model/recipe.model';
|
||||
import { Ingredient } from '../model/ingredient.model';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { RecipeService } from '../services/recipe.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-recipe-form',
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
ReactiveFormsModule
|
||||
],
|
||||
templateUrl: './recipe-form.component.html',
|
||||
styleUrls: ['./recipe-form.component.css']
|
||||
})
|
||||
|
||||
export class RecipeFormComponent {
|
||||
recipeForm: FormGroup;
|
||||
base64Image: string | ArrayBuffer | null = null;
|
||||
ingredientsOptions = ['Champignon', 'Tomata', 'Mozarella'];
|
||||
defaultOption: string = this.ingredientsOptions[2];
|
||||
|
||||
constructor(private fb: FormBuilder, private recipeService: RecipeService) {
|
||||
this.recipeForm = this.fb.group({
|
||||
name: ['', Validators.required],
|
||||
description: ['', Validators.required],
|
||||
image: ['', Validators.required],
|
||||
ingredients: this.fb.array([]),
|
||||
});
|
||||
}
|
||||
|
||||
get ingredients(): FormArray {
|
||||
return this.recipeForm.get('ingredients') as FormArray;
|
||||
}
|
||||
|
||||
addIngredient(): void {
|
||||
this.ingredients.push(this.fb.group({
|
||||
name: ['', Validators.required],
|
||||
qty: ['', Validators.required]
|
||||
}));
|
||||
}
|
||||
|
||||
removeIngredient(index: number): void {
|
||||
this.ingredients.removeAt(index);
|
||||
}
|
||||
|
||||
onFileChange(event: Event) {
|
||||
const input = event.target as HTMLInputElement;
|
||||
if (input.files && input.files[0]) {
|
||||
const file = input.files[0];
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
this.base64Image = reader.result;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
}
|
||||
|
||||
onSubmit(): void {
|
||||
if (this.recipeForm.valid) {
|
||||
const newRecipe: Recipe = {
|
||||
id: 0,
|
||||
name: this.recipeForm.value.name,
|
||||
description: this.recipeForm.value.description,
|
||||
image: this.base64Image?.toString() || "no-data",
|
||||
ingredients: this.recipeForm.value.ingredients.map((ingredient: Ingredient, idx: number) => ({
|
||||
id: idx,
|
||||
name: ingredient.name,
|
||||
qty: ingredient.qty,
|
||||
}))
|
||||
};
|
||||
console.log('Recipe added:', newRecipe);
|
||||
this.recipeService.addRecipe(newRecipe);
|
||||
this.recipeForm.reset();
|
||||
} else {
|
||||
console.log('Form is invalid');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,31 @@
|
||||
import { Recipe } from "../model/recipe";
|
||||
import { RECIPES } from "../datas/recipe.stub";
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Recipe } from '../model/recipe.model';
|
||||
|
||||
@Injectable()
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class RecipeService {
|
||||
private recipes: Recipe[];
|
||||
private localStorageKey = 'recipes';
|
||||
private recipes: Recipe[] = [];
|
||||
|
||||
constructor(){
|
||||
this.recipes = RECIPES;
|
||||
}
|
||||
constructor() { }
|
||||
|
||||
getAll(): Recipe[]{
|
||||
return this.recipes;
|
||||
}
|
||||
// Get recipes from local storage
|
||||
getRecipes(): Recipe[] {
|
||||
const recipesJson = localStorage.getItem(this.localStorageKey) || "[]";
|
||||
this.recipes = JSON.parse(recipesJson) || [];
|
||||
return this.recipes;
|
||||
}
|
||||
|
||||
addRecipe(recipe: Recipe): void {
|
||||
this.recipes.push(recipe);
|
||||
}
|
||||
// Add a new recipe
|
||||
addRecipe(recipe: Recipe): void {
|
||||
this.getRecipes();
|
||||
this.recipes.push(recipe);
|
||||
localStorage.setItem(this.localStorageKey, JSON.stringify(this.recipes));
|
||||
}
|
||||
|
||||
// Clear all recipes (for example, if needed)
|
||||
clearRecipes(): void {
|
||||
localStorage.removeItem(this.localStorageKey);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in new issue