summaryrefslogtreecommitdiff
path: root/recipeBuddy/src
diff options
context:
space:
mode:
Diffstat (limited to 'recipeBuddy/src')
-rw-r--r--recipeBuddy/src/app/DataModels/recipe.ts14
-rw-r--r--recipeBuddy/src/app/DataModels/step.ts2
-rw-r--r--recipeBuddy/src/app/add-recipe/add-recipe.component.css43
-rw-r--r--recipeBuddy/src/app/add-recipe/add-recipe.component.html109
-rw-r--r--recipeBuddy/src/app/add-recipe/add-recipe.component.spec.ts25
-rw-r--r--recipeBuddy/src/app/add-recipe/add-recipe.component.ts126
-rw-r--r--recipeBuddy/src/app/app-routing.module.ts4
-rw-r--r--recipeBuddy/src/app/app.module.ts22
-rw-r--r--recipeBuddy/src/index.html2
-rw-r--r--recipeBuddy/src/styles.css3
10 files changed, 344 insertions, 6 deletions
diff --git a/recipeBuddy/src/app/DataModels/recipe.ts b/recipeBuddy/src/app/DataModels/recipe.ts
index 368f237..937153f 100644
--- a/recipeBuddy/src/app/DataModels/recipe.ts
+++ b/recipeBuddy/src/app/DataModels/recipe.ts
@@ -14,7 +14,17 @@ export class Recipe {
private tags: string[];
private photos: string[];
- public constructor(id: number, name: string, description: string, ingredients: Ingredient[], steps: Step[], servingSize: number, cookTime: number, rating: number, tags: string[]) {
+ public constructor(id: number,
+ name: string,
+ description: string,
+ ingredients: Ingredient[],
+ steps: Step[],
+ servingSize: number,
+ cookTime: number,
+ timesCooked: number,
+ rating: number,
+ tags: string[],
+ photos: string[]) {
this.id = id;
this.name = name;
this.description = description;
@@ -24,6 +34,8 @@ export class Recipe {
this.cookTime = cookTime;
this.rating = rating;
this.tags = tags;
+ this.photos = photos;
+ this.timesCooked = timesCooked;
}
public getId(): number {
diff --git a/recipeBuddy/src/app/DataModels/step.ts b/recipeBuddy/src/app/DataModels/step.ts
index 1c1ca7b..67e14c1 100644
--- a/recipeBuddy/src/app/DataModels/step.ts
+++ b/recipeBuddy/src/app/DataModels/step.ts
@@ -2,7 +2,7 @@ export class Step {
private instruction: string;
private timer: number;
- public contructor(instruction: string, timer: number) {
+ public constructor(instruction: string, timer: number) {
this.instruction = instruction;
this.timer = timer;
}
diff --git a/recipeBuddy/src/app/add-recipe/add-recipe.component.css b/recipeBuddy/src/app/add-recipe/add-recipe.component.css
new file mode 100644
index 0000000..9d74c53
--- /dev/null
+++ b/recipeBuddy/src/app/add-recipe/add-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/add-recipe/add-recipe.component.html b/recipeBuddy/src/app/add-recipe/add-recipe.component.html
new file mode 100644
index 0000000..76095f9
--- /dev/null
+++ b/recipeBuddy/src/app/add-recipe/add-recipe.component.html
@@ -0,0 +1,109 @@
+<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="ingrName">
+ </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="units">
+ </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="instruct">
+ </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">Submit</button>
+</form>
diff --git a/recipeBuddy/src/app/add-recipe/add-recipe.component.spec.ts b/recipeBuddy/src/app/add-recipe/add-recipe.component.spec.ts
new file mode 100644
index 0000000..86b2da6
--- /dev/null
+++ b/recipeBuddy/src/app/add-recipe/add-recipe.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AddRecipeComponent } from './add-recipe.component';
+
+describe('AddRecipeComponent', () => {
+ let component: AddRecipeComponent;
+ let fixture: ComponentFixture<AddRecipeComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ AddRecipeComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(AddRecipeComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/recipeBuddy/src/app/add-recipe/add-recipe.component.ts b/recipeBuddy/src/app/add-recipe/add-recipe.component.ts
new file mode 100644
index 0000000..407997c
--- /dev/null
+++ b/recipeBuddy/src/app/add-recipe/add-recipe.component.ts
@@ -0,0 +1,126 @@
+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 { Recipe } from '../DataModels/recipe';
+import { Ingredient } from '../DataModels/ingredient'
+import { Step } from '../DataModels/step';
+import { BackendService } from '../REST_service/backend.service';
+
+@Component({
+ selector: 'app-add-recipe',
+ templateUrl: './add-recipe.component.html',
+ styleUrls: ['./add-recipe.component.css']
+})
+
+export class AddRecipeComponent {
+
+ recipeForm = this.fb.group({
+ recipeName: ['', Validators.required],
+ desc: [''],
+ ingredients: this.fb.array([
+ this.fb.group({
+ ingrName: [''],
+ amount: ['', Validators.pattern('^[0-9]*(\.[0-9]*)?$')],
+ units: ['']
+ })
+ ]),
+ steps: this.fb.array([
+ this.fb.group({
+ instruct: [''],
+ timer: ['']
+ })
+ ]),
+ servingSize: ['', Validators.pattern('^[0-9]*(\.[0-9]*)?$')],
+ cookTime: ['', Validators.pattern('^[0-9]*$')],
+ tags: [''],
+ photos: ['']
+ });
+
+ constructor(private fb: FormBuilder,
+ private restService: BackendService
+ ) { }
+
+ ngOnInit() {
+ }
+
+ get ingredients() {
+ return this.recipeForm.get('ingredients') as FormArray;
+ }
+
+ addIngredient() {
+ this.ingredients.push(
+ this.fb.group({
+ ingrName: [''],
+ amount: ['', Validators.pattern('^[0-9]*(\.[0-9]*)?$')],
+ units: ['']
+ })
+ );
+ }
+
+ rmIngredient(i) {
+ this.ingredients.removeAt(i);
+ }
+
+ get steps() {
+ return this.recipeForm.get('steps') as FormArray;
+ }
+
+ addStep() {
+ this.steps.push(
+ this.fb.group({
+ instruct: [''],
+ 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].ingrName,
+ (isNaN(tmp_amount) ? 0 : tmp_amount),
+ formData.ingredients[0].unit,
+ ""
+ ));
+ }
+
+ 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,
+ (isNaN(tmp_timer) ? 0 : tmp_timer)
+ ));
+ }
+
+ var servingsTmp = parseFloat(formData.servingSize)
+ var cookTimeTmp = parseInt(formData.cookTime)
+
+ var recipe = new Recipe (0, //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(','), //tags
+ formData.photos.split(',') //photos
+ );
+ this.restService.createRecipe(recipe).subscribe()
+ }
+}
diff --git a/recipeBuddy/src/app/app-routing.module.ts b/recipeBuddy/src/app/app-routing.module.ts
index a6e4399..bb7c96e 100644
--- a/recipeBuddy/src/app/app-routing.module.ts
+++ b/recipeBuddy/src/app/app-routing.module.ts
@@ -2,10 +2,12 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CookPageComponent } from './cook-page/cook-page.component';
+import { AddRecipeComponent } from './add-recipe/add-recipe.component';
const routes: Routes = [
{ path: '', redirectTo: '/cook', pathMatch: 'full' },
- { path: 'cook', component: CookPageComponent }
+ { path: 'cook', component: CookPageComponent },
+ { path: 'add', component: AddRecipeComponent }
];
@NgModule({
diff --git a/recipeBuddy/src/app/app.module.ts b/recipeBuddy/src/app/app.module.ts
index eaa0553..359254e 100644
--- a/recipeBuddy/src/app/app.module.ts
+++ b/recipeBuddy/src/app/app.module.ts
@@ -9,19 +9,35 @@ import { StepCardComponent } from './cook-page/step-card/step-card.component';
import { AppRoutingModule } from './app-routing.module';
-import {HttpClientModule } from '@angular/common/http'
+import { HttpClientModule } from '@angular/common/http';
+import { AddRecipeComponent } from './add-recipe/add-recipe.component';
+
+import { ReactiveFormsModule } from '@angular/forms';
+import { NoopAnimationsModule } from '@angular/platform-browser/animations';
+
+import { MatInputModule } from '@angular/material/input';
+import { MatFormFieldModule } from '@angular/material';
+import { MatIconModule } from '@angular/material/icon';
+import { MatButtonModule } from '@angular/material/button';
@NgModule({
declarations: [
AppComponent,
CookPageComponent,
- StepCardComponent
+ StepCardComponent,
+ AddRecipeComponent
],
imports: [
BrowserModule,
AppRoutingModule,
MatCardModule,
- HttpClientModule
+ HttpClientModule,
+ ReactiveFormsModule,
+ NoopAnimationsModule,
+ MatInputModule,
+ MatFormFieldModule,
+ MatIconModule,
+ MatButtonModule
],
providers: [],
bootstrap: [AppComponent]
diff --git a/recipeBuddy/src/index.html b/recipeBuddy/src/index.html
index 122efbf..29b1c1b 100644
--- a/recipeBuddy/src/index.html
+++ b/recipeBuddy/src/index.html
@@ -6,6 +6,8 @@
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
+ <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500&display=swap" rel="stylesheet">
+ <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body>
<app-root></app-root>
diff --git a/recipeBuddy/src/styles.css b/recipeBuddy/src/styles.css
index 90d4ee0..7e7239a 100644
--- a/recipeBuddy/src/styles.css
+++ b/recipeBuddy/src/styles.css
@@ -1 +1,4 @@
/* You can add global styles to this file, and also import other style files */
+
+html, body { height: 100%; }
+body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }