瀏覽代碼

Basic Recipe Card interface.

Tati 7 年之前
父節點
當前提交
73dcea47aa

+ 1 - 0
recipes/package.json

@@ -14,6 +14,7 @@
     "@types/storybook__addon-links": "^3.3.4",
     "@types/storybook__react": "^4.0.1",
     "axios": "^0.18.0",
+    "moment": "^2.24.0",
     "node-sass": "^4.11.0",
     "react": "^16.8.4",
     "react-dom": "^16.8.4",

+ 1 - 1
recipes/src/components/Card/index.tsx

@@ -34,7 +34,7 @@ function CBKCard(props: CBKCardProps){
           <h6 className='cbk-card__main__title'>{props.title}</h6>
           {
             summary ? 
-              <div className='cbk-card__main__summary'>{summary}</div> :
+              <p className='cbk-card__main__summary'>{summary}</p> :
               null
           }
         </div>

+ 4 - 2
recipes/src/components/Card/styles.scss

@@ -1,10 +1,8 @@
 @import 'styles/_variables.scss';
 
 .cbk-card {
-  //flex-direction: row;
   border-radius: 0px;
   border: 0px;
-  margin: 8px 0;
   .mdc-card__media {
     width: 168px;
   }
@@ -30,4 +28,8 @@
       -webkit-box-orient: vertical;
     }
   }
+}
+
+.cbk-card:not(:last-child) {
+  margin-bottom: 16px;
 }

+ 60 - 36
recipes/src/components/RecipeCard/index.tsx

@@ -1,45 +1,69 @@
 import React, { Component } from 'react';
+import IRecipe from '../../types/recipes';
+import Card, {
+  CardActions,
+  CardActionButtons,
+  CardPrimaryContent,
+  CardMedia,
+} from "@material/react-card";
+import Icon from 'components/Icon';
+import moment from 'moment';
 
-import './styles.scss';
-
-type Ingredient = {
-  name: string,
-  ingredients: {
-    name: string,
-    quantity: number,
-    unit: string,
-    _original: string,
-  }[],
-}
+import sample_img from "components/Card/sample.png";
+import { ReactComponent as Preparation } from 'svgs/preparation.svg';
+import { ReactComponent as Cooking } from 'svgs/cooking.svg';
+import { ReactComponent as Servings } from 'svgs/servings.svg';
 
-export type Recipe = {
-  _id: string,
-  name: string,
-  author: {
-    name: string,
-  },
-  details: {
-    preparationTime: string,
-    cookingTime: string,
-    servings: number,
-  },
-  ingredients: Ingredient[],
-  instructions: string[],
-  summary: string,
-  tags: string[],
-}
+import './styles.scss';
 
 type RecipeCardProps = {
-  recipe: Recipe,
-  actions?: boolean,
+  recipe: IRecipe,
 }
 
-export class RecipeCard extends Component<RecipeCardProps, {}> {
-  render() {
-    return (
-      <h2>recipeCard</h2>
-    );
-  }
+function CBKRecipeCard(props: RecipeCardProps) {
+  const { recipe } = props;
+  const prepTime = moment.duration(recipe.details.preparationTime).humanize();
+  const cookTime = moment.duration(recipe.details.cookingTime).humanize();
+  const servings = recipe.details.servings;
+
+  return (
+    <Card outlined className='cbk-recipe-card'>
+      <div className='cbk-recipe-card__primary'>
+        <CardMedia square imageUrl={sample_img} className='cbk-recipe-card__primary__image'/>
+        <div className='cbk-recipe-card__primary__title'>
+          <h6>{recipe.name}</h6>
+          <p>{recipe.summary}</p>
+          <ul>
+            <li>
+              <Icon width={32} height={32}><Preparation/></Icon>
+              <label>{prepTime}</label>
+            </li>
+            <li>
+              <Icon width={32} height={32}><Cooking/></Icon>
+              <label>{cookTime}</label>
+            </li>
+            <li>
+              <Icon width={32} height={32}><Servings/></Icon>
+              <label>{servings}</label>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div className='cbk-recipe-card__content'>
+        <div className='cbk-recipe-card__content__ingredients'>
+        </div>
+        <div className='cbk-recipe-card__content__instructions'>
+          <ol>
+            {
+              recipe.instructions.map((instruction, i) => (
+                <li key={i}>{instruction}</li>
+              ))
+            }            
+          </ol>
+        </div>
+      </div>
+    </Card>
+  )
 }
 
-export default RecipeCard;
+export default CBKRecipeCard;

+ 65 - 5
recipes/src/components/RecipeCard/styles.scss

@@ -1,7 +1,67 @@
-@import './../../styles/index.scss';
+@import 'styles/_variables.scss';
 
-.RecipeCard {
-  background-color: white;
-  height: 144px;
-  padding: $spacing-small;
+.cbk-recipe-card {
+  border: 0px;
+  padding: $spacing-large;
+  
+  &__primary {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+
+    &__image.mdc-card__media {
+      flex-grow: 1;
+      flex-basis: 33%;
+      border-top-left-radius: 0px;
+      border-top-right-radius: 0px;
+    }
+  
+    &__title {
+      flex-grow: 2;
+      padding-left: $spacing-regular;
+      padding-top: $spacing-regular;
+      padding-bottom: $spacing-regular;
+
+      h6 {
+        margin: 0;
+        font-size: $font-size-xx-large;
+      }
+
+      h6:after {
+        content: "";
+        display: block;
+        margin: 0 auto;
+        width: 50px;
+        /* height: 50%; */
+        margin-top: -20px;
+        border-bottom: 16px solid;
+        border-bottom-color: $grey-300;
+        margin-left: -4px;
+      }
+
+      p {
+        color: $grey-500;
+        letter-spacing: 1px;
+        text-align: justify;
+      }
+
+      ul {
+        display: flex;
+        flex-direction: row;
+        
+        li {
+          display: flex;
+          flex-direction: row;
+          align-items: center;
+          padding-right: $spacing-small;
+          color: $grey-500;
+          .cbk-icon {
+            svg > g path {
+              fill: $grey-500;
+            }
+          }
+        }
+      }
+    }
+  }
 }

+ 10 - 13
recipes/src/containers/recipes.tsx

@@ -7,6 +7,7 @@ import {
 import { connect } from "react-redux";
 import { Grid, Row, Cell } from "@material/react-layout-grid";
 import Card from 'components/Card';
+import RecipeCard from 'components/RecipeCard';
 import IRecipe from 'types/recipes';
 
 type RecipesContainerProps = {
@@ -60,25 +61,21 @@ class Recipes extends Component<RecipesContainerProps> {
             {
               data.map((recipe: any, i: number) => {
                 return (
-                  <Row key={i}>
-                    <Cell columns={10}>
-                      <Card
-                        title={recipe.name}
-                        onClick={this.handleRecipeSelection(recipe)}
-                        summary={recipe.summary}
-                        actions={actions}
-                      />
-                    </Cell>
-                  </Row>
+                  <Card
+                    title={recipe.name}
+                    onClick={this.handleRecipeSelection(recipe)}
+                    summary={recipe.summary}
+                    actions={actions}
+                  />
                 )
               })
             }
           </Cell>
           <Cell columns={6}>
             { selectedRecipe !== undefined && 
-              <section>
-                <h3>{selectedRecipe.name}</h3>
-              </section>
+              <RecipeCard 
+                recipe={selectedRecipe}
+              />
             }
           </Cell>
         </Row>