summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorschencej <55326070+schencej@users.noreply.github.com>2019-12-10 17:31:57 -0500
committerGitHub <noreply@github.com>2019-12-10 17:31:57 -0500
commitdb8efeafb8e3a427cded4ffa1b8fdcda789cbdaa (patch)
treef1a10c6a2e092de028810bc842dc11bde2580a49
parent58043492cf8a12d3b73dbb8760e26ffce0e2dc41 (diff)
parent3fd5630cae141bf49537537315d23bdbf92f8493 (diff)
Merge branch 'master' into top_bar
-rw-r--r--backend/readme.adoc13
-rw-r--r--backend/recipe.go5
-rw-r--r--recipeBuddy/src/app/add-recipe/add-recipe.component.ts18
-rw-r--r--recipeBuddy/src/app/app-routing.module.ts4
-rw-r--r--recipeBuddy/src/app/app.module.ts6
-rw-r--r--recipeBuddy/src/app/edit-recipe/edit-recipe.component.css43
-rw-r--r--recipeBuddy/src/app/edit-recipe/edit-recipe.component.html110
-rw-r--r--recipeBuddy/src/app/edit-recipe/edit-recipe.component.spec.ts25
-rw-r--r--recipeBuddy/src/app/edit-recipe/edit-recipe.component.ts188
9 files changed, 391 insertions, 21 deletions
diff --git a/backend/readme.adoc b/backend/readme.adoc
index b10ea07..bc3c50f 100644
--- a/backend/readme.adoc
+++ b/backend/readme.adoc
@@ -37,12 +37,11 @@ The current implementation expects (and returns) recipes in the form:
"name": "Ingredient 1 Name",
"amount": 1.0,
"unit": "Ingredient Units"
- "type_": ""
},
],
"steps": [
{
- "instructions": "Step Instructions/Description",
+ "instruction": "Step Instructions/Description",
"timer": 0
}
]
@@ -122,11 +121,11 @@ $ curl -X POST api.recipebuddy.xyz:8888/recipes -d '
{"name":"INGR 2","amount":1,"unit":"oz"}
],
"steps":[
- {"instructions":"Step 1: Do this first","timer":10}
+ {"instruction":"Step 1: Do this first","timer":10}
]
}'
-{"Status":{"Code":201,"Msg":"Recipe added successfully"},"Data":{"id":2,"name":"Test Recipe 2","description":"This is a descripiton for the test recipe","photos":["photo_url_1","photo_url_2"],"servingSize":0,"cookTime":60,"rating":5,"timesCooked":0,"tags":["keyword_1","keyword_2","keyword_3"],"ingredients":[{"name":"INGR 1","amount":2.5,"unit":"cups"},{"name":"INGR 2","amount":1,"unit":"oz"}],"steps":[{"instructions":"Step 1: Do this first","timer":10}]}}
+{"Status":{"Code":201,"Msg":"Recipe added successfully"},"Data":{"id":2,"name":"Test Recipe 2","description":"This is a descripiton for the test recipe","photos":["photo_url_1","photo_url_2"],"servingSize":0,"cookTime":60,"rating":5,"timesCooked":0,"tags":["keyword_1","keyword_2","keyword_3"],"ingredients":[{"name":"INGR 1","amount":2.5,"unit":"cups"},{"name":"INGR 2","amount":1,"unit":"oz"}],"steps":[{"instruction":"Step 1: Do this first","timer":10}]}}
----
Read
@@ -138,7 +137,7 @@ http://api.recipebuddy.xyz:8888/recipes/0[`/recipes/{id}`], the HTTP body is ign
----
$ curl -X GET api.recipebuddy.xyz:8888/recipes/1
-{"Status":{"Code":200,"Msg":"Successful"},"Data":{"id":1,"name":"Test Recipe","description":"This is a descripiton for the test recipe","photos":["photo_url_1","photo_url_2",""],"servingSize":0,"cookTime":60,"rating":5,"timesCooked":0,"tags":["keyword_1","keyword_2","keyword_3",""],"ingredients":[{"name":"INGR 1","amount":2.5,"unit":"cups"},{"name":"INGR 2","amount":1,"unit":"oz"}],"steps":[{"instructions":"Step 1: Do this first","timer":10}]}}
+{"Status":{"Code":200,"Msg":"Successful"},"Data":{"id":1,"name":"Test Recipe","description":"This is a descripiton for the test recipe","photos":["photo_url_1","photo_url_2",""],"servingSize":0,"cookTime":60,"rating":5,"timesCooked":0,"tags":["keyword_1","keyword_2","keyword_3",""],"ingredients":[{"name":"INGR 1","amount":2.5,"unit":"cups"},{"name":"INGR 2","amount":1,"unit":"oz"}],"steps":[{"instruction":"Step 1: Do this first","timer":10}]}}
----
To access a list of all recipe ids in the database send a `GET` request to
@@ -171,11 +170,11 @@ $ curl -X PUT localhost:8888/recipes/1 -d '
{ "name":"INGR 2", "amount":1, "unit":"oz" }
],
"steps":[
- { "instructions":"Step 1: Do this first", "timer":10 }
+ { "instruction":"Step 1: Do this first", "timer":10 }
]
}'
-{"Status":{"Code":201,"Msg":"Recipe added successfully"},"Data":{"id":1,"name":"Test Recipe 1","description":"This is a descripiton for the test recipe","photos":["photo_url_1","photo_url_2"],"servingSize":0,"cookTime":60,"rating":5,"timesCooked":0,"tags":["keyword_1","keyword_2","keyword_3"],"ingredients":[{"name":"INGR 1","amount":2.5,"unit":"cups"},{"name":"INGR 2","amount":1,"unit":"oz"}],"steps":[{"instructions":"Step 1: Do this first","timer":10}]}}
+{"Status":{"Code":201,"Msg":"Recipe added successfully"},"Data":{"id":1,"name":"Test Recipe 1","description":"This is a descripiton for the test recipe","photos":["photo_url_1","photo_url_2"],"servingSize":0,"cookTime":60,"rating":5,"timesCooked":0,"tags":["keyword_1","keyword_2","keyword_3"],"ingredients":[{"name":"INGR 1","amount":2.5,"unit":"cups"},{"name":"INGR 2","amount":1,"unit":"oz"}],"steps":[{"instruction":"Step 1: Do this first","timer":10}]}}
----
[WARNING]
diff --git a/backend/recipe.go b/backend/recipe.go
index a3191c3..59b7366 100644
--- a/backend/recipe.go
+++ b/backend/recipe.go
@@ -6,12 +6,11 @@ import "strings"
type Ingredient struct {
Name string `json:"name"`
Amount float64 `json:"amount"`
- Unit string `json:"units"`
- Type string `json:"type"`
+ Unit string `json:"unit"`
}
type Step struct {
- Desc string `json:"instructions"`
+ Desc string `json:"instruction"`
Time int `json:"timer"`
}
diff --git a/recipeBuddy/src/app/add-recipe/add-recipe.component.ts b/recipeBuddy/src/app/add-recipe/add-recipe.component.ts
index 407997c..5109c34 100644
--- a/recipeBuddy/src/app/add-recipe/add-recipe.component.ts
+++ b/recipeBuddy/src/app/add-recipe/add-recipe.component.ts
@@ -7,6 +7,8 @@ import { FormArray } from '@angular/forms';
import { Validators } from '@angular/forms';
+import { Router } from '@angular/router';
+
import { Recipe } from '../DataModels/recipe';
import { Ingredient } from '../DataModels/ingredient'
import { Step } from '../DataModels/step';
@@ -43,7 +45,8 @@ export class AddRecipeComponent {
});
constructor(private fb: FormBuilder,
- private restService: BackendService
+ private restService: BackendService,
+ private router: Router,
) { }
ngOnInit() {
@@ -99,9 +102,9 @@ export class AddRecipeComponent {
}
var steps = []
- for (i = 0; i < formData.ingredients.length; i++) {
- var tmp_timer = parseInt(formData.steps[0].timer)
- steps.push(new Step(formData.steps[0].instruct,
+ for (i = 0; i < formData.steps.length; i++) {
+ var tmp_timer = parseInt(formData.steps[i].timer)
+ steps.push(new Step(formData.steps[i].instruct,
(isNaN(tmp_timer) ? 0 : tmp_timer)
));
}
@@ -118,9 +121,10 @@ export class AddRecipeComponent {
(isNaN(cookTimeTmp) ? 0 :cookTimeTmp), //cookTime
0, //timesCooked
0, //rating
- formData.tags.split(','), //tags
- formData.photos.split(',') //photos
+ formData.tags.split(',').filter(word=> !(word==="")), //tags
+ formData.photos.split(',').filter(word=> !(word==="")) //photos
);
- this.restService.createRecipe(recipe).subscribe()
+ this.restService.createRecipe(recipe).subscribe();
+ this.router.navigate(['/']);
}
}
diff --git a/recipeBuddy/src/app/app-routing.module.ts b/recipeBuddy/src/app/app-routing.module.ts
index bb7c96e..9620f04 100644
--- a/recipeBuddy/src/app/app-routing.module.ts
+++ b/recipeBuddy/src/app/app-routing.module.ts
@@ -3,11 +3,13 @@ import { RouterModule, Routes } from '@angular/router';
import { CookPageComponent } from './cook-page/cook-page.component';
import { AddRecipeComponent } from './add-recipe/add-recipe.component';
+import { EditRecipeComponent } from './edit-recipe/edit-recipe.component';
const routes: Routes = [
{ path: '', redirectTo: '/cook', pathMatch: 'full' },
{ path: 'cook', component: CookPageComponent },
- { path: 'add', component: AddRecipeComponent }
+ { path: 'add', component: AddRecipeComponent },
+ { path: 'edit', component: EditRecipeComponent },
];
@NgModule({
diff --git a/recipeBuddy/src/app/app.module.ts b/recipeBuddy/src/app/app.module.ts
index e6c3a27..83747b4 100644
--- a/recipeBuddy/src/app/app.module.ts
+++ b/recipeBuddy/src/app/app.module.ts
@@ -5,7 +5,6 @@ import { MatCardModule } from '@angular/material';
import { AppComponent } from './app.component';
import { CookPageComponent} from './cook-page/cook-page.component';
-import { StepCardComponent } from './cook-page/step-card/step-card.component';
import { AppRoutingModule } from './app-routing.module';
@@ -20,13 +19,14 @@ import { MatFormFieldModule } from '@angular/material';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { MatToolbarModule } from '@angular/material/toolbar';
+import { EditRecipeComponent } from './edit-recipe/edit-recipe.component';
@NgModule({
declarations: [
AppComponent,
CookPageComponent,
- StepCardComponent,
- AddRecipeComponent
+ AddRecipeComponent,
+ EditRecipeComponent
],
imports: [
BrowserModule,
diff --git a/recipeBuddy/src/app/edit-recipe/edit-recipe.component.css b/recipeBuddy/src/app/edit-recipe/edit-recipe.component.css
new file mode 100644
index 0000000..9d74c53
--- /dev/null
+++ b/recipeBuddy/src/app/edit-recipe/edit-recipe.component.css
@@ -0,0 +1,43 @@
+.form {
+ min-width: 150px;
+ max-width: 750px;
+ width: 95%;
+ margin-left: auto;
+ margin-right: auto;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+.full-width {
+ width: 100%;
+}
+
+.half-width {
+ width: 50%;
+ padding: 1%;
+ margin-left:auto;
+ margin-right:auto;
+}
+
+.quarter-width {
+ width: 25%;
+ padding: 1%;
+ margin-left:auto;
+ margin-right:auto;
+}
+
+.third-width {
+ width: 33%;
+ padding: 1%;
+ margin-left:auto;
+ margin-right:auto;
+}
+
+td {
+ padding-right: 8px;
+}
+
+.center {
+ margin-left:auto;
+ margin-right:auto;
+}
diff --git a/recipeBuddy/src/app/edit-recipe/edit-recipe.component.html b/recipeBuddy/src/app/edit-recipe/edit-recipe.component.html
new file mode 100644
index 0000000..a8f2e97
--- /dev/null
+++ b/recipeBuddy/src/app/edit-recipe/edit-recipe.component.html
@@ -0,0 +1,110 @@
+<form [formGroup]="recipeForm" class="form" (ngSubmit)="onSubmit()">
+<h2>Add Recipe</h2>
+ <mat-form-field class="full-width">
+ <input matInput placeholder="Name" type="text"
+ formControlName="recipeName" required>
+ <mat-hint>
+ Name is required
+ </mat-hint>
+ <mat-error>
+ Name is required
+ </mat-error>
+ </mat-form-field>
+ <mat-form-field class="full-width">
+ <textarea matInput placeholder="Description"
+ formControlName="desc"> TEST </textarea>
+ </mat-form-field>
+ <mat-form-field class="full-width">
+ <input matInput placeholder="Servings" type=text
+ formControlName="servingSize" pattern="^[0-9]*(\.[0-9]*)?$">
+ <mat-error>
+ Servings must be a number.
+ </mat-error>
+ </mat-form-field>
+ <mat-form-field class="full-width">
+ <input matInput placeholder="Cooking Time" type="text" formControlName="cookTime"
+ pattern="^[0-9]*$">
+ <span matSuffix>Minutes</span>
+ <mat-error>
+ Must be in the form hh:mm
+ </mat-error>
+ </mat-form-field>
+ <mat-form-field class="full-width" floatLabel="options.value.floatLabel">
+ <mat-label>Keywords/Tags</mat-label>
+ <input matInput placeholder="Separate with a comma" type="text" formControlName="tags">
+ </mat-form-field>
+ <mat-form-field class="full-width" floatLabel="options.value.floatLabel">
+ <mat-label>Photos (URLS)</mat-label>
+ <input matInput placeholder="Separate with a comma" type="text" formControlName="photos">
+ </mat-form-field>
+
+ <div formArrayName="ingredients">
+ <h3>Ingredients</h3>
+ <div *ngFor="let ingr of ingredients.controls; let i=index">
+ <div [formGroupName]="i">
+ <h4>Ingredient {{ i + 1 }}</h4>
+ <div class="full-width">
+ <mat-form-field class="quarter-width">
+ <input matInput placeholder="Name" type="text"
+ formControlName="name">
+ </mat-form-field>
+ <mat-form-field class="quarter-width">
+ <input matInput placeholder="Amount"
+ type="text"
+ formControlName="amount" pattern="^[0-9]*(\.[0-9]*)?$">
+ <mat-error>
+ Amount must be a number.
+ </mat-error>
+ </mat-form-field>
+ <mat-form-field class="quarter-width">
+ <input matInput placeholder="Units" type="text"
+ formControlName="unit">
+ </mat-form-field>
+ <button matSuffix mat-mini-fab (click)="rmIngredient(i)"
+ type="button" style="margin-left: 10px">
+ <mat-icon>remove</mat-icon>
+ </button>
+ </div>
+ </div>
+ </div>
+ <div style="text-align: center">
+ <button mat-mini-fab (click)="addIngredient()"
+ type="button">
+ <mat-icon>add</mat-icon>
+ </button>
+ </div>
+ </div>
+
+ <div formArrayName="steps">
+ <h3>Steps</h3>
+ <div *ngFor="let address of steps.controls; let i=index">
+ <div [formGroupName]="i">
+ <h4>Step {{ i + 1 }}</h4>
+ <div class="ful-width">
+ <mat-form-field class="half-width">
+ <textarea matInput placeholder="Instructions" type="text"
+ formControlName="instruction">
+ </textarea>
+ </mat-form-field>
+ <mat-form-field class="quarter-width">
+ <input matInput placeholder="Timer" type="text"
+ formControlName="timer" pattern="^[0-9]*$">
+ <span matSuffix>Minutes</span>
+ </mat-form-field>
+ <button matSuffix mat-mini-fab (click)="rmStep(i)"
+ type="button" style="margin-left: 10px">
+ <mat-icon>remove</mat-icon>
+ </button>
+ </div>
+ </div>
+ </div>
+ <div style="text-align: center">
+ <button mat-mini-fab (click)="addStep()" matSuffix type="button">
+ <mat-icon>add</mat-icon>
+ </button>
+ </div>
+ </div>
+ <button mat-flat-button color="primary" type="submit"
+ [disabled]="!recipeForm.valid" style="margin-right: 5px">Update</button>
+ <button mat-flat-button color="primary" (click)="onCancel()" >Cancel</button>
+</form>
diff --git a/recipeBuddy/src/app/edit-recipe/edit-recipe.component.spec.ts b/recipeBuddy/src/app/edit-recipe/edit-recipe.component.spec.ts
new file mode 100644
index 0000000..e92d28b
--- /dev/null
+++ b/recipeBuddy/src/app/edit-recipe/edit-recipe.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { EditRecipeComponent } from './edit-recipe.component';
+
+describe('EditRecipeComponent', () => {
+ let component: EditRecipeComponent;
+ let fixture: ComponentFixture<EditRecipeComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ EditRecipeComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(EditRecipeComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/recipeBuddy/src/app/edit-recipe/edit-recipe.component.ts b/recipeBuddy/src/app/edit-recipe/edit-recipe.component.ts
new file mode 100644
index 0000000..203f733
--- /dev/null
+++ b/recipeBuddy/src/app/edit-recipe/edit-recipe.component.ts
@@ -0,0 +1,188 @@
+import { Component, OnInit } from '@angular/core';
+
+import { FormControl } from '@angular/forms';
+
+import { FormBuilder } from '@angular/forms';
+import { FormArray } from '@angular/forms';
+
+import { Validators } from '@angular/forms';
+
+import { Router } from '@angular/router';
+
+import { Recipe } from '../DataModels/recipe';
+import { Ingredient } from '../DataModels/ingredient'
+import { Step } from '../DataModels/step';
+import { BackendService } from '../REST_service/backend.service';
+
+@Component({
+ selector: 'app-edit-recipe',
+ templateUrl: './edit-recipe.component.html',
+ styleUrls: ['./edit-recipe.component.css']
+})
+export class EditRecipeComponent implements OnInit {
+
+ baseRecipe: Recipe = new Recipe (15, //id
+ '', //name
+ '', //description
+ [], //ingredients
+ [], //steps
+ 0, //servingSize
+ 0, //cookTime
+ 0, //timesCooked
+ 0, //rating
+ [], //tags
+ [] //photos
+ );
+
+ recipeForm = this.fb.group({
+ recipeName: ['', Validators.required],
+ desc: [''],
+ ingredients: this.fb.array([
+ this.fb.group({
+ name: [''],
+ amount: ['', Validators.pattern('^[0-9]*(\.[0-9]*)?$')],
+ unit: ['']
+ })
+ ]),
+ steps: this.fb.array([
+ this.fb.group({
+ instruction: [''],
+ timer: ['']
+ })
+ ]),
+ servingSize: ['', Validators.pattern('^[0-9]*(\.[0-9]*)?$')],
+ cookTime: ['', Validators.pattern('^[0-9]*$')],
+ tags: [''],
+ photos: ['']
+ });
+
+ constructor(private fb: FormBuilder,
+ private restService: BackendService,
+ private router: Router,
+ /*private passService: PassService,*/
+ )
+ {
+ restService.getRecipe(this.baseRecipe.id).subscribe(
+ res=> this.updateRecipe(res),
+ err=> console.log('EditRecipeComponent:restService:getRecipes: id='+ this.baseRecipe.id + 'err=' + err),
+ () => console.log('EditRecipe:restService:getRecipes: completed')
+ )
+
+ this.rmIngredient(0);
+ this.rmStep(0);
+ }
+
+ updateRecipe(r: Recipe)
+ {
+ var i: number;
+
+ this.recipeForm.patchValue(
+ {
+ recipeName: r.name,
+ desc: r.description,
+ servingSize: r.servingSize,
+ cookTime: r.cookTime,
+ tags: r.tags.join(','),
+ photos: r.photos.join(','),
+ }
+ )
+
+ console.log(r.tags.join(','));
+
+ for(i = 0; i < r.ingredients.length; i++) {
+ this.addIngredient();
+ this.ingredients.controls[0].setValue(r.ingredients[i]);
+ }
+ for(i = 0; i < r.steps.length; i++) {
+ this.addStep();
+ console.log(r.steps[i])
+ this.steps.controls[0].setValue(r.steps[i]);
+ }
+ }
+
+ ngOnInit() {
+ }
+
+ get ingredients() {
+ return this.recipeForm.get('ingredients') as FormArray;
+ }
+
+ addIngredient() {
+ this.ingredients.push(
+ this.fb.group({
+ name: [''],
+ amount: ['', Validators.pattern('^[0-9]*(\.[0-9]*)?$')],
+ unit: ['']
+ })
+ );
+ }
+
+ rmIngredient(i) {
+ this.ingredients.removeAt(i);
+ }
+
+ get steps() {
+ return this.recipeForm.get('steps') as FormArray;
+ }
+
+ addStep() {
+ this.steps.push(
+ this.fb.group({
+ instruction: [''],
+ timer: ['', Validators.pattern('^[0-9]*$')]
+ })
+ );
+ }
+
+ rmStep(i) {
+ this.steps.removeAt(i);
+ }
+
+ onSubmit() {
+ var formData = this.recipeForm.value;
+
+ var ingredients = []
+ var i;
+ for (i = 0; i < formData.ingredients.length; i++) {
+ var tmp_amount = parseFloat(formData.ingredients[0].amount)
+ ingredients.push(new Ingredient(formData.ingredients[0].name,
+ (isNaN(tmp_amount) ? 0 : tmp_amount),
+ formData.ingredients[0].unit,
+ ""
+ ));
+ }
+
+ var steps = []
+ for (i = 0; i < formData.steps.length; i++) {
+ var tmp_timer = parseInt(formData.steps[0].timer)
+ steps.push(new Step(formData.steps[0].instruction,
+ (isNaN(tmp_timer) ? 0 : tmp_timer)
+ ));
+ }
+
+ console.log(steps);
+
+ var servingsTmp = parseFloat(formData.servingSize)
+ var cookTimeTmp = parseInt(formData.cookTime)
+
+ var recipe = new Recipe (this.baseRecipe.id, //id
+ formData.recipeName, //name
+ formData.desc, //description
+ ingredients, //ingredients
+ steps, //steps
+ (isNaN(servingsTmp) ? 0 :servingsTmp), //servingSize
+ (isNaN(cookTimeTmp) ? 0 :cookTimeTmp), //cookTime
+ 0, //timesCooked
+ 0, //rating
+ formData.tags.split(',').filter(word => !(word==="")), //tags
+ formData.photos.split(',').filter(word => !(word==="")) //photos
+ );
+ console.log(recipe)
+ this.restService.updateRecipe(recipe).subscribe()
+ this.router.navigate(['/']);
+ }
+
+ onCancel() {
+ this.router.navigate(['/']);
+ }
+}