├── .gitignore ├── .hound.yml ├── Gemfile ├── Gemfile.lock ├── Procfile.dev ├── README.rdoc ├── Rakefile ├── app ├── assets │ ├── images │ │ └── .keep │ ├── javascripts │ │ ├── application.js.coffee │ │ ├── application_bundle.js │ │ ├── home.js.coffee │ │ └── utils │ │ │ └── google_analytics.js.coffee │ └── stylesheets │ │ ├── application.css.sass │ │ ├── base │ │ ├── _base.scss │ │ ├── _buttons.scss │ │ ├── _flashes.scss │ │ ├── _forms.scss │ │ ├── _grid-settings.scss │ │ ├── _lists.scss │ │ ├── _tables.scss │ │ ├── _typography.scss │ │ ├── _variables.scss │ │ ├── extends │ │ │ ├── _button.scss │ │ │ ├── _clearfix.scss │ │ │ └── _hide-text.scss │ │ └── mixins │ │ │ └── _flash.scss │ │ ├── home.css.sass │ │ └── theme │ │ ├── _avatars.css.sass │ │ ├── _buttons.css.sass │ │ ├── _cards.css.sass │ │ ├── _layout.css.sass │ │ ├── _pagination.css.sass │ │ ├── _person.sass │ │ └── _theme.css.sass ├── controllers │ ├── api │ │ └── v1 │ │ │ └── people_controller.rb │ ├── application_controller.rb │ ├── concerns │ │ └── .keep │ └── home_controller.rb ├── frontend │ ├── actions │ │ ├── index.coffee │ │ ├── people.coffee │ │ └── person.coffee │ ├── application.cjsx │ ├── components │ │ ├── buttons │ │ │ └── reset_button.cjsx │ │ ├── paginator │ │ │ ├── paginator_link.cjsx │ │ │ └── paginator_section.cjsx │ │ └── people │ │ │ ├── card.cjsx │ │ │ ├── list.cjsx │ │ │ ├── no_results.cjsx │ │ │ ├── person.cjsx │ │ │ └── search.cjsx │ ├── constants │ │ └── index.coffee │ ├── containers │ │ └── root.cjsx │ ├── layouts │ │ └── main.cjsx │ ├── reducers │ │ ├── index.coffee │ │ ├── people.coffee │ │ └── person.coffee │ ├── routes │ │ └── index.cjsx │ └── store │ │ └── configure_store.coffee ├── helpers │ └── application_helper.rb ├── mailers │ └── .keep ├── models │ ├── .keep │ ├── concerns │ │ └── .keep │ └── person.rb ├── serializers │ └── person_serializer.rb └── views │ ├── home │ └── index.html.haml │ └── layouts │ └── application.html.haml ├── bin ├── bundle ├── rails ├── rake ├── setup └── spring ├── config.ru ├── config ├── application.rb ├── boot.rb ├── database.yml ├── environment.rb ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── initializers │ ├── assets.rb │ ├── backtrace_silencers.rb │ ├── cookies_serializer.rb │ ├── filter_parameter_logging.rb │ ├── inflections.rb │ ├── kaminari_config.rb │ ├── mime_types.rb │ ├── session_store.rb │ └── wrap_parameters.rb ├── locales │ └── en.yml ├── newrelic.yml ├── routes.rb └── secrets.yml ├── db ├── migrate │ ├── 20140905152314_create_people.rb │ └── 20140905154625_add_picture_to_people.rb ├── schema.rb └── seeds.rb ├── lib ├── assets │ └── .keep └── tasks │ ├── .keep │ └── auto_annotate_models.rake ├── log └── .keep ├── package.json ├── public ├── 404.html ├── 422.html ├── 500.html ├── favicon.ico └── robots.txt ├── vendor └── assets │ ├── javascripts │ └── .keep │ └── stylesheets │ ├── .keep │ └── normalize.css └── webpack.config.js /.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/*.log 16 | /tmp 17 | .ruby-gemset 18 | .ruby-version 19 | node_modules 20 | -------------------------------------------------------------------------------- /.hound.yml: -------------------------------------------------------------------------------- 1 | ruby: 2 | enabled: true 3 | 4 | coffee_script: 5 | enabled: true 6 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | ruby "2.2.3" 4 | 5 | 6 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 7 | gem 'rails' 8 | # Use SCSS for stylesheets 9 | gem 'sass-rails', github: 'rails/sass-rails' 10 | # Use Uglifier as compressor for JavaScript assets 11 | gem 'uglifier', '>= 1.3.0' 12 | # Use CoffeeScript for .js.coffee assets and views 13 | gem 'coffee-rails', '~> 4.0.0' 14 | # See https://github.com/sstephenson/execjs#readme for more supported runtimes 15 | # gem 'therubyracer', platforms: :ruby 16 | 17 | # Use jquery as the JavaScript library 18 | gem 'jquery-rails' 19 | # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks 20 | gem 'turbolinks' 21 | 22 | # Use ActiveModel has_secure_password 23 | # gem 'bcrypt', '~> 3.1.7' 24 | 25 | # Use Rails Html Sanitizer for HTML sanitization 26 | gem 'rails-html-sanitizer', '~> 1.0' 27 | 28 | # Use Unicorn as the app server 29 | # gem 'unicorn' 30 | 31 | # Use Capistrano for deployment 32 | # gem 'capistrano-rails', group: :development 33 | 34 | group :development, :test do 35 | # Call 'debugger' anywhere in the code to stop execution and get a debugger console 36 | gem 'byebug' 37 | 38 | # Access an IRB console on exceptions page and /console in development 39 | gem 'web-console', github: 'rails/web-console' 40 | 41 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring 42 | gem 'spring' 43 | 44 | gem 'thin' 45 | end 46 | 47 | group :development do 48 | gem 'foreman' 49 | end 50 | 51 | group :production do 52 | gem 'rails_12factor' 53 | end 54 | 55 | gem 'pg' 56 | gem 'pg_search' 57 | 58 | gem 'haml-rails' 59 | gem 'bourbon' 60 | gem 'neat' 61 | gem 'bitters' 62 | gem 'faker' 63 | gem 'newrelic_rpm' 64 | 65 | gem "active_model_serializers", github: 'rails-api/active_model_serializers' 66 | 67 | gem 'annotate', github: 'ctran/annotate_models' 68 | gem 'font-awesome-rails' 69 | 70 | gem "js-routes", github: 'railsware/js-routes' 71 | 72 | gem 'kaminari' 73 | gem 'gon' 74 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GIT 2 | remote: git://github.com/ctran/annotate_models.git 3 | revision: 0146ee7b9a70d530a30a5e220c94d5e353624671 4 | specs: 5 | annotate (2.6.10) 6 | activerecord (>= 3.2, <= 4.3) 7 | rake (~> 10.4) 8 | 9 | GIT 10 | remote: git://github.com/rails-api/active_model_serializers.git 11 | revision: 35fb9de3104336fde07df093a4bd7765ac9ea0fa 12 | specs: 13 | active_model_serializers (0.10.0.rc1) 14 | activemodel (>= 4.0) 15 | 16 | GIT 17 | remote: git://github.com/rails/sass-rails.git 18 | revision: 8e68c5f24ed6487277e9df531ec57b375ad1bea2 19 | specs: 20 | sass-rails (5.0.3) 21 | railties (>= 4.0.0, < 5.0) 22 | sass (~> 3.1) 23 | sprockets (>= 2.8, < 4.0) 24 | sprockets-rails (>= 2.0, < 4.0) 25 | tilt (>= 1.1, < 3) 26 | 27 | GIT 28 | remote: git://github.com/rails/web-console.git 29 | revision: 26753c6279db73260a7de018e5630b0b5d56cfe1 30 | specs: 31 | web-console (2.1.2) 32 | activemodel (>= 4.0) 33 | binding_of_caller (>= 0.7.2) 34 | railties (>= 4.0) 35 | sprockets-rails (>= 2.0, < 4.0) 36 | 37 | GIT 38 | remote: git://github.com/railsware/js-routes.git 39 | revision: 42fc4863a398902d86867f3fbf1f58d2838a35d3 40 | specs: 41 | js-routes (1.0.1) 42 | railties (>= 3.2) 43 | sprockets-rails 44 | 45 | GEM 46 | remote: https://rubygems.org/ 47 | specs: 48 | actionmailer (4.2.1) 49 | actionpack (= 4.2.1) 50 | actionview (= 4.2.1) 51 | activejob (= 4.2.1) 52 | mail (~> 2.5, >= 2.5.4) 53 | rails-dom-testing (~> 1.0, >= 1.0.5) 54 | actionpack (4.2.1) 55 | actionview (= 4.2.1) 56 | activesupport (= 4.2.1) 57 | rack (~> 1.6) 58 | rack-test (~> 0.6.2) 59 | rails-dom-testing (~> 1.0, >= 1.0.5) 60 | rails-html-sanitizer (~> 1.0, >= 1.0.1) 61 | actionview (4.2.1) 62 | activesupport (= 4.2.1) 63 | builder (~> 3.1) 64 | erubis (~> 2.7.0) 65 | rails-dom-testing (~> 1.0, >= 1.0.5) 66 | rails-html-sanitizer (~> 1.0, >= 1.0.1) 67 | activejob (4.2.1) 68 | activesupport (= 4.2.1) 69 | globalid (>= 0.3.0) 70 | activemodel (4.2.1) 71 | activesupport (= 4.2.1) 72 | builder (~> 3.1) 73 | activerecord (4.2.1) 74 | activemodel (= 4.2.1) 75 | activesupport (= 4.2.1) 76 | arel (~> 6.0) 77 | activesupport (4.2.1) 78 | i18n (~> 0.7) 79 | json (~> 1.7, >= 1.7.7) 80 | minitest (~> 5.1) 81 | thread_safe (~> 0.3, >= 0.3.4) 82 | tzinfo (~> 1.1) 83 | arel (6.0.0) 84 | binding_of_caller (0.7.2) 85 | debug_inspector (>= 0.0.1) 86 | bitters (1.0.0) 87 | bourbon (>= 3.2) 88 | sass (>= 3.2) 89 | thor 90 | bourbon (4.2.3) 91 | sass (~> 3.4) 92 | thor 93 | builder (3.2.2) 94 | byebug (5.0.0) 95 | columnize (= 0.9.0) 96 | coffee-rails (4.0.1) 97 | coffee-script (>= 2.2.0) 98 | railties (>= 4.0.0, < 5.0) 99 | coffee-script (2.4.1) 100 | coffee-script-source 101 | execjs 102 | coffee-script-source (1.9.1.1) 103 | columnize (0.9.0) 104 | daemons (1.2.2) 105 | debug_inspector (0.0.2) 106 | erubis (2.7.0) 107 | eventmachine (1.0.7) 108 | execjs (2.5.2) 109 | faker (1.4.3) 110 | i18n (~> 0.5) 111 | font-awesome-rails (4.3.0.0) 112 | railties (>= 3.2, < 5.0) 113 | foreman (0.78.0) 114 | thor (~> 0.19.1) 115 | globalid (0.3.5) 116 | activesupport (>= 4.1.0) 117 | gon (5.2.3) 118 | actionpack (>= 2.3.0) 119 | json 120 | multi_json 121 | request_store (>= 1.0.5) 122 | haml (4.0.6) 123 | tilt 124 | haml-rails (0.9.0) 125 | actionpack (>= 4.0.1) 126 | activesupport (>= 4.0.1) 127 | haml (>= 4.0.6, < 5.0) 128 | html2haml (>= 1.0.1) 129 | railties (>= 4.0.1) 130 | html2haml (2.0.0) 131 | erubis (~> 2.7.0) 132 | haml (~> 4.0.0) 133 | nokogiri (~> 1.6.0) 134 | ruby_parser (~> 3.5) 135 | i18n (0.7.0) 136 | jquery-rails (4.0.3) 137 | rails-dom-testing (~> 1.0) 138 | railties (>= 4.2.0) 139 | thor (>= 0.14, < 2.0) 140 | json (1.8.3) 141 | kaminari (0.16.3) 142 | actionpack (>= 3.0.0) 143 | activesupport (>= 3.0.0) 144 | loofah (2.0.2) 145 | nokogiri (>= 1.5.9) 146 | mail (2.6.3) 147 | mime-types (>= 1.16, < 3) 148 | mime-types (2.6.1) 149 | mini_portile (0.6.2) 150 | minitest (5.7.0) 151 | multi_json (1.11.0) 152 | neat (1.7.2) 153 | bourbon (>= 4.0) 154 | sass (>= 3.3) 155 | newrelic_rpm (3.12.0.288) 156 | nokogiri (1.6.6.2) 157 | mini_portile (~> 0.6.0) 158 | pg (0.18.2) 159 | pg_search (1.0.3) 160 | activerecord (>= 3.1) 161 | activesupport (>= 3.1) 162 | arel 163 | rack (1.6.1) 164 | rack-test (0.6.3) 165 | rack (>= 1.0) 166 | rails (4.2.1) 167 | actionmailer (= 4.2.1) 168 | actionpack (= 4.2.1) 169 | actionview (= 4.2.1) 170 | activejob (= 4.2.1) 171 | activemodel (= 4.2.1) 172 | activerecord (= 4.2.1) 173 | activesupport (= 4.2.1) 174 | bundler (>= 1.3.0, < 2.0) 175 | railties (= 4.2.1) 176 | sprockets-rails 177 | rails-deprecated_sanitizer (1.0.3) 178 | activesupport (>= 4.2.0.alpha) 179 | rails-dom-testing (1.0.6) 180 | activesupport (>= 4.2.0.beta, < 5.0) 181 | nokogiri (~> 1.6.0) 182 | rails-deprecated_sanitizer (>= 1.0.1) 183 | rails-html-sanitizer (1.0.2) 184 | loofah (~> 2.0) 185 | rails_12factor (0.0.3) 186 | rails_serve_static_assets 187 | rails_stdout_logging 188 | rails_serve_static_assets (0.0.4) 189 | rails_stdout_logging (0.0.3) 190 | railties (4.2.1) 191 | actionpack (= 4.2.1) 192 | activesupport (= 4.2.1) 193 | rake (>= 0.8.7) 194 | thor (>= 0.18.1, < 2.0) 195 | rake (10.4.2) 196 | request_store (1.1.0) 197 | ruby_parser (3.7.0) 198 | sexp_processor (~> 4.1) 199 | sass (3.4.14) 200 | sexp_processor (4.6.0) 201 | spring (1.3.6) 202 | sprockets (3.2.0) 203 | rack (~> 1.0) 204 | sprockets-rails (2.3.1) 205 | actionpack (>= 3.0) 206 | activesupport (>= 3.0) 207 | sprockets (>= 2.8, < 4.0) 208 | thin (1.6.3) 209 | daemons (~> 1.0, >= 1.0.9) 210 | eventmachine (~> 1.0) 211 | rack (~> 1.0) 212 | thor (0.19.1) 213 | thread_safe (0.3.5) 214 | tilt (2.0.1) 215 | turbolinks (2.5.3) 216 | coffee-rails 217 | tzinfo (1.2.2) 218 | thread_safe (~> 0.1) 219 | uglifier (2.7.1) 220 | execjs (>= 0.3.0) 221 | json (>= 1.8.0) 222 | 223 | PLATFORMS 224 | ruby 225 | 226 | DEPENDENCIES 227 | active_model_serializers! 228 | annotate! 229 | bitters 230 | bourbon 231 | byebug 232 | coffee-rails (~> 4.0.0) 233 | faker 234 | font-awesome-rails 235 | foreman 236 | gon 237 | haml-rails 238 | jquery-rails 239 | js-routes! 240 | kaminari 241 | neat 242 | newrelic_rpm 243 | pg 244 | pg_search 245 | rails 246 | rails-html-sanitizer (~> 1.0) 247 | rails_12factor 248 | sass-rails! 249 | spring 250 | thin 251 | turbolinks 252 | uglifier (>= 1.3.0) 253 | web-console! 254 | -------------------------------------------------------------------------------- /Procfile.dev: -------------------------------------------------------------------------------- 1 | web: bundle exec spring rails server 2 | webpack: webpack --watch --colors 3 | -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | == Rails and Redux: A real use case 2 | 3 | This is a real use case application using: 4 | 5 | * Rails 4.2.0. 6 | * Webpack for managing JavaScript modules. 7 | * React.js. 8 | * Redux as Flux implementation. 9 | * PostgreSQL full-text search. 10 | 11 | To install it, just clone it and run: 12 | 13 | $ gem install foreman 14 | $ bundle install 15 | $ npm install -g webpack 16 | $ npm install 17 | $ db:setup 18 | 19 | To run it: 20 | $ foreman start -f Procfile.dev 21 | 22 | Happy coding! 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 File.expand_path('../config/application', __FILE__) 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigardone/rails_and_redux/66010a99f4e41bcee1737043adcbab7ad2485e6d/app/assets/images/.keep -------------------------------------------------------------------------------- /app/assets/javascripts/application.js.coffee: -------------------------------------------------------------------------------- 1 | #= require jquery 2 | #= require jquery_ujs 3 | #= require turbolinks 4 | #= require js-routes 5 | 6 | #= require application_bundle 7 | -------------------------------------------------------------------------------- /app/assets/javascripts/home.js.coffee: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/assets/javascripts/utils/google_analytics.js.coffee: -------------------------------------------------------------------------------- 1 | class @GoogleAnalytics 2 | @load: -> 3 | # Google Analytics depends on a global _gaq array. window is the global scope. 4 | window._gaq = [] 5 | window._gaq.push ["_setAccount", GoogleAnalytics.analyticsId()] 6 | 7 | # Create a script element and insert it in the DOM 8 | ga = document.createElement("script") 9 | ga.type = "text/javascript" 10 | ga.async = true 11 | ga.src = ((if "https:" is document.location.protocol then "https://ssl" else "http://www")) + ".google-analytics.com/ga.js" 12 | firstScript = document.getElementsByTagName("script")[0] 13 | firstScript.parentNode.insertBefore ga, firstScript 14 | 15 | GoogleAnalytics.trackPageview() 16 | 17 | @trackPageview: (url) -> 18 | unless GoogleAnalytics.isLocalRequest() 19 | if url 20 | window._gaq.push ["_trackPageview", url] 21 | else 22 | window._gaq.push ["_trackPageview"] 23 | window._gaq.push ["_trackPageLoadTime"] 24 | 25 | @isLocalRequest: -> 26 | GoogleAnalytics.documentDomainIncludes "local" 27 | 28 | @documentDomainIncludes: (str) -> 29 | document.domain.indexOf(str) isnt -1 30 | 31 | @analyticsId: -> 32 | gon.google_analytics_id 33 | 34 | GoogleAnalytics.load() 35 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css.sass: -------------------------------------------------------------------------------- 1 | @import normalize 2 | @import bourbon 3 | @import neat 4 | @import base/base 5 | 6 | @import font-awesome 7 | 8 | @import theme/theme 9 | 10 | @import home 11 | -------------------------------------------------------------------------------- /app/assets/stylesheets/base/_base.scss: -------------------------------------------------------------------------------- 1 | // Bitters v0.10.0 2 | // http://bitters.bourbon.io 3 | 4 | // Variables 5 | @import 'variables'; 6 | 7 | // Neat Settings -- uncomment if using Neat -- must be imported before Neat 8 | // @import 'grid-settings'; 9 | 10 | // Mixins 11 | @import 'mixins/flash'; 12 | 13 | // Extends 14 | @import 'extends/button'; 15 | @import 'extends/clearfix'; 16 | @import 'extends/hide-text'; 17 | 18 | // Typography and Elements 19 | @import 'typography'; 20 | @import 'forms'; 21 | @import 'tables'; 22 | @import 'lists'; 23 | @import 'flashes'; 24 | @import 'buttons'; 25 | -------------------------------------------------------------------------------- /app/assets/stylesheets/base/_buttons.scss: -------------------------------------------------------------------------------- 1 | button, 2 | input[type="submit"] { 3 | @extend %button; 4 | @include appearance(none); 5 | border: none; 6 | cursor: pointer; 7 | user-select: none; 8 | vertical-align: middle; 9 | white-space: nowrap; 10 | } 11 | -------------------------------------------------------------------------------- /app/assets/stylesheets/base/_flashes.scss: -------------------------------------------------------------------------------- 1 | %flash-alert { 2 | @include flash($alert-color); 3 | } 4 | 5 | %flash-error { 6 | @include flash($error-color); 7 | } 8 | 9 | %flash-notice { 10 | @include flash($notice-color); 11 | } 12 | 13 | %flash-success { 14 | @include flash($success-color); 15 | } 16 | -------------------------------------------------------------------------------- /app/assets/stylesheets/base/_forms.scss: -------------------------------------------------------------------------------- 1 | fieldset { 2 | background: lighten($base-border-color, 10); 3 | border: 1px solid $base-border-color; 4 | margin: 0 0 ($base-line-height / 2) 0; 5 | padding: $base-line-height; 6 | } 7 | 8 | input, 9 | label, 10 | select { 11 | display: block; 12 | font-family: $form-font-family; 13 | font-size: $form-font-size; 14 | } 15 | 16 | label { 17 | font-weight: bold; 18 | margin-bottom: $base-line-height / 4; 19 | 20 | &.required:after { 21 | content: "*"; 22 | } 23 | 24 | abbr { 25 | display: none; 26 | } 27 | } 28 | 29 | textarea, 30 | #{$all-text-inputs}, 31 | select[multiple=multiple] { 32 | @include box-sizing(border-box); 33 | @include transition(border-color); 34 | background-color: white; 35 | border-radius: $form-border-radius; 36 | border: 1px solid $form-border-color; 37 | box-shadow: $form-box-shadow; 38 | font-family: $form-font-family; 39 | font-size: $form-font-size; 40 | margin-bottom: $base-line-height / 2; 41 | padding: ($base-line-height / 3) ($base-line-height / 3); 42 | width: 100%; 43 | 44 | &:hover { 45 | border-color: $form-border-color-hover; 46 | } 47 | 48 | &:focus { 49 | border-color: $form-border-color-focus; 50 | box-shadow: $form-box-shadow-focus; 51 | outline: none; 52 | } 53 | } 54 | 55 | textarea { 56 | resize: vertical; 57 | } 58 | 59 | input[type="search"] { 60 | @include appearance(none); 61 | } 62 | 63 | input[type="checkbox"], input[type="radio"] { 64 | display: inline; 65 | margin-right: $base-line-height / 4; 66 | } 67 | 68 | input[type="file"] { 69 | margin-bottom: $base-line-height / 2; 70 | padding-bottom: ($base-line-height / 3); 71 | width: 100%; 72 | } 73 | 74 | select { 75 | width: auto; 76 | max-width: 100%; 77 | margin-bottom: $base-line-height; 78 | } 79 | -------------------------------------------------------------------------------- /app/assets/stylesheets/base/_grid-settings.scss: -------------------------------------------------------------------------------- 1 | @import 'neat-helpers'; // or '../neat/neat-helpers' when not in Rails 2 | 3 | // Neat Overrides 4 | // $column: 90px; 5 | // $gutter: 30px; 6 | // $grid-columns: 12; 7 | // $max-width: em(1088); 8 | 9 | // Neat Breakpoints 10 | $medium-screen: em(640); 11 | $large-screen: em(860); 12 | 13 | $medium-screen-up: new-breakpoint(min-width $medium-screen 4); 14 | $large-screen-up: new-breakpoint(min-width $large-screen 8); 15 | -------------------------------------------------------------------------------- /app/assets/stylesheets/base/_lists.scss: -------------------------------------------------------------------------------- 1 | ul, ol { 2 | margin: 0; 3 | padding: 0; 4 | list-style-type: none; 5 | 6 | &%default-ul { 7 | list-style-type: disc; 8 | margin-bottom: $base-line-height / 2; 9 | padding-left: $base-line-height; 10 | } 11 | 12 | &%default-ol { 13 | list-style-type: decimal; 14 | margin-bottom: $base-line-height / 2; 15 | padding-left: $base-line-height; 16 | } 17 | } 18 | 19 | dl { 20 | margin-bottom: $base-line-height / 2; 21 | 22 | dt { 23 | font-weight: bold; 24 | margin-top: $base-line-height / 2; 25 | } 26 | 27 | dd { 28 | margin: 0; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/assets/stylesheets/base/_tables.scss: -------------------------------------------------------------------------------- 1 | table { 2 | border-collapse: collapse; 3 | margin: ($base-line-height / 2) 0; 4 | table-layout: fixed; 5 | width: 100%; 6 | } 7 | 8 | th { 9 | border-bottom: 1px solid darken($base-border-color, 15%); 10 | font-weight: bold; 11 | padding: ($base-line-height / 2) 0; 12 | text-align: left; 13 | } 14 | 15 | td { 16 | border-bottom: 1px solid $base-border-color; 17 | padding: ($base-line-height / 2) 0; 18 | } 19 | 20 | tr, td, th { 21 | vertical-align: middle; 22 | } 23 | -------------------------------------------------------------------------------- /app/assets/stylesheets/base/_typography.scss: -------------------------------------------------------------------------------- 1 | body { 2 | -webkit-font-smoothing: antialiased; 3 | background-color: $base-background-color; 4 | color: $base-font-color; 5 | font-family: $base-font-family; 6 | font-size: $base-font-size; 7 | line-height: $unitless-line-height; 8 | } 9 | 10 | h1, h2, h3, h4, h5, h6 { 11 | font-family: $header-font-family; 12 | line-height: $header-line-height; 13 | margin: 0; 14 | text-rendering: optimizeLegibility; // Fix the character spacing for headings 15 | } 16 | 17 | h1 { 18 | font-size: $base-font-size * 2.25; // 16 * 2.25 = 36px 19 | } 20 | 21 | h2 { 22 | font-size: $base-font-size * 2; // 16 * 2 = 32px 23 | } 24 | 25 | h3 { 26 | font-size: $base-font-size * 1.75; // 16 * 1.75 = 28px 27 | } 28 | 29 | h4 { 30 | font-size: $base-font-size * 1.4; // 16 * 1.5 = 24px 31 | } 32 | 33 | h5 { 34 | font-size: $base-font-size * 1.25; // 16 * 1.25 = 20px 35 | } 36 | 37 | h6 { 38 | font-size: $base-font-size; 39 | } 40 | 41 | p { 42 | margin: 0 0 ($base-line-height * .5); 43 | } 44 | 45 | a { 46 | @include transition(color 0.1s linear); 47 | color: $base-link-color; 48 | text-decoration: none; 49 | 50 | &:hover { 51 | color: $hover-link-color; 52 | } 53 | 54 | &:active, &:focus { 55 | color: $hover-link-color; 56 | outline: none; 57 | } 58 | } 59 | 60 | hr { 61 | border-bottom: 1px solid $base-border-color; 62 | border-left: none; 63 | border-right: none; 64 | border-top: none; 65 | margin: $base-line-height 0; 66 | } 67 | 68 | img { 69 | margin: 0; 70 | max-width: 100%; 71 | } 72 | 73 | blockquote { 74 | border-left: 2px solid $base-border-color; 75 | color: lighten($base-font-color, 15); 76 | margin: $base-line-height 0; 77 | padding-left: $base-line-height / 2; 78 | } 79 | 80 | cite { 81 | color: lighten($base-font-color, 25); 82 | font-style: italic; 83 | 84 | &:before { 85 | content: '\2014 \00A0'; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /app/assets/stylesheets/base/_variables.scss: -------------------------------------------------------------------------------- 1 | // Typography 2 | $sans-serif: $helvetica; 3 | $serif: $georgia; 4 | $base-font-family: 'Average Sans', sans-serif; 5 | $header-font-family: 'Fjalla One', sans-serif; 6 | 7 | // Sizes 8 | $base-font-size: 1em; 9 | $base-line-height: $base-font-size * 1.5; 10 | $unitless-line-height: $base-line-height / ($base-line-height * 0 + 1); // Strip units from line-height: https://developer.mozilla.org/en-US/docs/Web/CSS/line-height#Prefer_unitless_numbers_for_line-height_values 11 | $header-line-height: $base-font-size * 1.25; 12 | $base-border-radius: 4px; 13 | 14 | // Colors 15 | $blue: #3498db; 16 | $green: #2ecc71; 17 | $red: #e74c3c; 18 | $yellow: #f1c40f; 19 | $orange: #e67e22; 20 | $purple: #9b59b6; 21 | $gray: #bdc3c7; 22 | $asphalt: #34495e; 23 | $pink: #ff5aec; 24 | 25 | $dark-blue: darken($blue, 15); 26 | $dark-purple: darken($purple, 15); 27 | $light-gray: lighten($gray, 15); 28 | $lighter-gray: lighten($gray, 20); 29 | $medium-gray: darken($gray, 10); 30 | $dark-gray: darken($gray, 40); 31 | $light-red: lighten($red, 15); 32 | $light-yellow: lighten($yellow, 15); 33 | $light-green: lighten($green, 15); 34 | $dark-asphalt: darken($asphalt, 7); 35 | $light-blue: lighten($blue, 20); 36 | $dark-orange: darken($orange, 15); 37 | $dark-red: darken($red, 15); 38 | $light-pink: lighten($pink, 31); 39 | 40 | // Background Color 41 | $base-background-color: $dark-gray; 42 | 43 | // Font Colors 44 | $base-font-color: $light-gray; 45 | $base-accent-color: $light-blue; 46 | 47 | // Link Colors 48 | $base-link-color: $base-accent-color; 49 | $hover-link-color: darken($base-accent-color, 15); 50 | $base-button-color: $base-link-color; 51 | $hover-button-color: $hover-link-color; 52 | 53 | // Border color 54 | $base-border-color: transparent; 55 | 56 | // Flash Colors 57 | $alert-color: $light-yellow; 58 | $error-color: $light-red; 59 | $notice-color: $light-yellow; 60 | $success-color: $light-green; 61 | 62 | // Forms 63 | $form-border-color: $base-border-color; 64 | $form-border-color-hover: darken($base-border-color, 10); 65 | $form-border-color-focus: $base-border-color; 66 | $form-border-radius: $base-border-radius; 67 | $form-box-shadow: 0 0 0; 68 | $form-box-shadow-focus: $form-box-shadow, 0 0 5px rgba(darken($form-border-color-focus, 5), 0.7); 69 | $form-font-size: $base-font-size; 70 | $form-font-family: $base-font-family; 71 | 72 | // Nprogress bar 73 | $nprogress-color: $blue; 74 | 75 | // Breakpoints 76 | $mobile: new-breakpoint(max-width 480px); 77 | $tablet: new-breakpoint(min-width 481px max-width 768px); 78 | $desktop: new-breakpoint(min-width 769px); 79 | -------------------------------------------------------------------------------- /app/assets/stylesheets/base/extends/_button.scss: -------------------------------------------------------------------------------- 1 | %button { 2 | -webkit-font-smoothing: antialiased; 3 | background-color: $base-button-color; 4 | border-radius: $base-border-radius; 5 | color: white; 6 | display: inline-block; 7 | font-size: $base-font-size; 8 | font-weight: bold; 9 | line-height: 1; 10 | padding: .75em 1em; 11 | text-decoration: none; 12 | 13 | &:hover { 14 | background-color: $hover-button-color; 15 | color: white; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/assets/stylesheets/base/extends/_clearfix.scss: -------------------------------------------------------------------------------- 1 | %clearfix { 2 | @include clearfix; 3 | } 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/base/extends/_hide-text.scss: -------------------------------------------------------------------------------- 1 | %hide-text { 2 | @include hide-text; 3 | } 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/base/mixins/_flash.scss: -------------------------------------------------------------------------------- 1 | @mixin flash($color) { 2 | background: $color; 3 | color: darken($color, 60); 4 | font-weight: bold; 5 | margin-bottom: $base-line-height / 2; 6 | padding: $base-line-height / 2; 7 | 8 | a { 9 | color: darken($color, 70); 10 | 11 | &:hover { 12 | color: darken($color, 90); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/assets/stylesheets/home.css.sass: -------------------------------------------------------------------------------- 1 | section 2 | header 3 | margin-bottom: 1em 4 | 5 | +media($mobile) 6 | h1 7 | font-size: 1.4em 8 | +media($tablet) 9 | h1 10 | font-size: 1.6rem 11 | 12 | .filter-wrapper 13 | +clearfix 14 | margin-bottom: 2rem 15 | 16 | .overview-wrapper 17 | +media($desktop) 18 | +span-columns(8) 19 | .form-wrapper 20 | +media($desktop) 21 | +span-columns(4) 22 | 23 | position: relative 24 | 25 | .reset 26 | position: absolute 27 | right: .5em 28 | top: .4em 29 | 30 | [type=search] 31 | +transition(all linear .3s) 32 | background: rgba(#fff, .5) 33 | display: inline-block 34 | padding: .5em 35 | color: $dark-gray 36 | 37 | &::-webkit-input-placeholder 38 | color: $dark-gray 39 | &:-moz-placeholder 40 | color: $dark-gray 41 | &::-moz-placeholder 42 | color: $dark-gray 43 | &:-ms-input-placeholder 44 | color: $dark-gray 45 | 46 | &:focus 47 | background: #fff 48 | box-shadow: 0 0 0 49 | 50 | &::-webkit-input-placeholder 51 | color: $gray 52 | &:-moz-placeholder 53 | color: $gray 54 | &::-moz-placeholder 55 | color: $gray 56 | &:-ms-input-placeholder 57 | color: $gray 58 | 59 | .warning 60 | text-align: center 61 | padding: 6rem 0 62 | .fa-stack 63 | font-size: 3em 64 | margin-bottom: 2rem 65 | h4 66 | line-height: 2em 67 | .btn 68 | margin: 2rem 69 | 70 | .relative 71 | position: relative 72 | 73 | -------------------------------------------------------------------------------- /app/assets/stylesheets/theme/_avatars.css.sass: -------------------------------------------------------------------------------- 1 | .avatar 2 | +transition 3 | background-color: #FFF 4 | width: 105px 5 | height: 105px 6 | border-radius: 50% 7 | display: block 8 | margin-bottom: .5rem 9 | border: 3px solid #fff 10 | -------------------------------------------------------------------------------- /app/assets/stylesheets/theme/_buttons.css.sass: -------------------------------------------------------------------------------- 1 | .btn 2 | +transition 3 | color: $base-font-color 4 | border: 1px solid $base-font-color 5 | padding: .6em 2em 6 | display: inline-block 7 | border-radius: $base-border-radius 8 | text-transform: uppercase 9 | 10 | &:hover 11 | background: $base-font-color 12 | color: $base-background-color 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/assets/stylesheets/theme/_cards.css.sass: -------------------------------------------------------------------------------- 1 | .cards-wrapper 2 | +clearfix 3 | position: relative 4 | 5 | .card 6 | +transition 7 | background: #fff 8 | margin-bottom: 2rem 9 | border-radius: $base-border-radius 10 | color: $base-background-color 11 | 12 | +media($mobile) 13 | +span-columns(12 of 12) 14 | +omega(2n) 15 | 16 | +media($tablet) 17 | +span-columns(6 of 12) 18 | +omega(2n) 19 | 20 | +media($desktop) 21 | +span-columns(4 of 12) 22 | +omega(3n) 23 | 24 | header 25 | +pad(1rem) 26 | +clearfix 27 | color: #fff 28 | margin-bottom: .5em 29 | border-radius: $base-border-radius $base-border-radius 0 0 30 | h4 31 | overflow: hidden 32 | text-overflow: ellipsis 33 | white-space: nowrap 34 | .avatar-wrapper 35 | +span-columns(5) 36 | position: relative 37 | .avatar 38 | +position(absolute, 0 0) 39 | .info-wrapper 40 | +span-columns(7) 41 | 42 | .card-body 43 | +pad(1rem) 44 | +clearfix 45 | border-radius: 0 0 $base-border-radius $base-border-radius 46 | 47 | .meta 48 | font-size: .9em 49 | li 50 | overflow: hidden 51 | text-overflow: ellipsis 52 | white-space: nowrap 53 | .fa 54 | font-size: .9em 55 | 56 | .headline 57 | height: 3em 58 | font-style: italic 59 | margin-bottom: 2rem 60 | 61 | .contact-info 62 | margin: -1rem 63 | padding: 1rem 64 | background: lighten($gray, 10) 65 | border-radius: 0 0 $base-border-radius $base-border-radius 66 | 67 | 68 | .fa 69 | margin-right: 1em 70 | opacity: .5 71 | 72 | 73 | &.female 74 | header 75 | background: lighten($pink, 10) 76 | 77 | &.male 78 | header 79 | background: lighten($blue, 10) 80 | 81 | &:hover 82 | box-shadow: 0 0.2em 0 0 $gray 83 | 84 | header 85 | .avatar 86 | +transform(scale(1.2)) 87 | margin-top: -30px 88 | 89 | .card-enter 90 | +transition(.5s linear all) 91 | opacity: 0.01 92 | 93 | .card-enter.card-enter-active 94 | opacity: 1 95 | 96 | .card-leave 97 | +transition(.5s linear all) 98 | opacity: 1 99 | 100 | .card-leave.card-leave-active 101 | opacity: 0.01 102 | 103 | -------------------------------------------------------------------------------- /app/assets/stylesheets/theme/_layout.css.sass: -------------------------------------------------------------------------------- 1 | html, body 2 | height: 100% 3 | 4 | body 5 | background: $base-background-color 6 | padding: 0 1rem 7 | 8 | #main_wrapper 9 | min-height: 100% 10 | padding: 2rem 0 11 | section 12 | +outer-container 13 | 14 | #main_footer 15 | padding: 2rem 0 16 | text-align: center 17 | -------------------------------------------------------------------------------- /app/assets/stylesheets/theme/_pagination.css.sass: -------------------------------------------------------------------------------- 1 | $size: em(14) 2 | 3 | .pagination 4 | +clearfix 5 | margin-bottom: 2rem 6 | text-align: center 7 | li 8 | display: inline-block 9 | a, span 10 | +transition 11 | background: $base-accent-color 12 | margin-left: $size/2 13 | display: inline-block 14 | border-radius: 50% 15 | width: $size 16 | height: $size 17 | 18 | a:hover 19 | background: darken($base-accent-color, 10) 20 | 21 | span 22 | background: $gray 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/assets/stylesheets/theme/_person.sass: -------------------------------------------------------------------------------- 1 | .person-detail 2 | background: #fff 3 | margin-bottom: 2rem 4 | border-radius: $base-border-radius 5 | width: 80% 6 | margin: 3em auto 7 | color: $base-background-color 8 | 9 | 10 | header 11 | +pad(1rem) 12 | +clearfix 13 | color: #fff 14 | margin-bottom: .5em 15 | border-radius: $base-border-radius $base-border-radius 0 0 16 | text-align: center 17 | h4 18 | overflow: hidden 19 | text-overflow: ellipsis 20 | white-space: nowrap 21 | line-height: 3em 22 | 23 | .avatar 24 | margin: 0 auto 25 | 26 | .card-body 27 | +pad(1rem) 28 | +clearfix 29 | border-radius: 0 0 $base-border-radius $base-border-radius 30 | 31 | .meta 32 | font-size: .9em 33 | li 34 | overflow: hidden 35 | text-overflow: ellipsis 36 | white-space: nowrap 37 | .fa 38 | font-size: .9em 39 | 40 | .headline 41 | height: 3em 42 | font-style: italic 43 | margin-bottom: 2rem 44 | 45 | .contact-info 46 | +clearfix 47 | margin: -1rem 48 | padding: 1rem 49 | background: lighten($gray, 10) 50 | border-radius: 0 0 $base-border-radius $base-border-radius 51 | 52 | li 53 | +span-columns(6) 54 | text-align: center 55 | font-size: 1.4em 56 | 57 | 58 | .fa 59 | opacity: .2 60 | font-size: 1.5em 61 | display: block 62 | line-height: 1.5em 63 | 64 | 65 | &.female 66 | header 67 | background: lighten($pink, 10) 68 | 69 | &.male 70 | header 71 | background: lighten($blue, 10) 72 | -------------------------------------------------------------------------------- /app/assets/stylesheets/theme/_theme.css.sass: -------------------------------------------------------------------------------- 1 | @import layout 2 | @import cards 3 | @import avatars 4 | @import pagination 5 | @import buttons 6 | @import person 7 | -------------------------------------------------------------------------------- /app/controllers/api/v1/people_controller.rb: -------------------------------------------------------------------------------- 1 | class Api::V1::PeopleController < ApplicationController 2 | before_filter :search_people 3 | 4 | def index 5 | render json: { 6 | people: @people, 7 | meta: { 8 | current_page: @people.current_page, 9 | next_page: @people.next_page, 10 | prev_page: @people.prev_page, 11 | total_pages: @people.total_pages, 12 | total_count: @people.total_count 13 | } 14 | } 15 | end 16 | 17 | def show 18 | person = Person.find params[:id] 19 | 20 | render json: person, root: 'person' 21 | end 22 | 23 | private 24 | 25 | def search_people 26 | @people = Person.sorted 27 | @people = @people.search(params[:search]) unless params[:search].blank? 28 | @people = @people.page(params[:page]) 29 | @people 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Prevent CSRF attacks by raising an exception. 3 | # For APIs, you may want to use :null_session instead. 4 | protect_from_forgery with: :exception 5 | before_filter :set_gon_variables 6 | 7 | protected 8 | 9 | def set_gon_variables 10 | gon.google_analytics_id = Rails.application.secrets[:google_analytics_id] 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigardone/rails_and_redux/66010a99f4e41bcee1737043adcbab7ad2485e6d/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | class HomeController < ApplicationController 2 | def index 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/frontend/actions/index.coffee: -------------------------------------------------------------------------------- 1 | module.exports = 2 | people: require './people' 3 | person: require './person' 4 | 5 | -------------------------------------------------------------------------------- /app/frontend/actions/people.coffee: -------------------------------------------------------------------------------- 1 | fetch = require 'isomorphic-fetch' 2 | { REQUEST_PEOPLE, RECEIVE_PEOPLE, SET_SEARCH } = require '../constants' 3 | 4 | module.exports = 5 | requestPeople: (params) -> 6 | type: REQUEST_PEOPLE 7 | pageNumber: params.page 8 | search: params.search 9 | 10 | fetchPeople: (params = {}) -> 11 | (dispatch) => 12 | dispatch @requestPeople(params) 13 | 14 | fetch(Routes.api_v1_people_path(params)) 15 | .then (req) => 16 | req.json() 17 | .then (json) => 18 | dispatch @receivePeople(json) 19 | 20 | receivePeople: (json) -> 21 | type: RECEIVE_PEOPLE 22 | people: json.people 23 | meta: json.meta 24 | 25 | setSearch: (search) -> 26 | (dispatch) => 27 | dispatch 28 | type: SET_SEARCH 29 | search: search 30 | -------------------------------------------------------------------------------- /app/frontend/actions/person.coffee: -------------------------------------------------------------------------------- 1 | fetch = require 'isomorphic-fetch' 2 | { REQUEST_PERSON, RECEIVE_PERSON } = require '../constants' 3 | 4 | module.exports = 5 | requestPerson: () -> 6 | type: REQUEST_PERSON 7 | 8 | loadPerson: (id) -> 9 | (dispatch) => 10 | dispatch @requestPerson() 11 | 12 | fetch(Routes.api_v1_person_path(id)) 13 | .then (req) => 14 | req.json() 15 | .then (json) => 16 | dispatch @receivePerson(json) 17 | 18 | receivePerson: (json) -> 19 | type: RECEIVE_PERSON 20 | person: json.person 21 | 22 | -------------------------------------------------------------------------------- /app/frontend/application.cjsx: -------------------------------------------------------------------------------- 1 | ReactDOM = require 'react-dom' 2 | Root = require './containers/root' 3 | configureStore = require './store/configure_store' 4 | createBrowserHistory = require 'history/lib/createBrowserHistory' 5 | 6 | window.onload = -> 7 | store = configureStore() 8 | 9 | ReactDOM.render , document.getElementById 'main_wrapper' 10 | -------------------------------------------------------------------------------- /app/frontend/components/buttons/reset_button.cjsx: -------------------------------------------------------------------------------- 1 | actions = require '../../actions' 2 | 3 | module.exports = React.createClass 4 | displayName: 'ResetButton' 5 | 6 | _handleOnClick: (e) -> 7 | e.preventDefault() 8 | 9 | { dispatch } = @props 10 | dispatch actions.people.fetchPeople(search: '') 11 | 12 | render: -> 13 | {@props.text} 14 | -------------------------------------------------------------------------------- /app/frontend/components/paginator/paginator_link.cjsx: -------------------------------------------------------------------------------- 1 | module.exports = React.createClass 2 | displayName: 'PaginatorLink' 3 | 4 | _handleOnClick: (e) -> 5 | e.preventDefault() 6 | @props.onPaginatorLinkClick(@props.pageNumber) 7 | 8 | render: -> 9 |   10 | 11 | -------------------------------------------------------------------------------- /app/frontend/components/paginator/paginator_section.cjsx: -------------------------------------------------------------------------------- 1 | PaginatorLink = require './paginator_link' 2 | 3 | module.exports = React.createClass 4 | displayName: 'PaginatorSection' 5 | 6 | _handleOnClick: (pageNumber) -> 7 | @props.pageNumberClicked(pageNumber) 8 | 9 | _renderLinks: -> 10 | for i in [1..@props.totalPages] 11 | if i == @props.currentPage 12 |
  •  
  • 13 | else 14 |
  • 15 | 16 | render: -> 17 | if @props.totalPages > 1 18 | 21 | else 22 |
     
    23 | -------------------------------------------------------------------------------- /app/frontend/components/people/card.cjsx: -------------------------------------------------------------------------------- 1 | classnames = require 'classnames' 2 | moment = require 'moment' 3 | { Link } = require('react-router') 4 | 5 | module.exports = React.createClass 6 | displayName: 'PersonCard' 7 | 8 | _birthDate: -> 9 | moment(@props.birth_date).format('D MMM YYYY') 10 | 11 | render: -> 12 | cardClasses = classnames 13 | card: true 14 | female: @props.gender == 'female' 15 | male: @props.gender == 'male' 16 | 17 |
    18 |
    19 |
    20 |   21 | 22 | 23 | 24 |
    25 |
    26 |

    {@props.first_name} {@props.last_name}

    27 |
      28 |
    • {@props.location}
    • 29 |
    • {@_birthDate()}
    • 30 |
    31 |
    32 |
    33 |
    34 |
    35 |

    {@props.headline}

    36 |
    37 |
      38 |
    • {@props.phone_number}
    • 39 |
    • {@props.email}
    • 40 |
    41 |
    42 |
    43 | -------------------------------------------------------------------------------- /app/frontend/components/people/list.cjsx: -------------------------------------------------------------------------------- 1 | PeopleSearch = require './search' 2 | PersonCard = require './card' 3 | PaginatorSection = require '../paginator/paginator_section' 4 | NoResults = require './no_results' 5 | { connect } = require 'react-redux' 6 | actions = require '../../actions' 7 | 8 | List = React.createClass 9 | displayName: 'PeopleSection' 10 | 11 | componentDidMount: -> 12 | @_fetchPeople() 13 | 14 | _fetchPeople: (pageNumber = @props.pageNumber)-> 15 | { dispatch, search } = @props 16 | dispatch actions.people.fetchPeople({search: search, page: pageNumber}) 17 | 18 | _renderPeople: -> 19 | if @props.people.length is 0 then return 20 | 21 | @props.people.map (person) -> 22 | 23 | 24 | _handleSearchKeyup: (search) -> 25 | { dispatch } = @props. 26 | dispatch actions.people.setSearch search 27 | 28 | render: -> 29 | return false unless @props.people? 30 | 31 | { dispatch, search } = @props 32 | 33 |
    34 | 35 | 36 |
    37 | {@_renderPeople()} 38 |
    39 | 40 |
    41 | 42 | mapStateToProps = (state) -> 43 | state.people 44 | 45 | module.exports = connect(mapStateToProps)(List) 46 | 47 | -------------------------------------------------------------------------------- /app/frontend/components/people/no_results.cjsx: -------------------------------------------------------------------------------- 1 | ResetButton = require '../buttons/reset_button' 2 | 3 | module.exports = React.createClass 4 | displayName: 'NoResults' 5 | 6 | render: -> 7 | { dispatch } = @props 8 | 9 |
    10 | 11 | 12 | 13 |

    No people found...

    14 | 15 |
    16 | -------------------------------------------------------------------------------- /app/frontend/components/people/person.cjsx: -------------------------------------------------------------------------------- 1 | classnames = require 'classnames' 2 | moment = require 'moment' 3 | Link = require('react-router').Link 4 | { connect } = require 'react-redux' 5 | actions = require '../../actions' 6 | 7 | 8 | Person = React.createClass 9 | displayName: 'Person' 10 | 11 | componentDidMount: -> 12 | { dispatch, params } = @props 13 | dispatch actions.person.loadPerson params.id 14 | 15 | _birthDate: -> 16 | moment(@props.person.birth_date).format('D MMM YYYY') 17 | 18 | render: -> 19 | return false if @props.isLoading 20 | 21 | cardClasses = classnames 22 | 'person-detail': true 23 | female: @props.person.gender == 'female' 24 | male: @props.person.gender == 'male' 25 | 26 |
    27 |
    28 |

    Person detail

    29 |
    30 | ← Back to people list 31 |
    32 |
    33 | 34 |

    {@props.person.first_name} {@props.person.last_name}

    35 |
      36 |
    • {@props.person.location}
    • 37 |
    • {@_birthDate()}
    • 38 |
    39 |
    40 |
    41 |
    42 |

    {@props.person.headline}

    43 |
    44 |
      45 |
    • {@props.person.phone_number}
    • 46 |
    • {@props.person.email}
    • 47 |
    48 |
    49 |
    50 |
    51 | 52 | 53 | 54 | mapStateToProps = (state) -> 55 | person: state.person 56 | isLoading: state.person.isLoading 57 | 58 | module.exports = connect(mapStateToProps)(Person) 59 | -------------------------------------------------------------------------------- /app/frontend/components/people/search.cjsx: -------------------------------------------------------------------------------- 1 | actions = require '../../actions' 2 | ResetButton = require '../buttons/reset_button' 3 | ReactDOM = require 'react-dom' 4 | 5 | module.exports = React.createClass 6 | displayName: 'PeopleSearch' 7 | 8 | _handleOnSubmit: (e) -> 9 | e.preventDefault() 10 | { dispatch } = @props 11 | dispatch actions.people.fetchPeople(search: @refs.search.value.trim()) 12 | 13 | _handleOnChange: (e) -> 14 | @props.onSearchKeyUp @refs.search.value 15 | 16 | _personText: (count) -> 17 | if count > 1 then 'people' else 'person' 18 | 19 | _renderResetButton: -> 20 | return false unless @props.search.length != 0 21 | 22 | { dispatch } = @props 23 | 24 | 25 | render: -> 26 | count = @props.totalCount 27 | personText = @_personText(count) 28 | overviewTitle = if @props.totalCount > 0 then "#{count} #{personText} found" 29 | 30 |
    31 |
    32 |

    {overviewTitle}

    33 |   34 |
    35 |
    36 |
    37 | {@_renderResetButton()} 38 | 39 |
    40 |
    41 |
    42 | -------------------------------------------------------------------------------- /app/frontend/constants/index.coffee: -------------------------------------------------------------------------------- 1 | module.exports = 2 | REQUEST_PEOPLE: 'REQUEST_PEOPLE' 3 | RECEIVE_PEOPLE: 'RECEIVE_PEOPLE' 4 | REQUEST_PERSON: 'REQUEST_PERSON' 5 | RECEIVE_PERSON: 'RECEIVE_PERSON' 6 | SET_SEARCH: 'SET_SEARCH' 7 | -------------------------------------------------------------------------------- /app/frontend/containers/root.cjsx: -------------------------------------------------------------------------------- 1 | { Provider } = require 'react-redux' 2 | configureStore = require '../store/configure_store' 3 | { Router, RoutingContext } = require 'react-router' 4 | routes = require '../routes' 5 | 6 | module.exports = React.createClass 7 | displayName: 'Root' 8 | 9 | renderRouter: -> 10 | if @props.routingContext 11 | 12 | else 13 | 14 | {routes} 15 | 16 | 17 | render: -> 18 | ( 19 |
    20 | 21 | {@renderRouter()} 22 | 23 |
    24 | ) 25 | -------------------------------------------------------------------------------- /app/frontend/layouts/main.cjsx: -------------------------------------------------------------------------------- 1 | module.exports = React.createClass 2 | displayName: 'MainLayout' 3 | 4 | render: -> 5 |
    6 |
    7 |

    Rails and Redux: A real use case

    8 |
    9 | {@props.children} 10 |
    11 | -------------------------------------------------------------------------------- /app/frontend/reducers/index.coffee: -------------------------------------------------------------------------------- 1 | { combineReducers } = require 'redux' 2 | 3 | module.exports = combineReducers 4 | people: require './people' 5 | person: require './person' 6 | -------------------------------------------------------------------------------- /app/frontend/reducers/people.coffee: -------------------------------------------------------------------------------- 1 | constants = require '../constants' 2 | 3 | initialState = 4 | people: null 5 | meta: {} 6 | search: '' 7 | isLoading: false 8 | pageNumber: 1 9 | 10 | module.exports = (state = initialState, action) -> 11 | switch action.type 12 | when constants.REQUEST_PEOPLE 13 | Object.assign {}, state, pageNumber: action.pageNumber, search: action.search 14 | 15 | when constants.SET_SEARCH 16 | Object.assign {}, state, search: action.search 17 | 18 | when constants.RECEIVE_PEOPLE 19 | newState = 20 | people: action.people 21 | meta: action.meta 22 | isLoading: false 23 | 24 | Object.assign {}, state, newState 25 | 26 | else 27 | state 28 | -------------------------------------------------------------------------------- /app/frontend/reducers/person.coffee: -------------------------------------------------------------------------------- 1 | { REQUEST_PERSON, RECEIVE_PERSON } = require '../constants' 2 | 3 | initialState = 4 | person: {} 5 | isLoading: false 6 | 7 | module.exports = (state = initialState, action) -> 8 | switch action.type 9 | when REQUEST_PERSON 10 | Object.assign {}, state, isLoading: true 11 | 12 | when RECEIVE_PERSON 13 | Object.assign {}, state, action.person, isLoading: false 14 | 15 | else 16 | state 17 | -------------------------------------------------------------------------------- /app/frontend/routes/index.cjsx: -------------------------------------------------------------------------------- 1 | MainLayout = require '../layouts/main' 2 | { Route } = require 'react-router' 3 | PeopleList = require '../components/people/list' 4 | Person = require '../components/people/person' 5 | 6 | module.exports = 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/frontend/store/configure_store.coffee: -------------------------------------------------------------------------------- 1 | { createStore, applyMiddleware } = require 'redux' 2 | thunkMiddleware = require 'redux-thunk' 3 | loggerMiddleware = require 'redux-logger' 4 | rootReducer = require '../reducers' 5 | 6 | logger = loggerMiddleware 7 | level: 'info', 8 | collapsed: true 9 | 10 | createStoreWithMiddleware = applyMiddleware(thunkMiddleware, logger)(createStore) 11 | 12 | configureStore = (initialState) -> 13 | createStoreWithMiddleware rootReducer, initialState 14 | 15 | module.exports = configureStore 16 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigardone/rails_and_redux/66010a99f4e41bcee1737043adcbab7ad2485e6d/app/mailers/.keep -------------------------------------------------------------------------------- /app/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigardone/rails_and_redux/66010a99f4e41bcee1737043adcbab7ad2485e6d/app/models/.keep -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigardone/rails_and_redux/66010a99f4e41bcee1737043adcbab7ad2485e6d/app/models/concerns/.keep -------------------------------------------------------------------------------- /app/models/person.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: people 4 | # 5 | # id :integer not null, primary key 6 | # first_name :string not null 7 | # last_name :string 8 | # gender :integer default("0") 9 | # birth_date :date 10 | # location :string 11 | # phone_number :string 12 | # email :string 13 | # headline :text 14 | # created_at :datetime not null 15 | # updated_at :datetime not null 16 | # picture :string 17 | # 18 | 19 | class Person < ActiveRecord::Base 20 | include PgSearch 21 | 22 | enum gender: [:male, :female] 23 | 24 | scope :sorted, ->{ order(first_name: :asc) } 25 | pg_search_scope :search, 26 | against: [ 27 | :first_name, 28 | :last_name, 29 | :location, 30 | :headline 31 | ], 32 | using: { 33 | tsearch: { 34 | prefix: true, 35 | normalization: 2 36 | } 37 | } 38 | end 39 | -------------------------------------------------------------------------------- /app/serializers/person_serializer.rb: -------------------------------------------------------------------------------- 1 | class PersonSerializer < ActiveModel::Serializer 2 | attributes :id, 3 | :first_name, 4 | :last_name, 5 | :full_name, 6 | :gender, 7 | :birth_date, 8 | :location, 9 | :phone_number, 10 | :email, 11 | :headline, 12 | :picture 13 | 14 | def full_name 15 | [object.first_name, object.last_name].join(' ') 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/views/home/index.html.haml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html 3 | %head 4 | %title Rails and Redux: A real use case 5 | = include_gon 6 | %link{href: "https://fonts.googleapis.com/css?family=Fjalla+One|Average+Sans", rel: "stylesheet", type: "text/css"}/ 7 | = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true 8 | = javascript_include_tag 'application', 'data-turbolinks-track' => true 9 | = csrf_meta_tags 10 | %body 11 | #main_wrapper 12 | = yield 13 | %footer#main_footer 14 | %small 15 | Crafted with ♥ by 16 | %a{href: "http://codeloveandboards.com", target:"_blank"} bigardone 17 | %br/ 18 | Check out the 19 | %a{href: "https://github.com/bigardone/rails_and_redux", target: '_blank'} source code 20 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path("../spring", __FILE__) 4 | rescue LoadError 5 | end 6 | APP_PATH = File.expand_path('../../config/application', __FILE__) 7 | require_relative '../config/boot' 8 | require 'rails/commands' 9 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path("../spring", __FILE__) 4 | rescue LoadError 5 | end 6 | require_relative '../config/boot' 7 | require 'rake' 8 | Rake.application.run 9 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | 4 | # path to your application root. 5 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 6 | 7 | Dir.chdir APP_ROOT do 8 | # This script is a starting point to setup your application. 9 | # Add necessary setup steps to this file: 10 | 11 | puts "== Installing dependencies ==" 12 | system "gem install bundler --conservative" 13 | system "bundle check || bundle install" 14 | 15 | # puts "\n== Copying sample files ==" 16 | # unless File.exist?("config/database.yml") 17 | # system "cp config/database.yml.sample config/database.yml" 18 | # end 19 | 20 | puts "\n== Preparing database ==" 21 | system "bin/rake db:setup" 22 | 23 | puts "\n== Removing old logs and tempfiles ==" 24 | system "rm -f log/*" 25 | system "rm -rf tmp/cache" 26 | 27 | puts "\n== Restarting application server ==" 28 | system "touch tmp/restart.txt" 29 | end 30 | -------------------------------------------------------------------------------- /bin/spring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # This file loads spring without using Bundler, in order to be fast 4 | # It gets overwritten when you run the `spring binstub` command 5 | 6 | unless defined?(Spring) 7 | require "rubygems" 8 | require "bundler" 9 | 10 | if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ spring \((.*?)\)$.*?^$/m) 11 | ENV["GEM_PATH"] = ([Bundler.bundle_path.to_s] + Gem.path).join(File::PATH_SEPARATOR) 12 | ENV["GEM_HOME"] = "" 13 | Gem.paths = ENV 14 | 15 | gem "spring", match[1] 16 | require "spring/binstub" 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails.application 5 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | # Pick the frameworks you want: 4 | require "active_model/railtie" 5 | require "active_record/railtie" 6 | require "action_controller/railtie" 7 | require "action_mailer/railtie" 8 | require "action_view/railtie" 9 | require "sprockets/railtie" 10 | # require "rails/test_unit/railtie" 11 | 12 | # Require the gems listed in Gemfile, including any gems 13 | # you've limited to :test, :development, or :production. 14 | Bundler.require(*Rails.groups) 15 | 16 | module RailsAndRedux 17 | class Application < Rails::Application 18 | # Settings in config/environments/* take precedence over those specified here. 19 | # Application configuration should go into files in config/initializers 20 | # -- all .rb files in that directory are automatically loaded. 21 | 22 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 23 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 24 | # config.time_zone = 'Central Time (US & Canada)' 25 | 26 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 27 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 28 | # config.i18n.default_locale = :de 29 | 30 | # For not swallow errors in after_commit/after_rollback callbacks. 31 | config.active_record.raise_in_transactional_callbacks = true 32 | 33 | # sass over scss 34 | config.sass.preferred_syntax = :sass 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | default: &default 2 | adapter: postgresql 3 | host: localhost 4 | 5 | development: 6 | <<: *default 7 | database: rails_and_redux_development 8 | 9 | test: 10 | <<: *default 11 | database: rails_and_redux_test 12 | 13 | production: 14 | <<: *default 15 | database: rails_and_redux_production 16 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports and disable caching. 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send. 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger. 20 | config.active_support.deprecation = :log 21 | 22 | # Raise an error on page load if there are pending migrations. 23 | config.active_record.migration_error = :page_load 24 | 25 | # Debug mode disables concatenation and preprocessing of assets. 26 | # This option may cause significant delays in view rendering with a large 27 | # number of complex assets. 28 | config.assets.debug = true 29 | 30 | # Asset digests allow you to set far-future HTTP expiration dates on all assets, 31 | # yet still be able to expire them through the digest params. 32 | config.assets.digest = true 33 | 34 | # Adds additional error checking when serving assets at runtime. 35 | # Checks for improperly declared sprockets dependencies. 36 | # Raises helpful error messages. 37 | config.assets.raise_runtime_errors = true 38 | 39 | # Raises error for missing translations 40 | # config.action_view.raise_on_missing_translations = true 41 | end 42 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # Code is not reloaded between requests. 5 | config.cache_classes = true 6 | 7 | # Eager load code on boot. This eager loads most of Rails and 8 | # your application in memory, allowing both threaded web servers 9 | # and those relying on copy on write to perform better. 10 | # Rake tasks automatically ignore this option for performance. 11 | config.eager_load = true 12 | 13 | # Full error reports are disabled and caching is turned on. 14 | config.consider_all_requests_local = false 15 | config.action_controller.perform_caching = true 16 | 17 | # Enable Rack::Cache to put a simple HTTP cache in front of your application 18 | # Add `rack-cache` to your Gemfile before enabling this. 19 | # For large-scale production use, consider using a caching reverse proxy like NGINX, varnish or squid. 20 | # config.action_dispatch.rack_cache = true 21 | 22 | # Disable Rails's static asset server (Apache or NGINX will already do this). 23 | config.serve_static_assets = false 24 | 25 | # Compress JavaScripts and CSS. 26 | config.assets.js_compressor = :uglifier 27 | # config.assets.css_compressor = :sass 28 | 29 | # Do not fallback to assets pipeline if a precompiled asset is missed. 30 | config.assets.compile = false 31 | 32 | # Asset digests allow you to set far-future HTTP expiration dates on all assets, 33 | # yet still be able to expire them through the digest params. 34 | config.assets.digest = true 35 | 36 | # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb 37 | 38 | # Specifies the header that your server uses for sending files. 39 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache 40 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX 41 | 42 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 43 | # config.force_ssl = true 44 | 45 | # Set to :info to decrease the log volume. 46 | config.log_level = :debug 47 | 48 | # Prepend all log lines with the following tags. 49 | # config.log_tags = [ :subdomain, :uuid ] 50 | 51 | # Use a different logger for distributed setups. 52 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 53 | 54 | # Use a different cache store in production. 55 | # config.cache_store = :mem_cache_store 56 | 57 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 58 | # config.action_controller.asset_host = "http://assets.example.com" 59 | 60 | # Ignore bad email addresses and do not raise email delivery errors. 61 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 62 | # config.action_mailer.raise_delivery_errors = false 63 | 64 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 65 | # the I18n.default_locale when a translation cannot be found). 66 | config.i18n.fallbacks = true 67 | 68 | # Send deprecation notices to registered listeners. 69 | config.active_support.deprecation = :notify 70 | 71 | # Use default logging formatter so that PID and timestamp are not suppressed. 72 | config.log_formatter = ::Logger::Formatter.new 73 | 74 | # Do not dump schema after migrations. 75 | config.active_record.dump_schema_after_migration = false 76 | end 77 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure static asset server for tests with Cache-Control for performance. 16 | config.serve_static_assets = true 17 | config.static_cache_control = 'public, max-age=3600' 18 | 19 | # Show full error reports and disable caching. 20 | config.consider_all_requests_local = true 21 | config.action_controller.perform_caching = false 22 | 23 | # Raise exceptions instead of rendering exception templates. 24 | config.action_dispatch.show_exceptions = false 25 | 26 | # Disable request forgery protection in test environment. 27 | config.action_controller.allow_forgery_protection = false 28 | 29 | # Tell Action Mailer not to deliver emails to the real world. 30 | # The :test delivery method accumulates sent emails in the 31 | # ActionMailer::Base.deliveries array. 32 | config.action_mailer.delivery_method = :test 33 | 34 | # Print deprecation notices to the stderr. 35 | config.active_support.deprecation = :stderr 36 | 37 | # Raises error for missing translations 38 | # config.action_view.raise_on_missing_translations = true 39 | end 40 | -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Add additional assets to the asset load path 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 11 | # Rails.application.config.assets.precompile += %w( search.js ) 12 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.action_dispatch.cookies_serializer = :json 4 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /config/initializers/kaminari_config.rb: -------------------------------------------------------------------------------- 1 | Kaminari.configure do |config| 2 | config.default_per_page = 9 3 | # config.max_per_page = nil 4 | # config.window = 4 5 | # config.outer_window = 0 6 | # config.left = 0 7 | # config.right = 0 8 | # config.page_method_name = :page 9 | # config.param_name = :page 10 | end 11 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.session_store :cookie_store, key: '_rails_and_redux_session' 4 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters) 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /config/newrelic.yml: -------------------------------------------------------------------------------- 1 | # 2 | # This file configures the New Relic Agent. New Relic monitors Ruby, Java, 3 | # .NET, PHP, Python and Node applications with deep visibility and low 4 | # overhead. For more information, visit www.newrelic.com. 5 | # 6 | # Generated September 06, 2014 7 | # 8 | # This configuration file is custom generated for bigardone 9 | 10 | 11 | # Here are the settings that are common to all environments 12 | common: &default_settings 13 | # ============================== LICENSE KEY =============================== 14 | 15 | # You must specify the license key associated with your New Relic 16 | # account. This key binds your Agent's data to your account in the 17 | # New Relic service. 18 | license_key: '<%= ENV["NEW_RELIC_LICENSE_KEY"] %>' 19 | 20 | # Agent Enabled (Ruby/Rails Only) 21 | # Use this setting to force the agent to run or not run. 22 | # Default is 'auto' which means the agent will install and run only 23 | # if a valid dispatcher such as Mongrel is running. This prevents 24 | # it from running with Rake or the console. Set to false to 25 | # completely turn the agent off regardless of the other settings. 26 | # Valid values are true, false and auto. 27 | # 28 | # agent_enabled: auto 29 | 30 | # Application Name Set this to be the name of your application as 31 | # you'd like it show up in New Relic. The service will then auto-map 32 | # instances of your application into an "application" on your 33 | # dashboard page. If you want to map this instance into multiple 34 | # apps, like "AJAX Requests" and "All UI" then specify a semicolon 35 | # separated list of up to three distinct names, or a yaml list. 36 | # Defaults to the capitalized RAILS_ENV or RACK_ENV (i.e., 37 | # Production, Staging, etc) 38 | # 39 | # Example: 40 | # 41 | # app_name: 42 | # - Ajax Service 43 | # - All Services 44 | # 45 | # Caution: If you change this name, a new application will appear in the New 46 | # Relic user interface with the new name, and data will stop reporting to the 47 | # app with the old name. 48 | # 49 | # See https://newrelic.com/docs/site/renaming-applications for more details 50 | # on renaming your New Relic applications. 51 | # 52 | app_name: Rails and Flux 53 | 54 | # When "true", the agent collects performance data about your 55 | # application and reports this data to the New Relic service at 56 | # newrelic.com. This global switch is normally overridden for each 57 | # environment below. (formerly called 'enabled') 58 | monitor_mode: true 59 | 60 | # Developer mode should be off in every environment but 61 | # development as it has very high overhead in memory. 62 | developer_mode: false 63 | 64 | # The newrelic agent generates its own log file to keep its logging 65 | # information separate from that of your application. Specify its 66 | # log level here. 67 | log_level: info 68 | 69 | # Optionally set the path to the log file This is expanded from the 70 | # root directory (may be relative or absolute, e.g. 'log/' or 71 | # '/var/log/') The agent will attempt to create this directory if it 72 | # does not exist. 73 | # log_file_path: 'log' 74 | 75 | # Optionally set the name of the log file, defaults to 'newrelic_agent.log' 76 | # log_file_name: 'newrelic_agent.log' 77 | 78 | # The newrelic agent communicates with the service via https by default. This 79 | # prevents eavesdropping on the performance metrics transmitted by the agent. 80 | # The encryption required by SSL introduces a nominal amount of CPU overhead, 81 | # which is performed asynchronously in a background thread. If you'd prefer 82 | # to send your metrics over http uncomment the following line. 83 | # ssl: false 84 | 85 | #============================== Browser Monitoring =============================== 86 | # New Relic Real User Monitoring gives you insight into the performance real users are 87 | # experiencing with your website. This is accomplished by measuring the time it takes for 88 | # your users' browsers to download and render your web pages by injecting a small amount 89 | # of JavaScript code into the header and footer of each page. 90 | browser_monitoring: 91 | # By default the agent automatically injects the monitoring JavaScript 92 | # into web pages. Set this attribute to false to turn off this behavior. 93 | auto_instrument: true 94 | 95 | # Proxy settings for connecting to the New Relic server. 96 | # 97 | # If a proxy is used, the host setting is required. Other settings 98 | # are optional. Default port is 8080. 99 | # 100 | # proxy_host: hostname 101 | # proxy_port: 8080 102 | # proxy_user: 103 | # proxy_pass: 104 | 105 | # The agent can optionally log all data it sends to New Relic servers to a 106 | # separate log file for human inspection and auditing purposes. To enable this 107 | # feature, change 'enabled' below to true. 108 | # See: https://newrelic.com/docs/ruby/audit-log 109 | audit_log: 110 | enabled: false 111 | 112 | # Tells transaction tracer and error collector (when enabled) 113 | # whether or not to capture HTTP params. When true, frameworks can 114 | # exclude HTTP parameters from being captured. 115 | # Rails: the RoR filter_parameter_logging excludes parameters 116 | # Java: create a config setting called "ignored_params" and set it to 117 | # a comma separated list of HTTP parameter names. 118 | # ex: ignored_params: credit_card, ssn, password 119 | capture_params: false 120 | 121 | # Transaction tracer captures deep information about slow 122 | # transactions and sends this to the New Relic service once a 123 | # minute. Included in the transaction is the exact call sequence of 124 | # the transactions including any SQL statements issued. 125 | transaction_tracer: 126 | 127 | # Transaction tracer is enabled by default. Set this to false to 128 | # turn it off. This feature is only available at the Professional 129 | # and above product levels. 130 | enabled: true 131 | 132 | # Threshold in seconds for when to collect a transaction 133 | # trace. When the response time of a controller action exceeds 134 | # this threshold, a transaction trace will be recorded and sent to 135 | # New Relic. Valid values are any float value, or (default) "apdex_f", 136 | # which will use the threshold for an dissatisfying Apdex 137 | # controller action - four times the Apdex T value. 138 | transaction_threshold: apdex_f 139 | 140 | # When transaction tracer is on, SQL statements can optionally be 141 | # recorded. The recorder has three modes, "off" which sends no 142 | # SQL, "raw" which sends the SQL statement in its original form, 143 | # and "obfuscated", which strips out numeric and string literals. 144 | record_sql: obfuscated 145 | 146 | # Threshold in seconds for when to collect stack trace for a SQL 147 | # call. In other words, when SQL statements exceed this threshold, 148 | # then capture and send to New Relic the current stack trace. This is 149 | # helpful for pinpointing where long SQL calls originate from. 150 | stack_trace_threshold: 0.500 151 | 152 | # Determines whether the agent will capture query plans for slow 153 | # SQL queries. Only supported in mysql and postgres. Should be 154 | # set to false when using other adapters. 155 | # explain_enabled: true 156 | 157 | # Threshold for query execution time below which query plans will 158 | # not be captured. Relevant only when `explain_enabled` is true. 159 | # explain_threshold: 0.5 160 | 161 | # Error collector captures information about uncaught exceptions and 162 | # sends them to New Relic for viewing 163 | error_collector: 164 | 165 | # Error collector is enabled by default. Set this to false to turn 166 | # it off. This feature is only available at the Professional and above 167 | # product levels. 168 | enabled: true 169 | 170 | # To stop specific errors from reporting to New Relic, set this property 171 | # to comma-separated values. Default is to ignore routing errors, 172 | # which are how 404's get triggered. 173 | ignore_errors: "ActionController::RoutingError,Sinatra::NotFound" 174 | 175 | # If you're interested in capturing memcache keys as though they 176 | # were SQL uncomment this flag. Note that this does increase 177 | # overhead slightly on every memcached call, and can have security 178 | # implications if your memcached keys are sensitive 179 | # capture_memcache_keys: true 180 | 181 | # Application Environments 182 | # ------------------------------------------ 183 | # Environment-specific settings are in this section. 184 | # For Rails applications, RAILS_ENV is used to determine the environment. 185 | # For Java applications, pass -Dnewrelic.environment to set 186 | # the environment. 187 | 188 | # NOTE if your application has other named environments, you should 189 | # provide newrelic configuration settings for these environments here. 190 | 191 | development: 192 | <<: *default_settings 193 | # Turn on communication to New Relic service in development mode 194 | monitor_mode: true 195 | app_name: Rails and Flux (Development) 196 | 197 | # Rails Only - when running in Developer Mode, the New Relic Agent will 198 | # present performance information on the last 100 transactions you have 199 | # executed since starting the mongrel. 200 | # NOTE: There is substantial overhead when running in developer mode. 201 | # Do not use for production or load testing. 202 | developer_mode: true 203 | 204 | test: 205 | <<: *default_settings 206 | # It almost never makes sense to turn on the agent when running 207 | # unit, functional or integration tests or the like. 208 | monitor_mode: false 209 | 210 | # Turn on the agent in production for 24x7 monitoring. NewRelic 211 | # testing shows an average performance impact of < 5 ms per 212 | # transaction, you can leave this on all the time without 213 | # incurring any user-visible performance degradation. 214 | production: 215 | <<: *default_settings 216 | monitor_mode: true 217 | 218 | # Many applications have a staging environment which behaves 219 | # identically to production. Support for that environment is provided 220 | # here. By default, the staging environment has the agent turned on. 221 | staging: 222 | <<: *default_settings 223 | monitor_mode: true 224 | app_name: Rails and Flux (Staging) 225 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | root 'home#index' 3 | 4 | 5 | namespace :api do 6 | namespace :v1 do 7 | resources :people, only: [:index, :show] 8 | end 9 | end 10 | 11 | get '*path', to: 'home#index' 12 | 13 | # The priority is based upon order of creation: first created -> highest priority. 14 | # See how all your routes lay out with "rake routes". 15 | 16 | # You can have the root of your site routed with "root" 17 | # root 'welcome#index' 18 | 19 | # Example of regular route: 20 | # get 'products/:id' => 'catalog#view' 21 | 22 | # Example of named route that can be invoked with purchase_url(id: product.id) 23 | # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase 24 | 25 | # Example resource route (maps HTTP verbs to controller actions automatically): 26 | # resources :products 27 | 28 | # Example resource route with options: 29 | # resources :products do 30 | # member do 31 | # get 'short' 32 | # post 'toggle' 33 | # end 34 | # 35 | # collection do 36 | # get 'sold' 37 | # end 38 | # end 39 | 40 | # Example resource route with sub-resources: 41 | # resources :products do 42 | # resources :comments, :sales 43 | # resource :seller 44 | # end 45 | 46 | # Example resource route with more complex sub-resources: 47 | # resources :products do 48 | # resources :comments 49 | # resources :sales do 50 | # get 'recent', on: :collection 51 | # end 52 | # end 53 | 54 | # Example resource route with concerns: 55 | # concern :toggleable do 56 | # post 'toggle' 57 | # end 58 | # resources :posts, concerns: :toggleable 59 | # resources :photos, concerns: :toggleable 60 | 61 | # Example resource route within a namespace: 62 | # namespace :admin do 63 | # # Directs /admin/products/* to Admin::ProductsController 64 | # # (app/controllers/admin/products_controller.rb) 65 | # resources :products 66 | # end 67 | end 68 | -------------------------------------------------------------------------------- /config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | development: 14 | secret_key_base: 3cef6a599347dc5162dff9946ff99160aff00d14033244f9dd80848b2b5a9a395c3e0ea989203519af9e7eb79f0e86c6e2d0f0d8a6a1ddb52b4ae42a1e1cd391 15 | google_analytics_id: foo 16 | 17 | test: 18 | secret_key_base: 91e0134c84aa381b0d80b154ad1604cd43d84edce05ce1c9bb9bc4e5c387e58a59491acd724e7fed412c13f5191ea6566ffdf77806a3a4258f403b6f59fc878c 19 | google_analytics_id: foo 20 | 21 | # Do not keep production secrets in the repository, 22 | # instead read values from the environment. 23 | production: 24 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 25 | google_analytics_id: <%= ENV["GOOGLE_ANALYTICS_ID"] %> 26 | -------------------------------------------------------------------------------- /db/migrate/20140905152314_create_people.rb: -------------------------------------------------------------------------------- 1 | class CreatePeople < ActiveRecord::Migration 2 | def change 3 | create_table :people do |t| 4 | t.string :first_name, null: false 5 | t.string :last_name 6 | t.integer :gender, default: 0 7 | t.date :birth_date 8 | t.string :location 9 | t.string :phone_number 10 | t.string :email 11 | t.text :headline 12 | 13 | t.timestamps null: false 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /db/migrate/20140905154625_add_picture_to_people.rb: -------------------------------------------------------------------------------- 1 | class AddPictureToPeople < ActiveRecord::Migration 2 | def change 3 | add_column :people, :picture, :string, after: :headline 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 20140905154625) do 15 | 16 | # These are extensions that must be enabled in order to support this database 17 | enable_extension "plpgsql" 18 | 19 | create_table "people", force: true do |t| 20 | t.string "first_name", null: false 21 | t.string "last_name" 22 | t.integer "gender", default: 0 23 | t.date "birth_date" 24 | t.string "location" 25 | t.string "phone_number" 26 | t.string "email" 27 | t.text "headline" 28 | t.datetime "created_at", null: false 29 | t.datetime "updated_at", null: false 30 | t.string "picture" 31 | end 32 | 33 | end 34 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | 50.times do |i| 2 | Person.create do |person| 3 | first_name = Faker::Name.first_name 4 | gender = Person.genders.values.sample 5 | picture_gender = gender == Person.genders[:male] ? 'men' : 'women' 6 | 7 | person.first_name = first_name 8 | person.last_name = Faker::Name.last_name 9 | person.gender = gender 10 | person.birth_date = (20..40).to_a.sample.years.ago 11 | person.location = Faker::Address.country 12 | person.email = Faker::Internet.email(first_name) 13 | person.phone_number = Faker::PhoneNumber.cell_phone 14 | person.headline = Faker::Lorem.sentence(3, true) 15 | person.picture = "http://api.randomuser.me/portraits/#{picture_gender}/#{i}.jpg" 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigardone/rails_and_redux/66010a99f4e41bcee1737043adcbab7ad2485e6d/lib/assets/.keep -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigardone/rails_and_redux/66010a99f4e41bcee1737043adcbab7ad2485e6d/lib/tasks/.keep -------------------------------------------------------------------------------- /lib/tasks/auto_annotate_models.rake: -------------------------------------------------------------------------------- 1 | # NOTE: only doing this in development as some production environments (Heroku) 2 | # NOTE: are sensitive to local FS writes, and besides -- it's just not proper 3 | # NOTE: to have a dev-mode tool do its thing in production. 4 | if Rails.env.development? 5 | task :set_annotation_options do 6 | # You can override any of these by setting an environment variable of the 7 | # same name. 8 | Annotate.set_defaults({ 9 | 'position_in_routes' => "before", 10 | 'position_in_class' => "before", 11 | 'position_in_test' => "before", 12 | 'position_in_fixture' => "before", 13 | 'position_in_factory' => "before", 14 | 'show_indexes' => "true", 15 | 'simple_indexes' => "false", 16 | 'model_dir' => "app/models", 17 | 'include_version' => "false", 18 | 'require' => "", 19 | 'exclude_tests' => "false", 20 | 'exclude_fixtures' => "false", 21 | 'exclude_factories' => "false", 22 | 'ignore_model_sub_dir' => "false", 23 | 'skip_on_db_migrate' => "false", 24 | 'format_bare' => "true", 25 | 'format_rdoc' => "false", 26 | 'format_markdown' => "false", 27 | 'sort' => "false", 28 | 'force' => "false", 29 | 'trace' => "false", 30 | }) 31 | end 32 | 33 | Annotate.load_tasks 34 | end 35 | -------------------------------------------------------------------------------- /log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigardone/rails_and_redux/66010a99f4e41bcee1737043adcbab7ad2485e6d/log/.keep -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rails_and_redux", 3 | "scripts": { 4 | "start": "./node_modules/.bin/webpack --progress --colors --watch" 5 | }, 6 | "devDependencies": { 7 | "webpack": "~1.7.3", 8 | "jsx-loader": "~0.12.2", 9 | "cjsx-loader": "~2.0.1", 10 | "coffee-loader": "^0.7.2", 11 | "babel-loader": "^4.2.0" 12 | }, 13 | "dependencies": { 14 | "classnames": "1.2.0", 15 | "history": "^1.9.1", 16 | "isomorphic-fetch": "^2.1.1", 17 | "lodash": "^3.10.1", 18 | "moment": "^2.10.3", 19 | "react": "^0.14.0", 20 | "react-dom": "^0.14.0", 21 | "react-redux": "^2.1.1", 22 | "react-router": "1.0.0-rc1", 23 | "redux-logger": "^1.0.6", 24 | "redux-thunk": "^0.1.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
    60 |
    61 |

    The page you were looking for doesn't exist.

    62 |

    You may have mistyped the address or the page may have moved.

    63 |
    64 |

    If you are the application owner check the logs for more information.

    65 |
    66 | 67 | 68 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
    60 |
    61 |

    The change you wanted was rejected.

    62 |

    Maybe you tried to change something you didn't have access to.

    63 |
    64 |

    If you are the application owner check the logs for more information.

    65 |
    66 | 67 | 68 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
    60 |
    61 |

    We're sorry, but something went wrong.

    62 |
    63 |

    If you are the application owner check the logs for more information.

    64 |
    65 | 66 | 67 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigardone/rails_and_redux/66010a99f4e41bcee1737043adcbab7ad2485e6d/public/favicon.ico -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigardone/rails_and_redux/66010a99f4e41bcee1737043adcbab7ad2485e6d/vendor/assets/javascripts/.keep -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigardone/rails_and_redux/66010a99f4e41bcee1737043adcbab7ad2485e6d/vendor/assets/stylesheets/.keep -------------------------------------------------------------------------------- /vendor/assets/stylesheets/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.1 | MIT License | git.io/normalize */ 2 | 3 | /** 4 | * 1. Set default font family to sans-serif. 5 | * 2. Prevent iOS text size adjust after orientation change, without disabling 6 | * user zoom. 7 | */ 8 | 9 | html { 10 | font-family: sans-serif; /* 1 */ 11 | -ms-text-size-adjust: 100%; /* 2 */ 12 | -webkit-text-size-adjust: 100%; /* 2 */ 13 | } 14 | 15 | /** 16 | * Remove default margin. 17 | */ 18 | 19 | body { 20 | margin: 0; 21 | } 22 | 23 | /* HTML5 display definitions 24 | ========================================================================== */ 25 | 26 | /** 27 | * Correct `block` display not defined for any HTML5 element in IE 8/9. 28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11 and Firefox. 29 | * Correct `block` display not defined for `main` in IE 11. 30 | */ 31 | 32 | article, 33 | aside, 34 | details, 35 | figcaption, 36 | figure, 37 | footer, 38 | header, 39 | hgroup, 40 | main, 41 | nav, 42 | section, 43 | summary { 44 | display: block; 45 | } 46 | 47 | /** 48 | * 1. Correct `inline-block` display not defined in IE 8/9. 49 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. 50 | */ 51 | 52 | audio, 53 | canvas, 54 | progress, 55 | video { 56 | display: inline-block; /* 1 */ 57 | vertical-align: baseline; /* 2 */ 58 | } 59 | 60 | /** 61 | * Prevent modern browsers from displaying `audio` without controls. 62 | * Remove excess height in iOS 5 devices. 63 | */ 64 | 65 | audio:not([controls]) { 66 | display: none; 67 | height: 0; 68 | } 69 | 70 | /** 71 | * Address `[hidden]` styling not present in IE 8/9/10. 72 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. 73 | */ 74 | 75 | [hidden], 76 | template { 77 | display: none; 78 | } 79 | 80 | /* Links 81 | ========================================================================== */ 82 | 83 | /** 84 | * Remove the gray background color from active links in IE 10. 85 | */ 86 | 87 | a { 88 | background: transparent; 89 | } 90 | 91 | /** 92 | * Improve readability when focused and also mouse hovered in all browsers. 93 | */ 94 | 95 | a:active, 96 | a:hover { 97 | outline: 0; 98 | } 99 | 100 | /* Text-level semantics 101 | ========================================================================== */ 102 | 103 | /** 104 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome. 105 | */ 106 | 107 | abbr[title] { 108 | border-bottom: 1px dotted; 109 | } 110 | 111 | /** 112 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. 113 | */ 114 | 115 | b, 116 | strong { 117 | font-weight: bold; 118 | } 119 | 120 | /** 121 | * Address styling not present in Safari and Chrome. 122 | */ 123 | 124 | dfn { 125 | font-style: italic; 126 | } 127 | 128 | /** 129 | * Address variable `h1` font-size and margin within `section` and `article` 130 | * contexts in Firefox 4+, Safari, and Chrome. 131 | */ 132 | 133 | h1 { 134 | font-size: 2em; 135 | margin: 0.67em 0; 136 | } 137 | 138 | /** 139 | * Address styling not present in IE 8/9. 140 | */ 141 | 142 | mark { 143 | background: #ff0; 144 | color: #000; 145 | } 146 | 147 | /** 148 | * Address inconsistent and variable font size in all browsers. 149 | */ 150 | 151 | small { 152 | font-size: 80%; 153 | } 154 | 155 | /** 156 | * Prevent `sub` and `sup` affecting `line-height` in all browsers. 157 | */ 158 | 159 | sub, 160 | sup { 161 | font-size: 75%; 162 | line-height: 0; 163 | position: relative; 164 | vertical-align: baseline; 165 | } 166 | 167 | sup { 168 | top: -0.5em; 169 | } 170 | 171 | sub { 172 | bottom: -0.25em; 173 | } 174 | 175 | /* Embedded content 176 | ========================================================================== */ 177 | 178 | /** 179 | * Remove border when inside `a` element in IE 8/9/10. 180 | */ 181 | 182 | img { 183 | border: 0; 184 | } 185 | 186 | /** 187 | * Correct overflow not hidden in IE 9/10/11. 188 | */ 189 | 190 | svg:not(:root) { 191 | overflow: hidden; 192 | } 193 | 194 | /* Grouping content 195 | ========================================================================== */ 196 | 197 | /** 198 | * Address margin not present in IE 8/9 and Safari. 199 | */ 200 | 201 | figure { 202 | margin: 1em 40px; 203 | } 204 | 205 | /** 206 | * Address differences between Firefox and other browsers. 207 | */ 208 | 209 | hr { 210 | -moz-box-sizing: content-box; 211 | box-sizing: content-box; 212 | height: 0; 213 | } 214 | 215 | /** 216 | * Contain overflow in all browsers. 217 | */ 218 | 219 | pre { 220 | overflow: auto; 221 | } 222 | 223 | /** 224 | * Address odd `em`-unit font size rendering in all browsers. 225 | */ 226 | 227 | code, 228 | kbd, 229 | pre, 230 | samp { 231 | font-family: monospace, monospace; 232 | font-size: 1em; 233 | } 234 | 235 | /* Forms 236 | ========================================================================== */ 237 | 238 | /** 239 | * Known limitation: by default, Chrome and Safari on OS X allow very limited 240 | * styling of `select`, unless a `border` property is set. 241 | */ 242 | 243 | /** 244 | * 1. Correct color not being inherited. 245 | * Known issue: affects color of disabled elements. 246 | * 2. Correct font properties not being inherited. 247 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. 248 | */ 249 | 250 | button, 251 | input, 252 | optgroup, 253 | select, 254 | textarea { 255 | color: inherit; /* 1 */ 256 | font: inherit; /* 2 */ 257 | margin: 0; /* 3 */ 258 | } 259 | 260 | /** 261 | * Address `overflow` set to `hidden` in IE 8/9/10/11. 262 | */ 263 | 264 | button { 265 | overflow: visible; 266 | } 267 | 268 | /** 269 | * Address inconsistent `text-transform` inheritance for `button` and `select`. 270 | * All other form control elements do not inherit `text-transform` values. 271 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. 272 | * Correct `select` style inheritance in Firefox. 273 | */ 274 | 275 | button, 276 | select { 277 | text-transform: none; 278 | } 279 | 280 | /** 281 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 282 | * and `video` controls. 283 | * 2. Correct inability to style clickable `input` types in iOS. 284 | * 3. Improve usability and consistency of cursor style between image-type 285 | * `input` and others. 286 | */ 287 | 288 | button, 289 | html input[type="button"], /* 1 */ 290 | input[type="reset"], 291 | input[type="submit"] { 292 | -webkit-appearance: button; /* 2 */ 293 | cursor: pointer; /* 3 */ 294 | } 295 | 296 | /** 297 | * Re-set default cursor for disabled elements. 298 | */ 299 | 300 | button[disabled], 301 | html input[disabled] { 302 | cursor: default; 303 | } 304 | 305 | /** 306 | * Remove inner padding and border in Firefox 4+. 307 | */ 308 | 309 | button::-moz-focus-inner, 310 | input::-moz-focus-inner { 311 | border: 0; 312 | padding: 0; 313 | } 314 | 315 | /** 316 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in 317 | * the UA stylesheet. 318 | */ 319 | 320 | input { 321 | line-height: normal; 322 | } 323 | 324 | /** 325 | * It's recommended that you don't attempt to style these elements. 326 | * Firefox's implementation doesn't respect box-sizing, padding, or width. 327 | * 328 | * 1. Address box sizing set to `content-box` in IE 8/9/10. 329 | * 2. Remove excess padding in IE 8/9/10. 330 | */ 331 | 332 | input[type="checkbox"], 333 | input[type="radio"] { 334 | box-sizing: border-box; /* 1 */ 335 | padding: 0; /* 2 */ 336 | } 337 | 338 | /** 339 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain 340 | * `font-size` values of the `input`, it causes the cursor style of the 341 | * decrement button to change from `default` to `text`. 342 | */ 343 | 344 | input[type="number"]::-webkit-inner-spin-button, 345 | input[type="number"]::-webkit-outer-spin-button { 346 | height: auto; 347 | } 348 | 349 | /** 350 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome. 351 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome 352 | * (include `-moz` to future-proof). 353 | */ 354 | 355 | input[type="search"] { 356 | -webkit-appearance: textfield; /* 1 */ 357 | -moz-box-sizing: content-box; 358 | -webkit-box-sizing: content-box; /* 2 */ 359 | box-sizing: content-box; 360 | } 361 | 362 | /** 363 | * Remove inner padding and search cancel button in Safari and Chrome on OS X. 364 | * Safari (but not Chrome) clips the cancel button when the search input has 365 | * padding (and `textfield` appearance). 366 | */ 367 | 368 | input[type="search"]::-webkit-search-cancel-button, 369 | input[type="search"]::-webkit-search-decoration { 370 | -webkit-appearance: none; 371 | } 372 | 373 | /** 374 | * Define consistent border, margin, and padding. 375 | */ 376 | 377 | fieldset { 378 | border: 1px solid #c0c0c0; 379 | margin: 0 2px; 380 | padding: 0.35em 0.625em 0.75em; 381 | } 382 | 383 | /** 384 | * 1. Correct `color` not being inherited in IE 8/9/10/11. 385 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 386 | */ 387 | 388 | legend { 389 | border: 0; /* 1 */ 390 | padding: 0; /* 2 */ 391 | } 392 | 393 | /** 394 | * Remove default vertical scrollbar in IE 8/9/10/11. 395 | */ 396 | 397 | textarea { 398 | overflow: auto; 399 | } 400 | 401 | /** 402 | * Don't inherit the `font-weight` (applied by a rule above). 403 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. 404 | */ 405 | 406 | optgroup { 407 | font-weight: bold; 408 | } 409 | 410 | /* Tables 411 | ========================================================================== */ 412 | 413 | /** 414 | * Remove most spacing between table cells. 415 | */ 416 | 417 | table { 418 | border-collapse: collapse; 419 | border-spacing: 0; 420 | } 421 | 422 | td, 423 | th { 424 | padding: 0; 425 | } 426 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require("path"); 2 | var webpack = require('webpack'); 3 | 4 | module.exports = { 5 | context: __dirname, 6 | entry: { 7 | main: "./app/frontend/application.cjsx", 8 | }, 9 | output: { 10 | path: path.join(__dirname, 'app', 'assets', 'javascripts'), 11 | filename: "application_bundle.js", 12 | publicPath: "/js/", 13 | devtoolModuleFilenameTemplate: '[resourcePath]', 14 | devtoolFallbackModuleFilenameTemplate: '[resourcePath]?[hash]' 15 | }, 16 | resolve: { 17 | extensions: ["", ".jsx", ".cjsx", ".coffee", ".js"] 18 | }, 19 | module: { 20 | loaders: [ 21 | { test : /\.jsx?$/, loader: 'babel?stage=0', exclude: /node_modules/ }, 22 | { test: /\.cjsx$/, loaders: ["coffee", "cjsx"]}, 23 | { test: /\.coffee$/, loader: "coffee-loader"} 24 | ] 25 | }, 26 | plugins: [ 27 | new webpack.ProvidePlugin({ 28 | 'React': 'react' 29 | }) 30 | ] 31 | } 32 | --------------------------------------------------------------------------------