Bladeren bron

Prototype using Formik

Tatiana Inama 7 jaren geleden
bovenliggende
commit
08adb48d7d

+ 9 - 6
recipes/src/components/Input/index.tsx

@@ -19,7 +19,8 @@ type InputProps = {
 	button?: {
 		icon: string,
 		onClick: () => void,
-	}
+	},
+	field?: any,
 };
 
 const Input = ({
@@ -31,7 +32,8 @@ const Input = ({
 	type = 'text',
 	style = 'regular',
 	icon,
-	button
+	button,
+	field = { name: '', value: '', onBlur: ()=>{}, onChange: ()=>{}}
 }: InputProps) => {
 	const fieldClasses = classNames(
 		'cbk-input',
@@ -57,20 +59,21 @@ const Input = ({
 			}
 			<div className="cbk-input-box">
 				<TextField
-					label={label}
+					label={field.name || label}
 					textarea={textarea}
 					className={fieldClasses}
 					fullWidth={style === 'display'}
 				>
 					<Field
-						value={value}
+						value={field.value}
+						onBlur={field.onBlur}
 						//@ts-ignore
-						onChange={onChange}
-						onKeyDown={onKeyDown}
+						onChange={field.onChange}
 						type={type}
 						min={0}
 						rows={1}
 						placeholder={style === 'display' ? label : ''}
+						name={field.name}
 					/>
 				</TextField>
 			</div>

+ 187 - 0
recipes/src/components/RecipeForm/index.tsx

@@ -0,0 +1,187 @@
+import React, { ReactComponentElement, useState } from 'react';
+import { Formik, Field, FieldArray, FormikActions, FormikProps, FieldArrayRenderProps } from 'formik';
+import Recipe, { Ingredient, SubRecipe } from 'src/types/recipes';
+import { Grid, Row, Cell } from '@material/react-layout-grid';
+import './styles.scss';
+import sample_image from 'sample.png';
+
+type IngredientsListProps = {
+  ingredients: SubRecipe[],
+}
+
+type RecipeFormProps = {
+  initialValues: Recipe
+}
+
+const custom = (label: string, component = 'text') => ({field}: any) => (
+  <span>
+    <label>
+      {label}
+    </label>
+    {
+      component === 'text' ? 
+        <input {...field}/> :
+        <textarea {...field}/>
+    }
+  </span>
+);
+
+class IngredientsList extends React.Component<IngredientsListProps, {selectedTab: number}> {
+  constructor(props: IngredientsListProps) {
+    super(props);
+    this.state = {
+      selectedTab: 0
+    };
+  }
+
+  render() {
+    const ingredients = this.props.ingredients;
+    return (
+      <section className='ingredient-tabs'>
+
+        <ul className='tab-header'>
+          {
+            ingredients.map((subgroup: any, index: number) => (
+              <li className='tab' key={index} onClick={()=>{ this.setState({ selectedTab: index })}}>
+                {subgroup.name}
+              </li>
+            ))  
+          }
+        </ul>
+        <div>
+          {
+            ingredients[this.state.selectedTab].ingredients.map(i => i.name)
+          }
+        </div>
+      </section>
+    )
+  }
+}
+
+const Pls = ({form, remove, push}:any) => {
+  const [selectedTab, setSelectedTab] = useState(0);
+  return (
+    <div className='ingredient-tabs'>
+      <ul className='tab-header'>
+        {
+          form.values.ingredients.map((subrecipe: any, index: number) => (
+            <li
+              className={`tab${selectedTab === index ? ' tab--selected' : ''}`}
+              key={index}
+            >
+              <div className='tab__content' onClick={()=> setSelectedTab(index)}> 
+                <Field name={`ingredients[${index}].name`}/>
+              </div>
+              <button onClick={()=> remove(index)}>X</button>
+            </li>
+          ))
+        }
+        <li className='tab tab--add'>
+          <button onClick={()=> push({name: '', ingredients: []})}>+</button>
+        </li>
+      </ul>
+      {
+        form.values.ingredients[selectedTab].ingredients.map((i: any) => i.name + ' ')
+      }
+    </div>
+  )
+}
+
+const RenderForm = ({
+  values,
+  status,
+  handleChange,
+  handleSubmit
+}: any) => {
+  
+
+  return (
+    <Grid>
+      <form onSubmit={handleSubmit} className='cbk-recipe-form'>
+      <Row>
+        <Cell columns={2}>
+          <img src={sample_image} style={{ width: '100%' }}/>
+        </Cell>
+        <Cell columns={10}>
+          <Field name='name' render={custom('name')}/>
+  
+          <Field name='summary' render={custom('summary', 'textarea')}/>
+        </Cell>
+      </Row>
+      
+      <h5>Author Information</h5>
+      <section>
+        <Row>
+          <Cell columns={3}>
+            <Field name='author.name'/>
+          </Cell>
+          <Cell columns={3}>
+            <Field name='author.website'/>
+          </Cell>
+        </Row>
+      </section>
+  
+      <h5>Recipe Information</h5>
+      <section>
+        <Row>
+          <Cell columns={3}>
+            <Field name='details.preparationTime'/>
+          </Cell>
+          <Cell columns={3}>
+            <Field name='details.cookingTime'/>
+          </Cell>
+          <Cell columns={3}>
+            <Field name='details.servings' type='number'/>
+          </Cell>
+          <Cell columns={3}>
+            <Field name='details.url'/>
+          </Cell>
+          <Cell columns={12}>
+          </Cell>
+        </Row>
+      </section>
+  
+      <h5>Ingredients</h5>
+      
+      <section>
+        <FieldArray
+          name='ingredients'
+          component={Pls}
+        />
+      </section>
+  
+      <h5>Instructions</h5>
+      <section>
+        {
+          values.instructions.map((instruction: any, i: number) => (
+            <Row key={i}>
+              <Cell columns={12}>
+                <input
+                  type='text'
+                  id={`instructions[${i}]`}
+                  value={instruction}
+                  onChange={handleChange}
+                />
+              </Cell>
+            </Row>
+          ))
+        }
+      </section>
+      <button type='submit'>Submit</button>    
+      </form>
+    </Grid>
+    
+      
+  );
+}
+const RecipeForm = ({ initialValues }: RecipeFormProps) => (
+  <Formik
+    initialValues={initialValues}
+    onSubmit={(values: any, actions:any) => {
+      console.log('submit', values, actions)
+    }}
+    render={RenderForm}
+  />
+);
+
+export default RecipeForm;

+ 43 - 0
recipes/src/components/RecipeForm/styles.scss

@@ -0,0 +1,43 @@
+.cbk-recipe-form {
+  width: 100%;
+
+  input,
+  textarea {
+    width: 100%;
+    border: 0;
+    padding: 4px 0;
+    border-bottom: 1px solid #ccc;
+    background-color: transparent;
+  }
+
+  .ingredient-tabs {
+    
+    ul.tab-header {
+      display: flex;
+      width: 100%;
+      justify-content: space-evenly;
+
+      .tab {
+        width: 100%;
+        display: flex;
+        justify-content: space-between;
+        cursor: pointer;
+        align-self: center;
+        
+        &__content {
+          padding: 20px;
+          flex-basis: 90%;
+        }
+
+        &--add {
+          flex-basis: 0;
+        }
+
+        button {
+          margin: 20px;
+        }
+      }
+    }
+    
+  }
+}

+ 244 - 236
recipes/src/containers/Recipes/Create/index.tsx

@@ -6,6 +6,7 @@ import Btn from 'components/Button';
 import Input from 'components/Input';
 import TagInput from 'components/TagInput';
 import { Form as IngredientForm } from 'components/Ingredient';
+import RecipeForm from 'components/RecipeForm';
 
 import './styles.scss';
 
@@ -19,6 +20,7 @@ interface CreateRecipeProps {
 
 interface CreateRecipeState extends Recipe {
   scrapeUrl: string,
+  form: Recipe,
 };
 
 type FormKeys = keyof Recipe | keyof SubRecipe | keyof Ingredient | keyof Author | keyof Details | number;
@@ -28,241 +30,244 @@ class CreateRecipe extends React.Component<CreateRecipeProps, CreateRecipeState>
     super(props);
     this.state = { 
       ..._recipe,
-      ingredients: [
-        {
-          "name": "For the Chicken:",
-          "ingredients": [
-            {
-              "name": "thin boneless skinless chicken breast",
-              "quantity": 1.5,
-              "unit": "pound",
-              "_original": "1-1/2 lb of Thin Boneless Skinless Chicken Breast",
-              "suggestions": []
-            },
-            {
-              "name": "olive oil",
-              "quantity": 2,
-              "unit": "tablespoon",
-              "_original": "2 Tbsp of Olive Oil",
-              "suggestions": []
-            },
-            {
-              "name": "juice of  lime",
-              "quantity": 1,
-              "unit": "",
-              "_original": "Juice of 1 Lime",
-              "suggestions": []
-            },
-            {
-              "name": "chili powder",
-              "quantity": 0.5,
-              "unit": "teaspoon",
-              "_original": "1/2 tsp of Chili Powder",
-              "suggestions": [
-                {
-                  "_id": "5cf1397d72cd194524435041",
-                  "name": "cocoa powder",
-                  "variants": [
-                    "cocoa"
-                  ],
-                  "equivalence": 118,
-                  "referenceUnit": "cup",
-                  "prefferedUnit": "gr",
-                  "measure": 2
-                },
-                {
-                  "_id": "5cf1397d72cd19452443503c",
-                  "name": "icing sugar",
-                  "variants": [
-                    "confectioner sugar",
-                    "powdered sugar"
-                  ],
-                  "equivalence": 125,
-                  "referenceUnit": "cup",
-                  "prefferedUnit": "gr",
-                  "measure": 2
-                }
-              ]
-            },
-            {
-              "name": "oregano",
-              "quantity": 0.5,
-              "unit": "teaspoon",
-              "_original": "1/2 tsp of Oregano",
-              "suggestions": []
-            },
-            {
-              "name": "cumin",
-              "quantity": 0.5,
-              "unit": "teaspoon",
-              "_original": "1/2 tsp of Cumin",
-              "suggestions": []
-            },
-            {
-              "name": "paprika",
-              "quantity": 0.5,
-              "unit": "teaspoon",
-              "_original": "1/2 tsp of Paprika",
-              "suggestions": []
-            },
-            {
-              "name": "granulated garlic",
-              "quantity": 0.5,
-              "unit": "teaspoon",
-              "_original": "1/2 tsp of Granulated Garlic",
-              "suggestions": [
-                {
-                  "_id": "5cf1397d72cd19452443503b",
-                  "name": "granulated sugar",
-                  "variants": [
-                    "sugar",
-                    "plain sugar"
-                  ],
-                  "equivalence": 200,
-                  "referenceUnit": "cup",
-                  "prefferedUnit": "gr",
-                  "measure": 2
-                }
-              ]
-            },
-            {
-              "name": "salt, to taste",
-              "quantity": 0,
-              "unit": "",
-              "_original": "Salt, to taste",
-              "suggestions": []
-            }
-          ]
-        },
-        {
-          "name": "For the Dressing:",
-          "ingredients": [
-            {
-              "name": "plain greek yogurt",
-              "quantity": 0.5,
-              "unit": "cup",
-              "_original": "1/2 cup of Plain Greek Yogurt",
-              "suggestions": [
-                {
-                  "_id": "5cf1397d72cd194524435040",
-                  "name": "yogurt",
-                  "variants": [
-                    "plain yogurt"
-                  ],
-                  "equivalence": 245,
-                  "referenceUnit": "cup",
-                  "prefferedUnit": "gr",
-                  "measure": 2
-                },
-                {
-                  "_id": "5cf1397d72cd19452443503b",
-                  "name": "granulated sugar",
-                  "variants": [
-                    "sugar",
-                    "plain sugar"
-                  ],
-                  "equivalence": 200,
-                  "referenceUnit": "cup",
-                  "prefferedUnit": "gr",
-                  "measure": 2
-                },
-                {
-                  "_id": "5cf1397d72cd194524435030",
-                  "name": "all purpose flour",
-                  "variants": [
-                    "plain flour",
-                    "all purpose flour",
-                    "regular flour",
-                    "flour"
-                  ],
-                  "equivalence": 125,
-                  "referenceUnit": "cup",
-                  "prefferedUnit": "gr",
-                  "translation": {
-                    "dutch": "patentbloem"
+      form: {
+        ..._recipe,
+        ingredients: [
+          {
+            "name": "For the Chicken:",
+            "ingredients": [
+              {
+                "name": "thin boneless skinless chicken breast",
+                "quantity": 1.5,
+                "unit": "pound",
+                "_original": "1-1/2 lb of Thin Boneless Skinless Chicken Breast",
+                "suggestions": []
+              },
+              {
+                "name": "olive oil",
+                "quantity": 2,
+                "unit": "tablespoon",
+                "_original": "2 Tbsp of Olive Oil",
+                "suggestions": []
+              },
+              {
+                "name": "juice of  lime",
+                "quantity": 1,
+                "unit": "",
+                "_original": "Juice of 1 Lime",
+                "suggestions": []
+              },
+              {
+                "name": "chili powder",
+                "quantity": 0.5,
+                "unit": "teaspoon",
+                "_original": "1/2 tsp of Chili Powder",
+                "suggestions": [
+                  {
+                    "_id": "5cf1397d72cd194524435041",
+                    "name": "cocoa powder",
+                    "variants": [
+                      "cocoa"
+                    ],
+                    "equivalence": 118,
+                    "referenceUnit": "cup",
+                    "prefferedUnit": "gr",
+                    "measure": 2
                   },
-                  "measure": 2
-                }
-              ]
-            },
-            {
-              "name": "fresh cilantro",
-              "quantity": 1,
-              "unit": "cup",
-              "_original": "1 cup of Fresh Cilantro",
-              "suggestions": []
-            },
-            {
-              "name": "scallions, roughly chopped",
-              "quantity": 2,
-              "unit": "",
-              "_original": "2 Scallions, roughly chopped",
-              "suggestions": []
-            },
-            {
-              "name": "juice of  lime or more, according to taste",
-              "quantity": 1,
-              "unit": "",
-              "_original": "Juice of 1 Lime or more, according to taste",
-              "suggestions": []
-            },
-            {
-              "name": "olive oil",
-              "quantity": 1,
-              "unit": "tablespoon",
-              "_original": "1 Tbsp of Olive Oil",
-              "suggestions": []
-            },
-            {
-              "name": "salt, to taste",
-              "quantity": 0,
-              "unit": "",
-              "_original": "Salt, to taste",
-              "suggestions": []
-            }
-          ]
-        },
-        {
-          "name": "For the rest of the salad:",
-          "ingredients": [
-            {
-              "name": "fresh lettuce of your choice",
-              "quantity": 0,
-              "unit": "",
-              "_original": "Fresh Lettuce of your choice",
-              "suggestions": []
-            },
-            {
-              "name": "bell peppers, halved and seeded",
-              "quantity": 2,
-              "unit": "",
-              "_original": "2 Bell Peppers, halved and seeded",
-              "suggestions": []
-            },
-            {
-              "name": "scallions or red onion, sliced",
-              "quantity": 0,
-              "unit": "",
-              "_original": "Scallions or REd Onion, sliced",
-              "suggestions": []
-            },
-            {
-              "name": "pico de gallo salsa",
-              "quantity": 0.5,
-              "unit": "cup",
-              "_original": "1/2 cup of Pico De Gallo Salsa",
-              "suggestions": []
-            },
-            {
-              "name": "avocado, sliced",
-              "quantity": 1,
-              "unit": "",
-              "_original": "1 Avocado, sliced",
-              "suggestions": []
-            }
-          ]
-        }
-      ],
+                  {
+                    "_id": "5cf1397d72cd19452443503c",
+                    "name": "icing sugar",
+                    "variants": [
+                      "confectioner sugar",
+                      "powdered sugar"
+                    ],
+                    "equivalence": 125,
+                    "referenceUnit": "cup",
+                    "prefferedUnit": "gr",
+                    "measure": 2
+                  }
+                ]
+              },
+              {
+                "name": "oregano",
+                "quantity": 0.5,
+                "unit": "teaspoon",
+                "_original": "1/2 tsp of Oregano",
+                "suggestions": []
+              },
+              {
+                "name": "cumin",
+                "quantity": 0.5,
+                "unit": "teaspoon",
+                "_original": "1/2 tsp of Cumin",
+                "suggestions": []
+              },
+              {
+                "name": "paprika",
+                "quantity": 0.5,
+                "unit": "teaspoon",
+                "_original": "1/2 tsp of Paprika",
+                "suggestions": []
+              },
+              {
+                "name": "granulated garlic",
+                "quantity": 0.5,
+                "unit": "teaspoon",
+                "_original": "1/2 tsp of Granulated Garlic",
+                "suggestions": [
+                  {
+                    "_id": "5cf1397d72cd19452443503b",
+                    "name": "granulated sugar",
+                    "variants": [
+                      "sugar",
+                      "plain sugar"
+                    ],
+                    "equivalence": 200,
+                    "referenceUnit": "cup",
+                    "prefferedUnit": "gr",
+                    "measure": 2
+                  }
+                ]
+              },
+              {
+                "name": "salt, to taste",
+                "quantity": 0,
+                "unit": "",
+                "_original": "Salt, to taste",
+                "suggestions": []
+              }
+            ]
+          },
+          {
+            "name": "For the Dressing:",
+            "ingredients": [
+              {
+                "name": "plain greek yogurt",
+                "quantity": 0.5,
+                "unit": "cup",
+                "_original": "1/2 cup of Plain Greek Yogurt",
+                "suggestions": [
+                  {
+                    "_id": "5cf1397d72cd194524435040",
+                    "name": "yogurt",
+                    "variants": [
+                      "plain yogurt"
+                    ],
+                    "equivalence": 245,
+                    "referenceUnit": "cup",
+                    "prefferedUnit": "gr",
+                    "measure": 2
+                  },
+                  {
+                    "_id": "5cf1397d72cd19452443503b",
+                    "name": "granulated sugar",
+                    "variants": [
+                      "sugar",
+                      "plain sugar"
+                    ],
+                    "equivalence": 200,
+                    "referenceUnit": "cup",
+                    "prefferedUnit": "gr",
+                    "measure": 2
+                  },
+                  {
+                    "_id": "5cf1397d72cd194524435030",
+                    "name": "all purpose flour",
+                    "variants": [
+                      "plain flour",
+                      "all purpose flour",
+                      "regular flour",
+                      "flour"
+                    ],
+                    "equivalence": 125,
+                    "referenceUnit": "cup",
+                    "prefferedUnit": "gr",
+                    "translation": {
+                      "dutch": "patentbloem"
+                    },
+                    "measure": 2
+                  }
+                ]
+              },
+              {
+                "name": "fresh cilantro",
+                "quantity": 1,
+                "unit": "cup",
+                "_original": "1 cup of Fresh Cilantro",
+                "suggestions": []
+              },
+              {
+                "name": "scallions, roughly chopped",
+                "quantity": 2,
+                "unit": "",
+                "_original": "2 Scallions, roughly chopped",
+                "suggestions": []
+              },
+              {
+                "name": "juice of  lime or more, according to taste",
+                "quantity": 1,
+                "unit": "",
+                "_original": "Juice of 1 Lime or more, according to taste",
+                "suggestions": []
+              },
+              {
+                "name": "olive oil",
+                "quantity": 1,
+                "unit": "tablespoon",
+                "_original": "1 Tbsp of Olive Oil",
+                "suggestions": []
+              },
+              {
+                "name": "salt, to taste",
+                "quantity": 0,
+                "unit": "",
+                "_original": "Salt, to taste",
+                "suggestions": []
+              }
+            ]
+          },
+          {
+            "name": "For the rest of the salad:",
+            "ingredients": [
+              {
+                "name": "fresh lettuce of your choice",
+                "quantity": 0,
+                "unit": "",
+                "_original": "Fresh Lettuce of your choice",
+                "suggestions": []
+              },
+              {
+                "name": "bell peppers, halved and seeded",
+                "quantity": 2,
+                "unit": "",
+                "_original": "2 Bell Peppers, halved and seeded",
+                "suggestions": []
+              },
+              {
+                "name": "scallions or red onion, sliced",
+                "quantity": 0,
+                "unit": "",
+                "_original": "Scallions or REd Onion, sliced",
+                "suggestions": []
+              },
+              {
+                "name": "pico de gallo salsa",
+                "quantity": 0.5,
+                "unit": "cup",
+                "_original": "1/2 cup of Pico De Gallo Salsa",
+                "suggestions": []
+              },
+              {
+                "name": "avocado, sliced",
+                "quantity": 1,
+                "unit": "",
+                "_original": "1 Avocado, sliced",
+                "suggestions": []
+              }
+            ]
+          }
+        ],
+      },
       scrapeUrl: '',
     }
   }
@@ -367,7 +372,10 @@ class CreateRecipe extends React.Component<CreateRecipeProps, CreateRecipeState>
         </Navbar>
         
         <div className="cbk-create-recipe">
-          <Grid>
+          <RecipeForm
+            initialValues={this.state.form}
+          />
+          {/* <Grid>
             <Row>
               <Cell columns={2}>
                 <img src={sample_img} style={{ width: '100%' }}/>
@@ -490,7 +498,7 @@ class CreateRecipe extends React.Component<CreateRecipeProps, CreateRecipeState>
                 <Btn raised unelevated>Create</Btn>
               </Cell>
             </Row>
-          </Grid>
+          </Grid> */}
         </div>
       </div>
     )