├── .browserslistrc ├── .gitignore ├── .ruby-version ├── Gemfile ├── Gemfile.lock ├── README.md ├── Rakefile ├── app ├── assets │ ├── config │ │ └── manifest.js │ ├── images │ │ ├── .keep │ │ └── Sammy_Meal.jpg │ ├── javascripts │ │ ├── application.js │ │ ├── cable.js │ │ ├── channels │ │ │ └── .keep │ │ └── homepage.js │ └── stylesheets │ │ ├── application.css │ │ └── homepage.scss ├── channels │ └── application_cable │ │ ├── channel.rb │ │ └── connection.rb ├── controllers │ ├── api │ │ └── v1 │ │ │ └── recipes_controller.rb │ ├── application_controller.rb │ ├── concerns │ │ └── .keep │ └── homepage_controller.rb ├── helpers │ ├── application_helper.rb │ └── homepage_helper.rb ├── javascript │ ├── components │ │ ├── App.jsx │ │ ├── Home.jsx │ │ ├── NewRecipe.jsx │ │ ├── Recipe.jsx │ │ └── Recipes.jsx │ ├── packs │ │ ├── Index.jsx │ │ └── application.js │ └── routes │ │ └── Index.jsx ├── jobs │ └── application_job.rb ├── mailers │ └── application_mailer.rb ├── models │ ├── application_record.rb │ ├── concerns │ │ └── .keep │ └── recipe.rb └── views │ ├── homepage │ └── index.html.erb │ └── layouts │ ├── application.html.erb │ ├── mailer.html.erb │ └── mailer.text.erb ├── babel.config.js ├── bin ├── bundle ├── rails ├── rake ├── setup ├── spring ├── update ├── webpack ├── webpack-dev-server └── yarn ├── config.ru ├── config ├── application.rb ├── boot.rb ├── cable.yml ├── credentials.yml.enc ├── database.yml ├── environment.rb ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── initializers │ ├── application_controller_renderer.rb │ ├── assets.rb │ ├── backtrace_silencers.rb │ ├── content_security_policy.rb │ ├── cookies_serializer.rb │ ├── filter_parameter_logging.rb │ ├── inflections.rb │ ├── mime_types.rb │ └── wrap_parameters.rb ├── locales │ └── en.yml ├── puma.rb ├── routes.rb ├── spring.rb ├── storage.yml ├── webpack │ ├── development.js │ ├── environment.js │ ├── production.js │ └── test.js └── webpacker.yml ├── db ├── migrate │ └── 20190407161357_create_recipes.rb ├── schema.rb └── seeds.rb ├── lib ├── assets │ └── .keep └── tasks │ └── .keep ├── log └── .keep ├── package.json ├── postcss.config.js ├── public ├── 404.html ├── 422.html ├── 500.html ├── apple-touch-icon-precomposed.png ├── apple-touch-icon.png ├── favicon.ico └── robots.txt ├── storage └── .keep ├── tmp └── .keep ├── vendor └── .keep └── yarn.lock /.browserslistrc: -------------------------------------------------------------------------------- 1 | defaults 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore all logfiles and tempfiles. 11 | /log/* 12 | /tmp/* 13 | !/log/.keep 14 | !/tmp/.keep 15 | 16 | # Ignore uploaded files in development 17 | /storage/* 18 | !/storage/.keep 19 | 20 | /node_modules 21 | /yarn-error.log 22 | 23 | /public/assets 24 | .byebug_history 25 | 26 | # Ignore master key for decrypting credentials and more. 27 | /config/master.key 28 | 29 | /public/packs 30 | /public/packs-test 31 | /node_modules 32 | /yarn-error.log 33 | yarn-debug.log* 34 | .yarn-integrity 35 | .DS_Store 36 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.6.1 -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | git_source(:github) { |repo| "https://github.com/#{repo}.git" } 3 | 4 | ruby '2.6.1' 5 | 6 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 7 | gem 'rails', '~> 5.2.3' 8 | # Use postgresql as the database for Active Record 9 | gem 'pg', '>= 0.18', '< 2.0' 10 | # Use Puma as the app server 11 | gem 'puma', '~> 3.11' 12 | # Use SCSS for stylesheets 13 | gem 'sass-rails', '~> 5.0' 14 | # Use Uglifier as compressor for JavaScript assets 15 | gem 'uglifier', '>= 1.3.0' 16 | # Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker 17 | gem 'webpacker' 18 | # See https://github.com/rails/execjs#readme for more supported runtimes 19 | # gem 'mini_racer', platforms: :ruby 20 | 21 | # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks 22 | gem 'turbolinks', '~> 5' 23 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 24 | gem 'jbuilder', '~> 2.5' 25 | # Use Redis adapter to run Action Cable in production 26 | # gem 'redis', '~> 4.0' 27 | # Use ActiveModel has_secure_password 28 | # gem 'bcrypt', '~> 3.1.7' 29 | 30 | # Use ActiveStorage variant 31 | # gem 'mini_magick', '~> 4.8' 32 | 33 | # Use Capistrano for deployment 34 | # gem 'capistrano-rails', group: :development 35 | 36 | # Reduces boot times through caching; required in config/boot.rb 37 | gem 'bootsnap', '>= 1.1.0', require: false 38 | 39 | group :development, :test do 40 | # Call 'byebug' anywhere in the code to stop execution and get a debugger console 41 | gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] 42 | end 43 | 44 | group :development do 45 | # Access an interactive console on exception pages or by calling 'console' anywhere in the code. 46 | gem 'web-console', '>= 3.3.0' 47 | gem 'listen', '>= 3.0.5', '< 3.2' 48 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring 49 | gem 'spring' 50 | gem 'spring-watcher-listen', '~> 2.0.0' 51 | end 52 | 53 | 54 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 55 | gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] 56 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actioncable (5.2.3) 5 | actionpack (= 5.2.3) 6 | nio4r (~> 2.0) 7 | websocket-driver (>= 0.6.1) 8 | actionmailer (5.2.3) 9 | actionpack (= 5.2.3) 10 | actionview (= 5.2.3) 11 | activejob (= 5.2.3) 12 | mail (~> 2.5, >= 2.5.4) 13 | rails-dom-testing (~> 2.0) 14 | actionpack (5.2.3) 15 | actionview (= 5.2.3) 16 | activesupport (= 5.2.3) 17 | rack (~> 2.0) 18 | rack-test (>= 0.6.3) 19 | rails-dom-testing (~> 2.0) 20 | rails-html-sanitizer (~> 1.0, >= 1.0.2) 21 | actionview (5.2.3) 22 | activesupport (= 5.2.3) 23 | builder (~> 3.1) 24 | erubi (~> 1.4) 25 | rails-dom-testing (~> 2.0) 26 | rails-html-sanitizer (~> 1.0, >= 1.0.3) 27 | activejob (5.2.3) 28 | activesupport (= 5.2.3) 29 | globalid (>= 0.3.6) 30 | activemodel (5.2.3) 31 | activesupport (= 5.2.3) 32 | activerecord (5.2.3) 33 | activemodel (= 5.2.3) 34 | activesupport (= 5.2.3) 35 | arel (>= 9.0) 36 | activestorage (5.2.3) 37 | actionpack (= 5.2.3) 38 | activerecord (= 5.2.3) 39 | marcel (~> 0.3.1) 40 | activesupport (5.2.3) 41 | concurrent-ruby (~> 1.0, >= 1.0.2) 42 | i18n (>= 0.7, < 2) 43 | minitest (~> 5.1) 44 | tzinfo (~> 1.1) 45 | arel (9.0.0) 46 | bindex (0.6.0) 47 | bootsnap (1.4.2) 48 | msgpack (~> 1.0) 49 | builder (3.2.3) 50 | byebug (11.0.1) 51 | concurrent-ruby (1.1.5) 52 | crass (1.0.4) 53 | erubi (1.8.0) 54 | execjs (2.7.0) 55 | ffi (1.10.0) 56 | globalid (0.4.2) 57 | activesupport (>= 4.2.0) 58 | i18n (1.6.0) 59 | concurrent-ruby (~> 1.0) 60 | jbuilder (2.8.0) 61 | activesupport (>= 4.2.0) 62 | multi_json (>= 1.2) 63 | listen (3.1.5) 64 | rb-fsevent (~> 0.9, >= 0.9.4) 65 | rb-inotify (~> 0.9, >= 0.9.7) 66 | ruby_dep (~> 1.2) 67 | loofah (2.2.3) 68 | crass (~> 1.0.2) 69 | nokogiri (>= 1.5.9) 70 | mail (2.7.1) 71 | mini_mime (>= 0.1.1) 72 | marcel (0.3.3) 73 | mimemagic (~> 0.3.2) 74 | method_source (0.9.2) 75 | mimemagic (0.3.3) 76 | mini_mime (1.0.1) 77 | mini_portile2 (2.4.0) 78 | minitest (5.11.3) 79 | msgpack (1.2.9) 80 | multi_json (1.13.1) 81 | nio4r (2.3.1) 82 | nokogiri (1.10.2) 83 | mini_portile2 (~> 2.4.0) 84 | pg (1.1.4) 85 | puma (3.12.1) 86 | rack (2.0.7) 87 | rack-proxy (0.6.5) 88 | rack 89 | rack-test (1.1.0) 90 | rack (>= 1.0, < 3) 91 | rails (5.2.3) 92 | actioncable (= 5.2.3) 93 | actionmailer (= 5.2.3) 94 | actionpack (= 5.2.3) 95 | actionview (= 5.2.3) 96 | activejob (= 5.2.3) 97 | activemodel (= 5.2.3) 98 | activerecord (= 5.2.3) 99 | activestorage (= 5.2.3) 100 | activesupport (= 5.2.3) 101 | bundler (>= 1.3.0) 102 | railties (= 5.2.3) 103 | sprockets-rails (>= 2.0.0) 104 | rails-dom-testing (2.0.3) 105 | activesupport (>= 4.2.0) 106 | nokogiri (>= 1.6) 107 | rails-html-sanitizer (1.0.4) 108 | loofah (~> 2.2, >= 2.2.2) 109 | railties (5.2.3) 110 | actionpack (= 5.2.3) 111 | activesupport (= 5.2.3) 112 | method_source 113 | rake (>= 0.8.7) 114 | thor (>= 0.19.0, < 2.0) 115 | rake (12.3.2) 116 | rb-fsevent (0.10.3) 117 | rb-inotify (0.10.0) 118 | ffi (~> 1.0) 119 | ruby_dep (1.5.0) 120 | sass (3.7.3) 121 | sass-listen (~> 4.0.0) 122 | sass-listen (4.0.0) 123 | rb-fsevent (~> 0.9, >= 0.9.4) 124 | rb-inotify (~> 0.9, >= 0.9.7) 125 | sass-rails (5.0.7) 126 | railties (>= 4.0.0, < 6) 127 | sass (~> 3.1) 128 | sprockets (>= 2.8, < 4.0) 129 | sprockets-rails (>= 2.0, < 4.0) 130 | tilt (>= 1.1, < 3) 131 | spring (2.0.2) 132 | activesupport (>= 4.2) 133 | spring-watcher-listen (2.0.1) 134 | listen (>= 2.7, < 4.0) 135 | spring (>= 1.2, < 3.0) 136 | sprockets (3.7.2) 137 | concurrent-ruby (~> 1.0) 138 | rack (> 1, < 3) 139 | sprockets-rails (3.2.1) 140 | actionpack (>= 4.0) 141 | activesupport (>= 4.0) 142 | sprockets (>= 3.0.0) 143 | thor (0.20.3) 144 | thread_safe (0.3.6) 145 | tilt (2.0.9) 146 | turbolinks (5.2.0) 147 | turbolinks-source (~> 5.2) 148 | turbolinks-source (5.2.0) 149 | tzinfo (1.2.5) 150 | thread_safe (~> 0.1) 151 | uglifier (4.1.20) 152 | execjs (>= 0.3.0, < 3) 153 | web-console (3.7.0) 154 | actionview (>= 5.0) 155 | activemodel (>= 5.0) 156 | bindex (>= 0.4.0) 157 | railties (>= 5.0) 158 | webpacker (4.0.2) 159 | activesupport (>= 4.2) 160 | rack-proxy (>= 0.6.1) 161 | railties (>= 4.2) 162 | websocket-driver (0.7.0) 163 | websocket-extensions (>= 0.1.0) 164 | websocket-extensions (0.1.3) 165 | 166 | PLATFORMS 167 | ruby 168 | 169 | DEPENDENCIES 170 | bootsnap (>= 1.1.0) 171 | byebug 172 | jbuilder (~> 2.5) 173 | listen (>= 3.0.5, < 3.2) 174 | pg (>= 0.18, < 2.0) 175 | puma (~> 3.11) 176 | rails (~> 5.2.3) 177 | sass-rails (~> 5.0) 178 | spring 179 | spring-watcher-listen (~> 2.0.0) 180 | turbolinks (~> 5) 181 | tzinfo-data 182 | uglifier (>= 1.3.0) 183 | web-console (>= 3.3.0) 184 | webpacker 185 | 186 | RUBY VERSION 187 | ruby 2.6.1p33 188 | 189 | BUNDLED WITH 190 | 1.17.2 191 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | This README would normally document whatever steps are necessary to get the 4 | application up and running. 5 | 6 | Things you may want to cover: 7 | 8 | * Ruby version 9 | 10 | * System dependencies 11 | 12 | * Configuration 13 | 14 | * Database creation 15 | 16 | * Database initialization 17 | 18 | * How to run the test suite 19 | 20 | * Services (job queues, cache servers, search engines, etc.) 21 | 22 | * Deployment instructions 23 | 24 | * ... 25 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative 'config/application' 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../javascripts .js 3 | //= link_directory ../stylesheets .css 4 | -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/do-community/react_rails_recipe/613ceb789e774f257a4e4440ea03de8ba851527d/app/assets/images/.keep -------------------------------------------------------------------------------- /app/assets/images/Sammy_Meal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/do-community/react_rails_recipe/613ceb789e774f257a4e4440ea03de8ba851527d/app/assets/images/Sammy_Meal.jpg -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's 5 | // vendor/assets/javascripts directory can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // compiled file. JavaScript code in this file should be added after the last require_* statement. 9 | // 10 | // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | //= require rails-ujs 14 | //= require activestorage 15 | //= require turbolinks 16 | //= require_tree . 17 | -------------------------------------------------------------------------------- /app/assets/javascripts/cable.js: -------------------------------------------------------------------------------- 1 | // Action Cable provides the framework to deal with WebSockets in Rails. 2 | // You can generate new channels where WebSocket features live using the `rails generate channel` command. 3 | // 4 | //= require action_cable 5 | //= require_self 6 | //= require_tree ./channels 7 | 8 | (function() { 9 | this.App || (this.App = {}); 10 | 11 | App.cable = ActionCable.createConsumer(); 12 | 13 | }).call(this); 14 | -------------------------------------------------------------------------------- /app/assets/javascripts/channels/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/do-community/react_rails_recipe/613ceb789e774f257a4e4440ea03de8ba851527d/app/assets/javascripts/channels/.keep -------------------------------------------------------------------------------- /app/assets/javascripts/homepage.js: -------------------------------------------------------------------------------- 1 | // Place all the behaviors and hooks related to the matching controller here. 2 | // All this logic will automatically be available in application.js. 3 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's 6 | * vendor/assets/stylesheets directory can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS 10 | * files in this directory. Styles in this file should be added after the last require_* statement. 11 | * It is generally better to create a new file per style scope. 12 | * 13 | *= require_tree . 14 | *= require_self 15 | */ 16 | .bg_primary-color { 17 | background-color: #FFFFFF; 18 | } 19 | 20 | .primary-color { 21 | background-color: #FFFFFF; 22 | } 23 | 24 | .bg_secondary-color { 25 | background-color: #293241; 26 | } 27 | 28 | .secondary-color { 29 | color: #293241; 30 | } 31 | 32 | .custom-button.btn { 33 | background-color: #293241; 34 | color: #FFF; 35 | border: none; 36 | } 37 | 38 | .custom-button.btn:hover { 39 | color: #FFF !important; 40 | border: none; 41 | } 42 | 43 | .hero { 44 | width: 100vw; 45 | height: 50vh; 46 | } 47 | 48 | .hero img { 49 | object-fit: cover; 50 | object-position: top; 51 | height: 100%; 52 | width: 100%; 53 | } 54 | 55 | .overlay { 56 | height: 100%; 57 | width: 100%; 58 | opacity: 0.4; 59 | } -------------------------------------------------------------------------------- /app/assets/stylesheets/homepage.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the Homepage controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/controllers/api/v1/recipes_controller.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Api::V1::RecipesController < ApplicationController 4 | def index 5 | recipe = Recipe.all.order(created_at: :desc) 6 | render json: recipe 7 | end 8 | 9 | def create 10 | recipe = Recipe.create!(recipe_params) 11 | if recipe 12 | render json: recipe 13 | else 14 | render json: recipe.errors 15 | end 16 | end 17 | 18 | def show 19 | if recipe 20 | render json: recipe 21 | else 22 | render json: recipe.errors 23 | end 24 | end 25 | 26 | def destroy 27 | recipe&.destroy 28 | render json: { message: 'Recipe deleted!' } 29 | end 30 | 31 | private 32 | 33 | def recipe_params 34 | params.permit(:name, :image, :ingredients, :instruction) 35 | end 36 | 37 | def recipe 38 | @recipe ||= Recipe.find(params[:id]) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | end 3 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/do-community/react_rails_recipe/613ceb789e774f257a4e4440ea03de8ba851527d/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /app/controllers/homepage_controller.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class HomepageController < ApplicationController 4 | def index; end 5 | end 6 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/homepage_helper.rb: -------------------------------------------------------------------------------- 1 | module HomepageHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/javascript/components/App.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Routes from "../routes/Index"; 3 | 4 | export default props => <>{Routes}; 5 | -------------------------------------------------------------------------------- /app/javascript/components/Home.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; 3 | 4 | export default () => ( 5 |
6 |
7 |
8 |

Food Recipes

9 |

10 | A curated list of recipes for the best homemade meal and delicacies. 11 |

12 |
13 | 18 | View Recipes 19 | 20 |
21 |
22 |
23 | ); 24 | -------------------------------------------------------------------------------- /app/javascript/components/NewRecipe.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; 3 | 4 | class NewRecipe extends React.Component { 5 | constructor(props) { 6 | super(props); 7 | this.state = { 8 | name: "", 9 | ingredients: "", 10 | instruction: "" 11 | }; 12 | 13 | this.onChange = this.onChange.bind(this); 14 | this.onSubmit = this.onSubmit.bind(this); 15 | this.stripHtmlEntities = this.stripHtmlEntities.bind(this); 16 | } 17 | 18 | stripHtmlEntities(str) { 19 | return String(str) 20 | .replace(//g, ">"); 22 | } 23 | 24 | onChange(event) { 25 | this.setState({ [event.target.name]: event.target.value }); 26 | } 27 | 28 | onSubmit(event) { 29 | event.preventDefault(); 30 | const url = "/api/v1/recipes/create"; 31 | const { name, ingredients, instruction } = this.state; 32 | 33 | if (name.length == 0 || ingredients.length == 0 || instruction.length == 0) 34 | return; 35 | 36 | const body = { 37 | name, 38 | ingredients, 39 | instruction: this.stripHtmlEntities( 40 | instruction.replace(/\n/g, "

") 41 | ) 42 | }; 43 | const token = document.querySelector('meta[name="csrf-token"]').content; 44 | 45 | fetch(url, { 46 | method: "POST", 47 | headers: { 48 | "X-CSRF-Token": token, 49 | "Content-Type": "application/json" 50 | }, 51 | body: JSON.stringify(body) 52 | }) 53 | .then(response => { 54 | if (response.ok) { 55 | return response.json(); 56 | } 57 | throw new Error("Network response was not ok."); 58 | }) 59 | .then(response => this.props.history.push(`/recipe/${response.id}`)) 60 | .catch(error => console.log(error.message)); 61 | } 62 | 63 | render() { 64 | return ( 65 |
66 |
67 |
68 |

69 | Add a new recipe to our awesome recipe collection. 70 |

71 |
72 |
73 | 74 | 82 |
83 |
84 | 85 | 93 | 94 | Separate each ingredient with a comma. 95 | 96 |
97 | 98 |