瀏覽代碼

Improve routing. Add Input component with styles

Tatiana Inama 7 年之前
父節點
當前提交
666f28a3da

+ 2 - 0
package.json

@@ -13,10 +13,12 @@
     "@material/react-card": "^0.11.0",
     "@material/react-drawer": "^0.11.0",
     "@material/react-layout-grid": "^0.11.0",
+    "@material/textfield": "^2.0.0",
     "@types/classnames": "^2.2.7",
     "@types/dotenv": "^6.1.0",
     "@types/material-components-web": "^0.43.1",
     "@types/node": "^11.13.2",
+    "@types/react": "^16.8.15",
     "@types/react-redux": "^7.0.6",
     "@types/redux-thunk": "^2.1.0",
     "@types/sqlite3": "^3.1.3",

+ 1 - 0
recipes/package.json

@@ -8,6 +8,7 @@
     "@material/react-drawer": "^0.11.0",
     "@material/react-layout-grid": "^0.11.0",
     "@material/react-list": "^0.11.0",
+    "@material/react-text-field": "^0.11.0",
     "@types/jest": "^24.0.11",
     "@types/node": "^11.13.0",
     "@types/react": "^16.8.12",

+ 1 - 0
recipes/public/index.html

@@ -25,6 +25,7 @@
     <title>Recipes</title>
     <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500">
     <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lekton">
+    <link rel="stylesheet" href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css">
   </head>
   <body>
     <noscript>You need to enable JavaScript to run this app.</noscript>

+ 30 - 0
recipes/src/components/Input/index.tsx

@@ -0,0 +1,30 @@
+import React from 'react';
+import TextField, { HelperText, Input as Field } from '@material/react-text-field';
+
+import '@material/react-text-field/dist/text-field.css';
+import './styles.scss';
+
+type InputProps = {
+	label: string,
+	helperText?: string,
+	value: string|number,
+	onChange: (e: any) => void,
+	textarea?: boolean,
+};
+
+const Input = (props: InputProps) => (
+	<TextField
+		label={props.label}
+		helperText={<HelperText>{props.helperText || ''}</HelperText>}
+		style={{ width: '100%' }}
+		textarea={props.textarea}
+	>
+		<Field
+			value={props.value}
+			//@ts-ignore
+			onChange={props.onChange}
+		/>
+	</TextField>
+);
+
+export default Input;

+ 0 - 0
recipes/src/components/Input/styles.scss


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

@@ -8,7 +8,7 @@ type NavbarProps = {
     label: string,
     onClick: () => void,
   }[],
-  children?: ReactElement,
+  children?: ReactElement|never[],
 }
 export default function Navbar(props: NavbarProps){
   return (

+ 134 - 7
recipes/src/containers/Recipes/Create.tsx

@@ -1,11 +1,138 @@
 import React from 'react';
+import  Navbar from 'components/Navbar';
+import { Grid, Row, Cell } from '@material/react-layout-grid';
+
+import Input from 'components/Input';
+import './styles.scss';
+
+import sample_img from "../../sample.png";
+import { ISubRecipe } from 'src/types/recipes';
+import { string } from 'prop-types';
+
+type CreateRecipeProps = {
+};
+
+type CreateRecipeState = {
+  form: {
+    name: string,
+    summary: string,
+    preparationTime: string,
+    cookingTime: string,
+    servings: number,
+  }
 
-const Create = (props: any) => {
-  return (
-    <div>
-      <h2>Create Recipe</h2>
-    </div>
-  )
 };
 
-export default Create;
+// author?: {
+//   name: string,
+// },
+// details?: {
+//   preparationTime: string,
+//   cookingTime: string,
+//   servings: number
+// },
+// ingredients?: ISubRecipe[],
+// instructions?: string[],
+// tags?: string[],
+
+type FormKeys = keyof CreateRecipeState['form'];
+
+class CreateRecipe extends React.Component<CreateRecipeProps, CreateRecipeState> {
+  constructor(props: any) {
+    super(props);
+    this.state = {
+      form: {
+        name: '',
+        summary: '',
+        preparationTime: '',
+        cookingTime: '',
+        servings: 0,
+      }
+    }
+  }
+
+  updateField(key: FormKeys) {
+    return (e: any) => {
+      this.setState({
+        form: {
+          [key]: e.currentTarget.value
+        }
+      } as Pick<CreateRecipeState, keyof CreateRecipeState>)
+    }
+  }
+
+  componentDidUpdate() {
+
+  }
+
+  render() {
+    return (
+      <div>
+        <Navbar
+          title="Create a recipe"
+        />
+        
+        <div className="cbk-create-recipe">
+          <Grid>
+            <Row>
+              <Cell columns={2}>
+                <img src={sample_img} style={{ width: '100%' }}/>
+              </Cell>
+              <Cell columns={10}>
+                <Input 
+                  label='name'
+                  helperText='Recipe name'
+                  value={this.state.form.name}
+                  onChange={this.updateField('name')}
+                />
+
+                <Input
+                  label='summary'
+                  helperText='Recipe description'
+                  value={this.state.form.summary}
+                  onChange={this.updateField('summary')}
+                  textarea
+                />
+              </Cell>
+            </Row>
+
+            <h5>Recipe Information</h5>
+            <Row>
+              <Cell columns={3}>
+                <Input
+                  label='Preparation time'
+                  value={this.state.form.preparationTime}
+                  onChange={this.updateField('preparationTime')}
+                />
+              </Cell>
+              <Cell columns={3}>
+                <Input
+                  label='Preparation time'
+                  value={this.state.form.cookingTime}
+                  onChange={this.updateField('cookingTime')}
+                />
+              </Cell>
+              <Cell columns={3}>
+                <Input
+                  label='Preparation time'
+                  value={this.state.form.servings}
+                  onChange={this.updateField('servings')}
+                />
+              </Cell>
+              <Cell columns={3}>
+                <Input
+                  label='Tags'
+                  value={this.state.form.preparationTime}
+                  onChange={this.updateField('preparationTime')}
+                />
+              </Cell>
+            </Row>
+          </Grid>
+        </div>
+
+      </div>
+    )
+  }
+}
+
+export default CreateRecipe;

+ 4 - 1
recipes/src/containers/Recipes/List.tsx

@@ -6,6 +6,7 @@ import {
 } from "containers/Recipes/actions";
 import { connect } from "react-redux";
 import { Grid, Row, Cell } from "@material/react-layout-grid";
+import { Button } from "@material/react-button";
 import Card from 'components/Card';
 import RecipeCard from 'components/RecipeCard';
 import IRecipe from 'types/recipes';
@@ -65,7 +66,9 @@ class RecipeList extends Component<RecipeListProps> {
         <Navbar
           title="Recipes"
         >
-          <Link to='/recipes/create'>Create Recipe</Link>
+          <Button unelevated>
+            <Link to='/recipes/create'>Create Recipe</Link>
+          </Button>
         </Navbar>
 
         <Grid>

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

@@ -39,6 +39,7 @@ function shouldFetch(recipes: IRecipe[]) {
 
 export function fetchIfNeeded(query: any) {
   return (dispatch: any, getState: any) => {
+    console.log("fetch");
     if(shouldFetch(getState())) {
       return dispatch(fetchRecipes(query))
     } else {

+ 1 - 2
recipes/src/containers/Recipes/index.tsx

@@ -1,11 +1,10 @@
-import React, { Component } from "react";
+import React from "react";
 
 import { Route, RouteComponentProps } from 'react-router-dom';
 import RecipeList from './List';
 import Create from './Create';
 
 const RecipesContainer = (props: RouteComponentProps) => {
-  console.log('props', props);
   return (
     <div>
       <Route

+ 1 - 1
recipes/src/containers/Recipes/services.ts

@@ -5,7 +5,7 @@ import IRecipe from 'types/recipes';
 const API: string = process.env.REACT_APP_API_RECIPES;
 
 export const getRecipes = (query: any): Promise<IRecipe[]> => 
-  axios.get(`${API}/all`)
+  axios.get(`${API}all`)
   .then(response => response.data);
 
 export default {

+ 11 - 0
recipes/src/containers/Recipes/styles.scss

@@ -0,0 +1,11 @@
+@import 'styles/_variables.scss';
+
+.cbk-create-recipe {
+    margin: $spacing-large;
+    padding: $spacing-small;
+    background-color: white;
+
+    .mdc-text-field {
+        width: 100%;
+    }
+}

二進制
recipes/src/sample.png


+ 1 - 0
recipes/src/styles/app.scss

@@ -64,6 +64,7 @@ code {
   width: 100%;
   .mdc-layout-grid {
     display: flex;
+    flex-direction: column;
     width: 100%;
     
     .mdc-layout-grid__inner {