Jelajahi Sumber

Add super basic card with selection option for recipes

Tati 7 tahun lalu
induk
melakukan
e34b3ef900

+ 5 - 2
recipes/src/components/Card/index.tsx

@@ -14,18 +14,21 @@ import './styles.scss';
 import { ReactNodeArray } from 'react';
 import { ReactNodeArray } from 'react';
 import sample_img from "./sample.png";
 import sample_img from "./sample.png";
 
 
-const not_found = "https://www.archgard.com/assets/upload_fallbacks/image_not_found-54bf2d65c203b1e48fea1951497d4f689907afe3037d02a02dcde5775746765c.png";
+type fc = (recipe: any) => undefined;
+
 type CBKCardProps = {
 type CBKCardProps = {
   children?: ReactNodeArray,
   children?: ReactNodeArray,
   title: string,
   title: string,
   img?: string,
   img?: string,
+  recipe?: any,
+  onClick: fc,
 }
 }
   
   
 function _Card(props: CBKCardProps){
 function _Card(props: CBKCardProps){
   return(
   return(
     <Card outlined className='cbk-card'>
     <Card outlined className='cbk-card'>
       <CardMedia imageUrl={props.img || sample_img}></CardMedia>
       <CardMedia imageUrl={props.img || sample_img}></CardMedia>
-      <CardPrimaryContent>
+      <CardPrimaryContent onClick={props.onClick}>
         <h6>{props.title}</h6>
         <h6>{props.title}</h6>
       </CardPrimaryContent>
       </CardPrimaryContent>
       <CardActions>
       <CardActions>

+ 43 - 18
recipes/src/containers/recipes.tsx

@@ -1,43 +1,52 @@
 import React, { Component } from "react";
 import React, { Component } from "react";
 import {
 import {
-  fetchRecipes,
-  receiveRecipes,
+  fetchIfNeeded as fetch,
+  receiveRecipes as receive,
+  selectRecipe as select,
 } from "store/recipes/actions";
 } from "store/recipes/actions";
 import { connect } from "react-redux";
 import { connect } from "react-redux";
 import { Grid, Row, Cell } from "@material/react-layout-grid";
 import { Grid, Row, Cell } from "@material/react-layout-grid";
 import Card from 'components/Card';
 import Card from 'components/Card';
 
 
-class Recipes extends Component<any, any> {
+type RecipesContainerProps = {
+  data: [],
+  isFetching: boolean,
+  selectedRecipe: {} | undefined,
+  fetchRecipes: (query: any) => undefined,
+  receiveRecipes: (recipes: []) => undefined,
+  selectRecipe: (recipe: any) => undefined,
+};
+
+class Recipes extends Component<RecipesContainerProps> {
   constructor(props: any) {
   constructor(props: any) {
     super(props);
     super(props);
-    console.log('props', props);
   }
   }
 
 
   componentDidMount() {
   componentDidMount() {
-    console.log('props', this.props)
-    const { dispatch } = this.props;
-    dispatch(fetchRecipes({}));
+    const { fetchRecipes } = this.props;
+    fetchRecipes({});
   }
   }
 
 
   componentDidUpdate(prevProps: any) {
   componentDidUpdate(prevProps: any) {
-    const { dispatch, recipes } = this.props;
-    dispatch(receiveRecipes(recipes));
+    const { data, receiveRecipes, isFetching } = this.props;
+
+    if (isFetching === false && data.length !== prevProps.data.length) {
+      receiveRecipes(data);
+    }
   }
   }
 
 
   render() {
   render() {
-    console.log(this.props.data);
-
     return(
     return(
       <Cell columns={6}>
       <Cell columns={6}>
         {
         {
           this.props.data.map((recipe: any, i: number) => {
           this.props.data.map((recipe: any, i: number) => {
-            console.log("card");
             return (
             return (
-              <Row>
+              <Row key={i}>
                 <Cell columns={10}>
                 <Cell columns={10}>
                   <Card
                   <Card
-                    key="i"
                     title={recipe.name}
                     title={recipe.name}
+                    recipe={recipe}
+                    onClick={() => this.props.selectRecipe(recipe)}
                   />
                   />
                 </Cell>
                 </Cell>
               </Row>
               </Row>
@@ -49,9 +58,25 @@ class Recipes extends Component<any, any> {
   }
   }
 }
 }
 
 
-function mapStateToProps(state: any) {
-  const { recipes } = state;
-  return state.recipes;
+const mapStateToProps = ({ recipes }: any, ownProps: any) => {
+  return recipes;
+}
+
+const mapDispatchToProps = (dispatch: any) => {
+  return {
+    fetchRecipes: (query: any) => {
+      dispatch(fetch(query))
+    },
+    receiveRecipes: (recipes: []) => {
+      dispatch(receive(recipes))
+    },
+    selectRecipe: (recipe: any) => {
+      dispatch(select(recipe))
+    }
+  }
 }
 }
 
 
-export default  connect(mapStateToProps)(Recipes);
+export default connect(
+  mapStateToProps,
+  mapDispatchToProps
+)(Recipes);

+ 0 - 51
recipes/src/routes/Recipes.tsx

@@ -1,51 +0,0 @@
-import React, { Component } from 'react';
-import { RecipeCard, Recipe } from '../components/RecipeCard';
-import Card from '../components/Card';
-import axios from 'axios';
-
-type RecipeState = {
-  error: null | Error,
-  isLoaded: boolean,
-  recipes: Recipe[],
-}
-
-class Recipes extends Component<{}, RecipeState> {
-  constructor(props: any) {
-    super(props);
-    this.state = {
-      error: null,
-      isLoaded: false,
-      recipes: [],
-    }
-  }
-
-  componentDidMount(){
-    axios.get('https://recipes.davidventura.com.ar/recipes/ingredients/?ingredients=beef,bacon').then(response => {
-      console.log('response', response.data);
-      this.setState({
-        isLoaded: true,
-        recipes: response.data,
-      })
-    }).catch(error => {
-      this.setState({
-        isLoaded: true,
-        error: error,
-        recipes: [],
-      })
-    })
-  }
-
-  render() {
-    return (
-      <div>
-        {/* {
-          this.state.recipes.map((_recipe) => (
-            <RecipeCard recipe={_recipe} key={_recipe._id}/>
-          ))
-        } */}
-      </div>
-    )
-  }
-}
-
-export default Recipes;

+ 22 - 1
recipes/src/store/recipes/actions.ts

@@ -3,6 +3,7 @@ import axios from 'axios';
 
 
 export const RECEIVE_RECIPES = 'RECEIVE_RECIPES';
 export const RECEIVE_RECIPES = 'RECEIVE_RECIPES';
 export const REQUEST_RECIPES = 'REQUEST_RECIPES';
 export const REQUEST_RECIPES = 'REQUEST_RECIPES';
+export const SELECT_RECIPE = 'SELECT_RECIPE';
 
 
 export const requestRecipes = (query: {}) => ({
 export const requestRecipes = (query: {}) => ({
   type: REQUEST_RECIPES,
   type: REQUEST_RECIPES,
@@ -15,10 +16,15 @@ export const receiveRecipes = (json: []) => ({
   payload: json,
   payload: json,
 });
 });
 
 
+export const selectRecipe = (recipe: any) => ({
+  type: SELECT_RECIPE,
+  payload: recipe,
+});
+
 export function fetchRecipes(query: any) {
 export function fetchRecipes(query: any) {
   return (dispatch: any) => {
   return (dispatch: any) => {
     dispatch(requestRecipes(query))
     dispatch(requestRecipes(query))
-    return axios.get('https://recipes.davidventura.com.ar/recipes/all')
+    return axios.get('http://localhost:3000/recipes/all')
     .then(response => {
     .then(response => {
       console.log('response', response.data);
       console.log('response', response.data);
       return response.data
       return response.data
@@ -29,3 +35,18 @@ export function fetchRecipes(query: any) {
     })
     })
   }
   }
 }
 }
+
+function shouldFetch(recipes: []) {
+  return recipes.length ? false : true;
+}
+
+export function fetchIfNeeded(query: any) {
+  return (dispatch: any, getState: any) => {
+    if(shouldFetch(getState())) {
+      return dispatch(fetchRecipes(query))
+    } else {
+      return Promise.resolve();
+    }
+
+  }
+}

+ 9 - 1
recipes/src/store/recipes/reducers.ts

@@ -2,6 +2,7 @@ const initialState = {
   recipes: {
   recipes: {
     isFetching: false,
     isFetching: false,
     data: [],
     data: [],
+    selectedRecipe: undefined,
   }
   }
 };
 };
 
 
@@ -9,7 +10,6 @@ export const recipesReducer = (
   state = initialState,
   state = initialState,
   action: any
   action: any
 ) => {
 ) => {
-  console.log("action", action)
   switch (action.type) {
   switch (action.type) {
     case 'REQUEST_RECIPES': 
     case 'REQUEST_RECIPES': 
       return {
       return {
@@ -28,6 +28,14 @@ export const recipesReducer = (
           data: action.payload || state.recipes.data,
           data: action.payload || state.recipes.data,
         }
         }
       }
       }
+    case 'SELECT_RECIPE':
+      return {
+        ...state,
+        recipes: {
+          ...state.recipes,
+          selectedRecipe: action.payload
+        }
+      }
     default:
     default:
       return state;
       return state;
   }
   }