Jelajahi Sumber

Improve Edit Recipe types

Tatiana Inama 7 tahun lalu
induk
melakukan
c5e9946cd8

+ 3 - 1
ktchn/src/recipes/controller.ts

@@ -5,6 +5,7 @@ import { FilterQuery } from 'mongodb';
 import Scrape from './scrape/index';
 import Scrape from './scrape/index';
 import { ScrapedRecipe } from './model';
 import { ScrapedRecipe } from './model';
 import Ingredient from '../ingredients/model';
 import Ingredient from '../ingredients/model';
+import { dissoc } from 'ramda';
 
 
 function validRecipe(data: any): Promise<Recipe> {
 function validRecipe(data: any): Promise<Recipe> {
   return new Promise(function(resolve, reject) {
   return new Promise(function(resolve, reject) {
@@ -91,7 +92,8 @@ const getByIngredients: Controller = (db) => ({ query }, res) => {
 }
 }
 
 
 const update: Controller = (db) => ({params, body}, res) => {
 const update: Controller = (db) => ({params, body}, res) => {
-  return db.update<Recipe>(params.id, body).then(result => res.json(result))
+  const newRecipe = dissoc('_id', body) as Recipe; 
+  return db.update<Recipe>(params.id, newRecipe).then(result => res.json(result))
 }
 }
 
 
 export {
 export {

+ 6 - 6
recipes/src/components/RecipeForm/index.tsx

@@ -1,6 +1,6 @@
 import React, { useState, Component } from 'react';
 import React, { useState, Component } from 'react';
 
 
-import Recipe, { Ingredient, Suggestion, _ingredient, _subRecipe } from 'types/recipes';
+import Recipe, { Ingredient, Suggestion, _ingredient, _subRecipe, DBRecipe } from 'types/recipes';
 import { Grid, Row, Cell } from '@material/react-layout-grid';
 import { Grid, Row, Cell } from '@material/react-layout-grid';
 import './styles.scss';
 import './styles.scss';
 import sample_image from 'sample.png';
 import sample_image from 'sample.png';
@@ -10,9 +10,9 @@ import Button from 'components/Button';
 //@ts-ignore
 //@ts-ignore
 import { Field, FieldArray, FormikProps, ArrayHelpers, Formik } from 'formik';
 import { Field, FieldArray, FormikProps, ArrayHelpers, Formik } from 'formik';
 
 
-type RecipeFormProps = {
-  initialValues: Recipe,
-  onSubmit: (recipe: Recipe) => void
+type RecipeFormProps<T> = {
+  initialValues: T,
+  onSubmit: (data: T) => void
 }
 }
 
 
 const convertIngredient = (ingredient: Ingredient, suggestion: Suggestion): Ingredient => {
 const convertIngredient = (ingredient: Ingredient, suggestion: Suggestion): Ingredient => {
@@ -151,7 +151,7 @@ const RenderForm = ({
   values,
   values,
   handleChange,
   handleChange,
   handleSubmit
   handleSubmit
-}: FormikProps<Recipe>) => {
+}: FormikProps<Recipe|DBRecipe>) => {
   return (
   return (
     <Grid>
     <Grid>
       <form onSubmit={handleSubmit} className='cbk-recipe-form'>
       <form onSubmit={handleSubmit} className='cbk-recipe-form'>
@@ -236,7 +236,7 @@ const RenderForm = ({
   );
   );
 }
 }
 
 
-const RecipeForm = ({ initialValues, onSubmit }: RecipeFormProps) => (
+const RecipeForm = <T extends Recipe|DBRecipe>({ initialValues, onSubmit }: RecipeFormProps<T>) => (
   <Formik
   <Formik
     enableReinitialize
     enableReinitialize
     initialValues={initialValues}
     initialValues={initialValues}

+ 11 - 9
recipes/src/containers/Recipes/Edit/index.tsx

@@ -5,35 +5,37 @@ import RecipeForm from 'components/RecipeForm';
 
 
 import './styles.scss';
 import './styles.scss';
 
 
-import Recipe, { SubRecipe, Author, Details, _recipe, _subRecipe, _ingredient, Ingredient } from 'types/recipes';
-import { getRecipeById, saveRecipe } from '../services';
+import Recipe, { SubRecipe, Author, Details, _recipe, _subRecipe, _ingredient, Ingredient, DBRecipe } from 'types/recipes';
+import { getRecipeById, updateRecipe } from '../services';
 import { RouteComponentProps } from 'react-router';
 import { RouteComponentProps } from 'react-router';
 
 
 interface EditRecipeProps extends RouteComponentProps<{id: string}> {
 interface EditRecipeProps extends RouteComponentProps<{id: string}> {
 
 
 };
 };
 
 
-interface EdirRecipeState {
-  form: Recipe,
+interface EditRecipeState {
+  form: DBRecipe,
 };
 };
 
 
-class EditRecipe extends React.Component<EditRecipeProps, EdirRecipeState> {
+class EditRecipe extends React.Component<EditRecipeProps, EditRecipeState> {
   constructor(props: EditRecipeProps) {
   constructor(props: EditRecipeProps) {
     super(props);
     super(props);
     this.state = { 
     this.state = { 
       form: {
       form: {
         ..._recipe,
         ..._recipe,
+        _id: '',
       }
       }
     }
     }
   }
   }
 
 
   componentDidMount = () => {
   componentDidMount = () => {
     getRecipeById(this.props.match.params.id).then(recipe => this.setState({ form: recipe }))
     getRecipeById(this.props.match.params.id).then(recipe => this.setState({ form: recipe }))
+
   }
   }
 
 
-  saveRecipe = (recipe: Recipe) => {
-    saveRecipe(recipe)
-      .then(response => {
+  saveRecipe = (recipe: DBRecipe) => {
+    updateRecipe(recipe)
+      .then((response: any) => {
         if (response.status === 200) {
         if (response.status === 200) {
           this.props.history.push('/recipes')
           this.props.history.push('/recipes')
         } else {
         } else {
@@ -53,7 +55,7 @@ class EditRecipe extends React.Component<EditRecipeProps, EdirRecipeState> {
         <div className="cbk-create-recipe">
         <div className="cbk-create-recipe">
           <RecipeForm
           <RecipeForm
             initialValues={form}
             initialValues={form}
-            onSubmit={(recipe) => this.saveRecipe(recipe)}
+            onSubmit={(recipe: DBRecipe) => this.saveRecipe(recipe)}
           />
           />
         </div>
         </div>
       </div>
       </div>

+ 1 - 1
recipes/src/containers/Recipes/List/actions.ts

@@ -17,7 +17,7 @@ export const receiveRecipes = (json: Recipe[]) => ({
   payload: json,
   payload: json,
 });
 });
 
 
-export const selectRecipe = (recipe: Recipe) => ({
+export const selectRecipe = (recipe?: Recipe) => ({
   type: SELECT_RECIPE,
   type: SELECT_RECIPE,
   payload: recipe,
   payload: recipe,
 });
 });

+ 13 - 7
recipes/src/containers/Recipes/List/index.tsx

@@ -9,17 +9,17 @@ import { Grid, Row, Cell } from "@material/react-layout-grid";
 import Button from "components/Button";
 import Button from "components/Button";
 import Card from 'components/Card';
 import Card from 'components/Card';
 import RecipeCard from 'components/RecipeCard';
 import RecipeCard from 'components/RecipeCard';
-import Recipe from 'types/recipes';
+import Recipe, { DBRecipe } from 'types/recipes';
 import Navbar from 'components/Navbar';
 import Navbar from 'components/Navbar';
 import { Link, RouteComponentProps } from 'react-router-dom';
 import { Link, RouteComponentProps } from 'react-router-dom';
 
 
 interface RecipeListProps extends RouteComponentProps {
 interface RecipeListProps extends RouteComponentProps {
-  data: Recipe[],
+  data: DBRecipe[],
   isFetching: boolean,
   isFetching: boolean,
   selectedRecipe: any | undefined,
   selectedRecipe: any | undefined,
   fetchRecipes: (query: any) => undefined,
   fetchRecipes: (query: any) => undefined,
-  receiveRecipes: (recipes: Recipe[]) => undefined,
-  selectRecipe: (recipe: Recipe) => undefined,
+  receiveRecipes: (recipes: DBRecipe[]) => undefined,
+  selectRecipe: (recipe?: DBRecipe) => undefined,
 };
 };
 
 
 class RecipeList extends Component<RecipeListProps, {phoneDisplay: boolean}> {
 class RecipeList extends Component<RecipeListProps, {phoneDisplay: boolean}> {
@@ -42,10 +42,15 @@ class RecipeList extends Component<RecipeListProps, {phoneDisplay: boolean}> {
     }
     }
   }
   }
 
 
-  handleRecipeSelection(recipe: Recipe) {
+  cleanRecipeSelection() {
+    this.props.selectRecipe();
+  }
+
+  handleRecipeSelection(recipe: DBRecipe) {
     return (event: React.MouseEvent) => {
     return (event: React.MouseEvent) => {
       if (this.state.phoneDisplay) {
       if (this.state.phoneDisplay) {
         this.props.history.push('/recipes/view/' + recipe._id)
         this.props.history.push('/recipes/view/' + recipe._id)
+        this.cleanRecipeSelection();
       } else {
       } else {
         this.props.selectRecipe(recipe) 
         this.props.selectRecipe(recipe) 
       }
       }
@@ -54,6 +59,7 @@ class RecipeList extends Component<RecipeListProps, {phoneDisplay: boolean}> {
 
 
   handleEditRecipe = (id = '') => (event: React.MouseEvent) => {
   handleEditRecipe = (id = '') => (event: React.MouseEvent) => {
     this.props.history.push('/recipes/edit/' + id)
     this.props.history.push('/recipes/edit/' + id)
+    this.cleanRecipeSelection();
   }
   }
 
 
   handler = (event: React.MouseEvent) => {
   handler = (event: React.MouseEvent) => {
@@ -127,10 +133,10 @@ const mapDispatchToProps = (dispatch: any) => {
     fetchRecipes: (query: any) => {
     fetchRecipes: (query: any) => {
       dispatch(fetch(query))
       dispatch(fetch(query))
     },
     },
-    receiveRecipes: (recipes: Recipe[]) => {
+    receiveRecipes: (recipes: DBRecipe[]) => {
       dispatch(receive(recipes))
       dispatch(receive(recipes))
     },
     },
-    selectRecipe: (recipe: Recipe) => {
+    selectRecipe: (recipe: DBRecipe) => {
       dispatch(select(recipe))
       dispatch(select(recipe))
     }
     }
   }
   }

+ 2 - 3
recipes/src/containers/Recipes/View/index.tsx

@@ -1,7 +1,6 @@
 import React, { useState, useEffect } from 'react';
 import React, { useState, useEffect } from 'react';
 import { getRecipeById } from './../services';
 import { getRecipeById } from './../services';
 import { RouteComponentProps } from 'react-router';
 import { RouteComponentProps } from 'react-router';
-import {dissoc} from 'ramda';
 
 
 import RecipeCard from 'components/RecipeCard';
 import RecipeCard from 'components/RecipeCard';
 import Recipe, { _recipe } from 'types/recipes';
 import Recipe, { _recipe } from 'types/recipes';
@@ -20,8 +19,8 @@ class ViewRecipe extends React.Component<ViewRecipeProps, {recipe: Recipe}> {
 
 
   componentDidMount() {
   componentDidMount() {
     getRecipeById(this.props.match.params.id).then(
     getRecipeById(this.props.match.params.id).then(
-      recipe => this.setState({ recipe: dissoc('_id', recipe) })
-    );
+      recipe => this.setState({ recipe })
+    )
   }
   }
 
 
   render() {
   render() {

+ 11 - 4
recipes/src/containers/Recipes/services.ts

@@ -1,17 +1,17 @@
 import axios, { AxiosPromise } from 'axios';
 import axios, { AxiosPromise } from 'axios';
-import Recipe from 'types/recipes';
+import Recipe, { DBRecipe } from 'types/recipes';
 
 
 //@ts-ignore
 //@ts-ignore
 const API: string = process.env.REACT_APP_API_RECIPES;
 const API: string = process.env.REACT_APP_API_RECIPES;
 
 
-export const getRecipes = (query: any): Promise<Recipe[]> => 
+export const getRecipes = (query: any): Promise<DBRecipe[]> => 
   axios.get(`${API}/all`)
   axios.get(`${API}/all`)
   .then(response => response.data);
   .then(response => response.data);
 
 
 export const saveRecipe = (recipe: Recipe): Promise<any> => 
 export const saveRecipe = (recipe: Recipe): Promise<any> => 
   axios.post(`${API}`, recipe)
   axios.post(`${API}`, recipe)
 
 
-export const getRecipeById = (id: string): Promise<Recipe> =>
+export const getRecipeById = (id: string): Promise<DBRecipe> =>
   axios.get(`${API}/id/${id}`)
   axios.get(`${API}/id/${id}`)
   .then(response => response.data)
   .then(response => response.data)
 
 
@@ -21,9 +21,16 @@ export const scrapeRecipe = (url: string): Promise<Recipe> =>
     { url }
     { url }
   ).then(response => response.data);
   ).then(response => response.data);
 
 
+export const updateRecipe = (recipe: DBRecipe): Promise<any> => 
+    axios.put(
+      `${API}/edit/${recipe._id}`,
+      recipe
+    ).then(response => response);
+
 export default {
 export default {
   getRecipes,
   getRecipes,
   getRecipeById,
   getRecipeById,
   scrapeRecipe,
   scrapeRecipe,
-  saveRecipe
+  saveRecipe,
+  updateRecipe
 }
 }

+ 4 - 1
recipes/src/types/recipes.ts

@@ -107,7 +107,6 @@ export interface Suggestion {
 }
 }
 
 
 export default interface Recipe {
 export default interface Recipe {
-  _id?: string,
   author: Author,
   author: Author,
   details: Details,
   details: Details,
   ingredients: SubRecipe[],
   ingredients: SubRecipe[],
@@ -116,3 +115,7 @@ export default interface Recipe {
   summary: string,
   summary: string,
   tags: string[],
   tags: string[],
 }
 }
+
+export interface DBRecipe extends Recipe {
+  _id: string
+}