├── .babelrc ├── .gitignore ├── .postcssrc.yml ├── Gemfile ├── Gemfile.lock ├── LICENSE.txt ├── README.md ├── Rakefile ├── app ├── assets │ ├── config │ │ └── manifest.js │ ├── images │ │ └── .keep │ ├── javascripts │ │ ├── application.js │ │ ├── cable.js │ │ ├── channels │ │ │ └── .keep │ │ ├── home.coffee │ │ └── notes.coffee │ └── stylesheets │ │ ├── application.css │ │ ├── home.scss │ │ └── notes.scss ├── channels │ └── application_cable │ │ ├── channel.rb │ │ └── connection.rb ├── controllers │ ├── api │ │ └── notes_controller.rb │ ├── application_controller.rb │ ├── concerns │ │ └── .keep │ └── home_controller.rb ├── helpers │ ├── application_helper.rb │ ├── home_helper.rb │ └── notes_helper.rb ├── javascript │ └── packs │ │ ├── app.js │ │ ├── application.js │ │ ├── containers │ │ └── notes │ │ │ ├── edit.js │ │ │ ├── index.js │ │ │ ├── new.js │ │ │ └── show.js │ │ ├── globalNav.js │ │ ├── home.js │ │ ├── index.js │ │ ├── login.js │ │ ├── modules │ │ ├── auth.js │ │ ├── note.js │ │ └── notes.js │ │ ├── privateRoute.js │ │ └── signup.js ├── jobs │ └── application_job.rb ├── mailers │ └── application_mailer.rb ├── models │ ├── application_record.rb │ ├── concerns │ │ └── .keep │ ├── note.rb │ └── user.rb └── views │ ├── devise │ └── mailer │ │ ├── confirmation_instructions.html.erb │ │ └── reset_password_instructions.html.erb │ ├── home │ ├── confirm_success.html.erb │ └── index.html.erb │ └── layouts │ ├── application.html.erb │ ├── mailer.html.erb │ └── mailer.text.erb ├── bin ├── bundle ├── rails ├── rake ├── setup ├── spring ├── update ├── webpack ├── webpack-dev-server └── yarn ├── config.ru ├── config ├── application.rb ├── boot.rb ├── cable.yml ├── database.yml ├── environment.rb ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── initializers │ ├── application_controller_renderer.rb │ ├── assets.rb │ ├── backtrace_silencers.rb │ ├── cookies_serializer.rb │ ├── devise.rb │ ├── devise_token_auth.rb │ ├── filter_parameter_logging.rb │ ├── inflections.rb │ ├── mime_types.rb │ ├── omniauth.rb │ └── wrap_parameters.rb ├── locales │ ├── devise.en.yml │ └── en.yml ├── puma.rb ├── routes.rb ├── secrets.yml ├── spring.rb ├── webpack │ ├── configuration.js │ ├── development.js │ ├── loaders │ │ ├── assets.js │ │ ├── babel.js │ │ ├── coffee.js │ │ ├── erb.js │ │ ├── react.js │ │ └── sass.js │ ├── production.js │ ├── shared.js │ └── test.js └── webpacker.yml ├── db ├── migrate │ ├── 20170604061340_devise_token_auth_create_users.rb │ └── 20170605031939_create_notes.rb ├── schema.rb └── seeds.rb ├── lib ├── assets │ └── .keep └── tasks │ └── .keep ├── log └── .keep ├── package.json ├── public ├── 404.html ├── 422.html ├── 500.html ├── apple-touch-icon-precomposed.png ├── apple-touch-icon.png ├── favicon.ico └── robots.txt ├── test ├── application_system_test_case.rb ├── controllers │ ├── .keep │ ├── home_controller_test.rb │ └── notes_controller_test.rb ├── fixtures │ ├── .keep │ ├── files │ │ └── .keep │ └── notes.yml ├── helpers │ └── .keep ├── integration │ └── .keep ├── mailers │ └── .keep ├── models │ ├── .keep │ └── note_test.rb ├── system │ └── .keep └── test_helper.rb ├── tmp └── .keep ├── vendor └── .keep └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "env", 5 | { 6 | "modules": false, 7 | "targets": { 8 | "browsers": "> 1%", 9 | "uglify": true 10 | }, 11 | "useBuiltIns": true 12 | } 13 | ], 14 | "react" 15 | ], 16 | "plugins": [ 17 | "syntax-dynamic-import", 18 | [ 19 | "transform-class-properties", 20 | { 21 | "spec": true 22 | } 23 | ] 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /.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 the default SQLite database. 11 | /db/*.sqlite3 12 | /db/*.sqlite3-journal 13 | 14 | # Ignore all logfiles and tempfiles. 15 | /log/* 16 | /tmp/* 17 | !/log/.keep 18 | !/tmp/.keep 19 | 20 | /node_modules 21 | /yarn-error.log 22 | 23 | .byebug_history 24 | 25 | vendor/bundle 26 | .env 27 | /public/packs 28 | /node_modules 29 | -------------------------------------------------------------------------------- /.postcssrc.yml: -------------------------------------------------------------------------------- 1 | plugins: 2 | postcss-smart-import: {} 3 | precss: {} 4 | autoprefixer: {} 5 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | git_source(:github) do |repo_name| 4 | repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") 5 | "https://github.com/#{repo_name}.git" 6 | end 7 | 8 | 9 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 10 | gem 'rails', '~> 5.1.1' 11 | # Use sqlite3 as the database for Active Record 12 | gem 'sqlite3' 13 | # Use Puma as the app server 14 | gem 'puma', '~> 3.7' 15 | # Use SCSS for stylesheets 16 | gem 'sass-rails', '~> 5.0' 17 | # Use Uglifier as compressor for JavaScript assets 18 | gem 'uglifier', '>= 1.3.0' 19 | # See https://github.com/rails/execjs#readme for more supported runtimes 20 | # gem 'therubyracer', platforms: :ruby 21 | 22 | # Use CoffeeScript for .coffee assets and views 23 | gem 'coffee-rails', '~> 4.2' 24 | # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks 25 | gem 'turbolinks', '~> 5' 26 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 27 | gem 'jbuilder', '~> 2.5' 28 | # Use Redis adapter to run Action Cable in production 29 | # gem 'redis', '~> 3.0' 30 | # Use ActiveModel has_secure_password 31 | # gem 'bcrypt', '~> 3.1.7' 32 | 33 | # Use Capistrano for deployment 34 | # gem 'capistrano-rails', group: :development 35 | 36 | gem 'omniauth' 37 | gem 'omniauth-facebook' 38 | gem 'devise_token_auth' 39 | gem 'dotenv-rails' 40 | gem 'webpacker' 41 | 42 | group :development, :test do 43 | # Call 'byebug' anywhere in the code to stop execution and get a debugger console 44 | gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] 45 | # Adds support for Capybara system testing and selenium driver 46 | gem 'capybara', '~> 2.13' 47 | gem 'selenium-webdriver' 48 | gem 'pry-rails' 49 | gem 'pry-byebug' 50 | gem 'pry-stack_explorer' 51 | gem 'pry-doc' 52 | end 53 | 54 | group :development do 55 | # Access an IRB console on exception pages or by using <%= console %> anywhere in the code. 56 | gem 'web-console', '>= 3.3.0' 57 | gem 'listen', '>= 3.0.5', '< 3.2' 58 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring 59 | gem 'spring' 60 | gem 'spring-watcher-listen', '~> 2.0.0' 61 | end 62 | 63 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 64 | gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] 65 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actioncable (5.1.1) 5 | actionpack (= 5.1.1) 6 | nio4r (~> 2.0) 7 | websocket-driver (~> 0.6.1) 8 | actionmailer (5.1.1) 9 | actionpack (= 5.1.1) 10 | actionview (= 5.1.1) 11 | activejob (= 5.1.1) 12 | mail (~> 2.5, >= 2.5.4) 13 | rails-dom-testing (~> 2.0) 14 | actionpack (5.1.1) 15 | actionview (= 5.1.1) 16 | activesupport (= 5.1.1) 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.1.1) 22 | activesupport (= 5.1.1) 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.1.1) 28 | activesupport (= 5.1.1) 29 | globalid (>= 0.3.6) 30 | activemodel (5.1.1) 31 | activesupport (= 5.1.1) 32 | activerecord (5.1.1) 33 | activemodel (= 5.1.1) 34 | activesupport (= 5.1.1) 35 | arel (~> 8.0) 36 | activesupport (5.1.1) 37 | concurrent-ruby (~> 1.0, >= 1.0.2) 38 | i18n (~> 0.7) 39 | minitest (~> 5.1) 40 | tzinfo (~> 1.1) 41 | addressable (2.5.1) 42 | public_suffix (~> 2.0, >= 2.0.2) 43 | arel (8.0.0) 44 | bcrypt (3.1.11) 45 | bindex (0.5.0) 46 | binding_of_caller (0.7.2) 47 | debug_inspector (>= 0.0.1) 48 | builder (3.2.3) 49 | byebug (9.0.6) 50 | capybara (2.14.0) 51 | addressable 52 | mime-types (>= 1.16) 53 | nokogiri (>= 1.3.3) 54 | rack (>= 1.0.0) 55 | rack-test (>= 0.5.4) 56 | xpath (~> 2.0) 57 | childprocess (0.7.0) 58 | ffi (~> 1.0, >= 1.0.11) 59 | coderay (1.1.1) 60 | coffee-rails (4.2.2) 61 | coffee-script (>= 2.2.0) 62 | railties (>= 4.0.0) 63 | coffee-script (2.4.1) 64 | coffee-script-source 65 | execjs 66 | coffee-script-source (1.12.2) 67 | concurrent-ruby (1.0.5) 68 | debug_inspector (0.0.3) 69 | devise (4.3.0) 70 | bcrypt (~> 3.0) 71 | orm_adapter (~> 0.1) 72 | railties (>= 4.1.0, < 5.2) 73 | responders 74 | warden (~> 1.2.3) 75 | devise_token_auth (0.1.42) 76 | devise (> 3.5.2, <= 4.3) 77 | rails (< 6) 78 | dotenv (2.2.1) 79 | dotenv-rails (2.2.1) 80 | dotenv (= 2.2.1) 81 | railties (>= 3.2, < 5.2) 82 | erubi (1.6.0) 83 | execjs (2.7.0) 84 | faraday (0.11.0) 85 | multipart-post (>= 1.2, < 3) 86 | ffi (1.9.18) 87 | globalid (0.4.0) 88 | activesupport (>= 4.2.0) 89 | hashie (3.5.5) 90 | i18n (0.8.4) 91 | jbuilder (2.6.4) 92 | activesupport (>= 3.0.0) 93 | multi_json (>= 1.2) 94 | jwt (1.5.6) 95 | listen (3.1.5) 96 | rb-fsevent (~> 0.9, >= 0.9.4) 97 | rb-inotify (~> 0.9, >= 0.9.7) 98 | ruby_dep (~> 1.2) 99 | loofah (2.0.3) 100 | nokogiri (>= 1.5.9) 101 | mail (2.6.5) 102 | mime-types (>= 1.16, < 4) 103 | method_source (0.8.2) 104 | mime-types (3.1) 105 | mime-types-data (~> 3.2015) 106 | mime-types-data (3.2016.0521) 107 | mini_portile2 (2.1.0) 108 | minitest (5.10.2) 109 | multi_json (1.12.1) 110 | multi_xml (0.6.0) 111 | multipart-post (2.0.0) 112 | nio4r (2.1.0) 113 | nokogiri (1.7.2) 114 | mini_portile2 (~> 2.1.0) 115 | oauth2 (1.3.1) 116 | faraday (>= 0.8, < 0.12) 117 | jwt (~> 1.0) 118 | multi_json (~> 1.3) 119 | multi_xml (~> 0.5) 120 | rack (>= 1.2, < 3) 121 | omniauth (1.6.1) 122 | hashie (>= 3.4.6, < 3.6.0) 123 | rack (>= 1.6.2, < 3) 124 | omniauth-facebook (4.0.0) 125 | omniauth-oauth2 (~> 1.2) 126 | omniauth-oauth2 (1.4.0) 127 | oauth2 (~> 1.0) 128 | omniauth (~> 1.2) 129 | orm_adapter (0.5.0) 130 | pry (0.10.4) 131 | coderay (~> 1.1.0) 132 | method_source (~> 0.8.1) 133 | slop (~> 3.4) 134 | pry-byebug (3.4.2) 135 | byebug (~> 9.0) 136 | pry (~> 0.10) 137 | pry-doc (0.10.0) 138 | pry (~> 0.9) 139 | yard (~> 0.9) 140 | pry-rails (0.3.6) 141 | pry (>= 0.10.4) 142 | pry-stack_explorer (0.4.9.2) 143 | binding_of_caller (>= 0.7) 144 | pry (>= 0.9.11) 145 | public_suffix (2.0.5) 146 | puma (3.9.1) 147 | rack (2.0.3) 148 | rack-test (0.6.3) 149 | rack (>= 1.0) 150 | rails (5.1.1) 151 | actioncable (= 5.1.1) 152 | actionmailer (= 5.1.1) 153 | actionpack (= 5.1.1) 154 | actionview (= 5.1.1) 155 | activejob (= 5.1.1) 156 | activemodel (= 5.1.1) 157 | activerecord (= 5.1.1) 158 | activesupport (= 5.1.1) 159 | bundler (>= 1.3.0, < 2.0) 160 | railties (= 5.1.1) 161 | sprockets-rails (>= 2.0.0) 162 | rails-dom-testing (2.0.3) 163 | activesupport (>= 4.2.0) 164 | nokogiri (>= 1.6) 165 | rails-html-sanitizer (1.0.3) 166 | loofah (~> 2.0) 167 | railties (5.1.1) 168 | actionpack (= 5.1.1) 169 | activesupport (= 5.1.1) 170 | method_source 171 | rake (>= 0.8.7) 172 | thor (>= 0.18.1, < 2.0) 173 | rake (12.0.0) 174 | rb-fsevent (0.9.8) 175 | rb-inotify (0.9.8) 176 | ffi (>= 0.5.0) 177 | responders (2.4.0) 178 | actionpack (>= 4.2.0, < 5.3) 179 | railties (>= 4.2.0, < 5.3) 180 | ruby_dep (1.5.0) 181 | rubyzip (1.2.1) 182 | sass (3.4.24) 183 | sass-rails (5.0.6) 184 | railties (>= 4.0.0, < 6) 185 | sass (~> 3.1) 186 | sprockets (>= 2.8, < 4.0) 187 | sprockets-rails (>= 2.0, < 4.0) 188 | tilt (>= 1.1, < 3) 189 | selenium-webdriver (3.4.0) 190 | childprocess (~> 0.5) 191 | rubyzip (~> 1.0) 192 | websocket (~> 1.0) 193 | slop (3.6.0) 194 | spring (2.0.2) 195 | activesupport (>= 4.2) 196 | spring-watcher-listen (2.0.1) 197 | listen (>= 2.7, < 4.0) 198 | spring (>= 1.2, < 3.0) 199 | sprockets (3.7.1) 200 | concurrent-ruby (~> 1.0) 201 | rack (> 1, < 3) 202 | sprockets-rails (3.2.0) 203 | actionpack (>= 4.0) 204 | activesupport (>= 4.0) 205 | sprockets (>= 3.0.0) 206 | sqlite3 (1.3.13) 207 | thor (0.19.4) 208 | thread_safe (0.3.6) 209 | tilt (2.0.7) 210 | turbolinks (5.0.1) 211 | turbolinks-source (~> 5) 212 | turbolinks-source (5.0.3) 213 | tzinfo (1.2.3) 214 | thread_safe (~> 0.1) 215 | uglifier (3.2.0) 216 | execjs (>= 0.3.0, < 3) 217 | warden (1.2.7) 218 | rack (>= 1.0) 219 | web-console (3.5.1) 220 | actionview (>= 5.0) 221 | activemodel (>= 5.0) 222 | bindex (>= 0.4.0) 223 | railties (>= 5.0) 224 | webpacker (2.0) 225 | activesupport (>= 4.2) 226 | multi_json (~> 1.2) 227 | railties (>= 4.2) 228 | websocket (1.2.4) 229 | websocket-driver (0.6.5) 230 | websocket-extensions (>= 0.1.0) 231 | websocket-extensions (0.1.2) 232 | xpath (2.1.0) 233 | nokogiri (~> 1.3) 234 | yard (0.9.9) 235 | 236 | PLATFORMS 237 | ruby 238 | 239 | DEPENDENCIES 240 | byebug 241 | capybara (~> 2.13) 242 | coffee-rails (~> 4.2) 243 | devise_token_auth 244 | dotenv-rails 245 | jbuilder (~> 2.5) 246 | listen (>= 3.0.5, < 3.2) 247 | omniauth 248 | omniauth-facebook 249 | pry-byebug 250 | pry-doc 251 | pry-rails 252 | pry-stack_explorer 253 | puma (~> 3.7) 254 | rails (~> 5.1.1) 255 | sass-rails (~> 5.0) 256 | selenium-webdriver 257 | spring 258 | spring-watcher-listen (~> 2.0.0) 259 | sqlite3 260 | turbolinks (~> 5) 261 | tzinfo-data 262 | uglifier (>= 1.3.0) 263 | web-console (>= 3.3.0) 264 | webpacker 265 | 266 | BUNDLED WITH 267 | 1.14.3 268 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Yosuke Saito 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-devise-token-auth-sample 2 | 3 | This is a sample application of React on Rails using devise_token_auth gem for authentication. 4 | 5 | ## Development 6 | 7 | ```sh 8 | $ git clone https://github.com/saitoxu/react-devise-token-auth-sample.git 9 | $ cd react-devise-token-auth-sample 10 | $ bundle install --path vendor/bundle 11 | $ yarn install 12 | $ yarn dev 13 | $ rails s # in another shell 14 | ``` 15 | 16 | ## Author 17 | 18 | - Yosuke Saito - [saitoxu](https://github.com/saitoxu) 19 | 20 | ## License 21 | 22 | [MIT](LICENSE.txt) 23 | -------------------------------------------------------------------------------- /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/saitoxu/react-devise-token-auth-sample/68024040bae95024f2bba6f15d6f076dd45ce315/app/assets/images/.keep -------------------------------------------------------------------------------- /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_tree . 15 | -------------------------------------------------------------------------------- /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/saitoxu/react-devise-token-auth-sample/68024040bae95024f2bba6f15d6f076dd45ce315/app/assets/javascripts/channels/.keep -------------------------------------------------------------------------------- /app/assets/javascripts/home.coffee: -------------------------------------------------------------------------------- 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 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/notes.coffee: -------------------------------------------------------------------------------- 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 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/assets/stylesheets/home.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the home controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/notes.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the notes 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/notes_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | class NotesController < ApplicationController 3 | before_action :authenticate_user! 4 | before_action :set_note, only: [:show, :update, :destroy] 5 | 6 | def index 7 | @notes = Note.where(user: current_user) 8 | render json: { notes: @notes }, status: :ok 9 | end 10 | 11 | def show 12 | if @note.user != current_user 13 | render json: { success: false, errors: ['You don\'t have the note'] }, status: :not_found 14 | return 15 | end 16 | render json: { note: @note }, status: :ok 17 | end 18 | 19 | def update 20 | if @note.user != current_user 21 | render json: { success: false, errors: ['You don\'t have the note'] }, status: :not_found 22 | return 23 | end 24 | if @note.update(note_params) 25 | head :no_content 26 | return 27 | end 28 | render json: @note.errors, status: :unprocessable_entity 29 | end 30 | 31 | def create 32 | @note = Note.new(note_params) 33 | @note.user = current_user 34 | if @note.save 35 | render json: { note: @note }, status: :created 36 | return 37 | end 38 | render json: { errors: @note.errors }, status: :unprocessable_entity 39 | end 40 | 41 | def destroy 42 | if @note.user != current_user 43 | render json: { success: false, errors: ['You don\'t have the note'] }, status: :not_found 44 | return 45 | end 46 | if @note.destroy 47 | head :no_content 48 | return 49 | end 50 | render json: @note.errors, status: :unprocessable_entity 51 | end 52 | 53 | private 54 | 55 | def set_note 56 | @note = Note.find(params[:id]) 57 | end 58 | 59 | def note_params 60 | params.require(:note).permit(:title, :content) 61 | end 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | include DeviseTokenAuth::Concerns::SetUserByToken 3 | # protect_from_forgery with: :exception 4 | end 5 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saitoxu/react-devise-token-auth-sample/68024040bae95024f2bba6f15d6f076dd45ce315/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | class HomeController < ApplicationController 2 | def index 3 | end 4 | 5 | def confirm_success 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/home_helper.rb: -------------------------------------------------------------------------------- 1 | module HomeHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/notes_helper.rb: -------------------------------------------------------------------------------- 1 | module NotesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/javascript/packs/app.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Route, Switch } from 'react-router-dom' 3 | import PrivateRoute from './privateRoute' 4 | import GlobalNav from './globalNav' 5 | import Home from './home' 6 | import Signup from './signup' 7 | import Login from './login' 8 | import NoteList from './containers/notes/index' 9 | import NoteForm from './containers/notes/new' 10 | import NoteEdit from './containers/notes/edit' 11 | import Note from './containers/notes/show' 12 | 13 | class App extends React.Component { 14 | render() { 15 | return ( 16 |
17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 |
30 | ) 31 | } 32 | } 33 | 34 | export default App 35 | -------------------------------------------------------------------------------- /app/javascript/packs/application.js: -------------------------------------------------------------------------------- 1 | /* eslint no-console:0 */ 2 | // This file is automatically compiled by Webpack, along with any other files 3 | // present in this directory. You're encouraged to place your actual application logic in 4 | // a relevant structure within app/javascript and only use these pack files to reference 5 | // that code so it'll be compiled. 6 | // 7 | // To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate 8 | // layout file, like app/views/layouts/application.html.erb 9 | 10 | console.log('Hello World from Webpacker') 11 | -------------------------------------------------------------------------------- /app/javascript/packs/containers/notes/edit.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Redirect } from 'react-router-dom' 3 | import { connect } from 'react-redux' 4 | import axios from 'axios' 5 | import { expireAuthentication } from '../../modules/auth' 6 | import { fetchNote } from '../../modules/note' 7 | 8 | class NoteEdit extends React.Component { 9 | constructor(props) { 10 | super(props) 11 | this.state = { 12 | title: '', 13 | content: '', 14 | redirect: false 15 | } 16 | } 17 | 18 | componentDidMount() { 19 | const { id } = this.props.match.params 20 | this.props.dispatch(fetchNote(id)) 21 | } 22 | 23 | componentWillReceiveProps(nextProps) { 24 | const title = nextProps.note ? nextProps.note.title : '' 25 | const content = nextProps.note ? nextProps.note.content : '' 26 | this.setState({ title, content }) 27 | } 28 | 29 | handleSubmit(e) { 30 | e.preventDefault() 31 | const { id } = this.props.match.params 32 | const { title, content } = this.state 33 | const { auth } = this.props 34 | const data = { 35 | note: { title, content } 36 | } 37 | axios({ 38 | url: `/api/notes/${id}`, 39 | method: 'PUT', 40 | headers: { 41 | 'access-token': auth.accessToken, 42 | 'client': auth.client, 43 | 'uid': auth.uid, 44 | 'expiry': auth.expiry, 45 | 'token-type': 'Bearer' 46 | }, 47 | data 48 | }).then(response => { 49 | this.setState({ redirect: true }) 50 | }).catch(error => { 51 | if (error.response && error.response.status === 401) { 52 | this.props.dispatch(expireAuthentication()) 53 | } 54 | }) 55 | } 56 | 57 | render() { 58 | const { id } = this.props.match.params 59 | const { redirect } = this.state 60 | const { loading } = this.props 61 | if (loading) { 62 | return ( 63 |
64 |

Loading...

65 |
66 | ) 67 | } 68 | if (redirect) { 69 | return 70 | } 71 | return ( 72 |
73 |

Edit Note

74 |
75 | 76 | this.setState({ title: e.target.value })} /> 77 | 78 |