├── .gitignore
├── LICENCE.txt
├── api
├── .gitignore
├── apidoc.json
├── doc
│ ├── api_data.js
│ ├── api_data.json
│ ├── api_project.js
│ ├── api_project.json
│ ├── css
│ │ └── style.css
│ ├── img
│ │ ├── favicon.ico
│ │ ├── glyphicons-halflings-white.png
│ │ └── glyphicons-halflings.png
│ ├── index.html
│ ├── locales
│ │ ├── ca.js
│ │ ├── de.js
│ │ ├── es.js
│ │ ├── fr.js
│ │ ├── locale.js
│ │ ├── nl.js
│ │ ├── pl.js
│ │ ├── pt_br.js
│ │ ├── ru.js
│ │ ├── zh.js
│ │ └── zh_cn.js
│ ├── main.js
│ ├── utils
│ │ ├── handlebars_helper.js
│ │ └── send_sample_request.js
│ └── vendor
│ │ ├── bootstrap-responsive.min.css
│ │ ├── bootstrap.min.css
│ │ ├── bootstrap.min.js
│ │ ├── diff_match_patch.min.js
│ │ ├── handlebars.min.js
│ │ ├── jquery.min.js
│ │ ├── lodash.min.js
│ │ ├── path-to-regexp
│ │ ├── LICENSE
│ │ └── index.js
│ │ ├── polyfill.js
│ │ ├── prettify.css
│ │ ├── prettify
│ │ ├── lang-apollo.js
│ │ ├── lang-basic.js
│ │ ├── lang-clj.js
│ │ ├── lang-css.js
│ │ ├── lang-dart.js
│ │ ├── lang-erlang.js
│ │ ├── lang-go.js
│ │ ├── lang-hs.js
│ │ ├── lang-lisp.js
│ │ ├── lang-llvm.js
│ │ ├── lang-lua.js
│ │ ├── lang-matlab.js
│ │ ├── lang-ml.js
│ │ ├── lang-mumps.js
│ │ ├── lang-n.js
│ │ ├── lang-pascal.js
│ │ ├── lang-proto.js
│ │ ├── lang-r.js
│ │ ├── lang-rd.js
│ │ ├── lang-scala.js
│ │ ├── lang-sql.js
│ │ ├── lang-tcl.js
│ │ ├── lang-tex.js
│ │ ├── lang-vb.js
│ │ ├── lang-vhdl.js
│ │ ├── lang-wiki.js
│ │ ├── lang-xq.js
│ │ ├── lang-yaml.js
│ │ ├── prettify.css
│ │ ├── prettify.js
│ │ └── run_prettify.js
│ │ ├── require.min.js
│ │ ├── semver.min.js
│ │ └── webfontloader.js
├── package.json
└── src
│ ├── data
│ ├── bordeaux-wines.json
│ ├── burgundy-wines.json
│ ├── champagne-wines.json
│ ├── images
│ │ ├── aligote.png
│ │ ├── arcins.png
│ │ ├── bel-air.png
│ │ ├── boisson.png
│ │ ├── bollinger-special-cuvee.png
│ │ ├── bonnamy.png
│ │ ├── chantalouette.png
│ │ ├── charme-cos-labory.png
│ │ ├── cheval-noir.png
│ │ ├── chevrol-bel-air.png
│ │ ├── clarendelle.png
│ │ ├── cormeil-figeac.png
│ │ ├── cote-beaune-village.png
│ │ ├── deutz.png
│ │ ├── domaine-chatenoy.png
│ │ ├── domaine-desoucherie.png
│ │ ├── domaine-petit-coteau.png
│ │ ├── fleur-haut-bages-liberal.png
│ │ ├── jaillance.png
│ │ ├── la-noe.png
│ │ ├── la-roche.png
│ │ ├── lacaussade-saint-martin.png
│ │ ├── ladoix-pierre-andre.png
│ │ ├── laniote.png
│ │ ├── lanson-blanc-de-blanc.png
│ │ ├── lanson.png
│ │ ├── latour-camblanes.png
│ │ ├── laurent-perrier.png
│ │ ├── les-cailloux.png
│ │ ├── les-champs-clos-blanc.png
│ │ ├── les-champs-clos-rouge.png
│ │ ├── les-hauts-de-tour-prignac.png
│ │ ├── les-vaillons.png
│ │ ├── lestage.png
│ │ ├── macon-lugny.png
│ │ ├── marsannay.png
│ │ ├── moet-chandon.png
│ │ ├── mouton-cadet-rose.png
│ │ ├── mouton-cadet.png
│ │ ├── oratoire-chasse-spleen.png
│ │ ├── patache-d-aux.png
│ │ ├── philippe-de-valois.png
│ │ ├── pol-roger.png
│ │ ├── rahoul.png
│ │ ├── reserve-des-vignerons-blanc.png
│ │ ├── reserve-des-vignerons-rouge.png
│ │ ├── roc-de-boissac.png
│ │ ├── teynac.png
│ │ ├── thomas-barton-reserve.png
│ │ ├── tour-des-termes.png
│ │ └── vin-de-messe.png
│ └── loire-wines.json
│ └── server.js
├── dependencies
├── .gitignore
└── package.json
├── deps.js
├── install.sh
├── print
├── index.html
├── pdf
│ ├── all.pdf
│ ├── index.pdf
│ ├── step-0.pdf
│ ├── step-1.pdf
│ ├── step-2.pdf
│ ├── step-3.pdf
│ ├── step-4.pdf
│ ├── step-5.pdf
│ ├── step-6.pdf
│ ├── step-7.pdf
│ └── step-8.pdf
├── step-0
│ └── index.html
├── step-1
│ └── index.html
├── step-2
│ └── index.html
├── step-3
│ └── index.html
├── step-4
│ └── index.html
├── step-5
│ └── index.html
├── step-6
│ └── index.html
├── step-7
│ └── index.html
└── step-8
│ └── index.html
├── readme.md
├── step-0-done
├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── package.json
├── public
│ ├── css
│ │ └── main.css
│ ├── img
│ │ ├── chevrol-bel-air.png
│ │ └── react.png
│ ├── index.html
│ └── js
│ │ └── .gitkeep
├── readme.md
├── src
│ ├── app.js
│ └── components
│ │ └── wine.js
└── webpack.config.js
├── step-0
└── readme.md
├── step-1-done
├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── package.json
├── public
│ ├── css
│ │ ├── avalanche.css
│ │ └── main.css
│ ├── img
│ │ ├── chevrol-bel-air.png
│ │ └── react.png
│ ├── index.html
│ └── js
│ │ └── .gitkeep
├── readme.md
├── src
│ ├── app.js
│ └── components
│ │ └── wine.js
├── tests
│ ├── bootstrap.js
│ ├── components
│ │ └── wine.spec.js
│ └── index.js
└── webpack.config.js
├── step-1
├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── package.json
├── public
│ ├── css
│ │ └── main.css
│ ├── img
│ │ ├── chevrol-bel-air.png
│ │ └── react.png
│ ├── index.html
│ └── js
│ │ └── .gitkeep
├── readme.md
├── src
│ ├── app.js
│ └── components
│ │ └── wine.js
├── tests
│ ├── bootstrap.js
│ └── index.js
└── webpack.config.js
├── step-2-done
├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── package.json
├── public
│ ├── css
│ │ ├── avalanche.css
│ │ └── main.css
│ ├── img
│ │ ├── chevrol-bel-air.png
│ │ └── react.png
│ ├── index.html
│ └── js
│ │ └── .gitkeep
├── readme.md
├── src
│ ├── app.js
│ └── components
│ │ ├── regions.js
│ │ ├── wine-app.js
│ │ ├── wine-list.js
│ │ └── wine.js
├── tests
│ ├── bootstrap.js
│ ├── components
│ │ ├── regions.spec.js
│ │ ├── wine-app.spec.js
│ │ ├── wine-list.spec.js
│ │ └── wine.spec.js
│ └── index.js
└── webpack.config.js
├── step-2
├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── package.json
├── public
│ ├── css
│ │ ├── avalanche.css
│ │ └── main.css
│ ├── img
│ │ ├── chevrol-bel-air.png
│ │ └── react.png
│ ├── index.html
│ └── js
│ │ └── .gitkeep
├── readme.md
├── src
│ ├── app.js
│ └── components
│ │ ├── regions.js
│ │ ├── wine-app.js
│ │ ├── wine-list.js
│ │ └── wine.js
├── tests
│ ├── bootstrap.js
│ ├── components
│ │ ├── regions.spec.js
│ │ ├── wine-app.spec.js
│ │ ├── wine-list.spec.js
│ │ └── wine.spec.js
│ └── index.js
├── webpack.config.js
├── wines-components.png
└── wines.png
├── step-3-done
├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── package.json
├── public
│ ├── css
│ │ ├── avalanche.css
│ │ └── main.css
│ ├── img
│ │ ├── chevrol-bel-air.png
│ │ └── react.png
│ ├── index.html
│ └── js
│ │ └── .gitkeep
├── readme.md
├── src
│ ├── app.js
│ ├── components
│ │ ├── not-found.js
│ │ ├── regions.js
│ │ ├── wine-app.js
│ │ ├── wine-list.js
│ │ └── wine.js
│ └── index.js
├── tests
│ ├── bootstrap.js
│ ├── components
│ │ ├── regions.spec.js
│ │ ├── wine-app.spec.js
│ │ ├── wine-list.spec.js
│ │ └── wine.spec.js
│ └── index.js
└── webpack.config.js
├── step-3
├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── package.json
├── public
│ ├── css
│ │ ├── avalanche.css
│ │ └── main.css
│ ├── img
│ │ ├── chevrol-bel-air.png
│ │ └── react.png
│ ├── index.html
│ └── js
│ │ └── .gitkeep
├── readme.md
├── src
│ ├── app.js
│ ├── components
│ │ ├── not-found.js
│ │ ├── regions.js
│ │ ├── wine-app.js
│ │ ├── wine-list.js
│ │ └── wine.js
│ └── index.js
├── tests
│ ├── bootstrap.js
│ ├── components
│ │ ├── regions.spec.js
│ │ ├── wine-app.spec.js
│ │ ├── wine-list.spec.js
│ │ └── wine.spec.js
│ └── index.js
├── view1.png
├── view2.png
├── view3.png
└── webpack.config.js
├── step-4-done
├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── package.json
├── public
│ ├── css
│ │ ├── avalanche.css
│ │ └── main.css
│ ├── img
│ │ ├── chevrol-bel-air.png
│ │ └── react.png
│ ├── index.html
│ └── js
│ │ └── .gitkeep
├── readme.md
├── src
│ ├── app.js
│ ├── components
│ │ ├── comments.js
│ │ ├── not-found.js
│ │ ├── regions.js
│ │ ├── wine-app.js
│ │ ├── wine-list.js
│ │ └── wine.js
│ └── index.js
├── tests
│ ├── bootstrap.js
│ ├── components
│ │ ├── regions.spec.js
│ │ ├── wine-app.spec.js
│ │ ├── wine-list.spec.js
│ │ └── wine.spec.js
│ └── index.js
└── webpack.config.js
├── step-4
├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── mockup.png
├── package.json
├── public
│ ├── css
│ │ ├── avalanche.css
│ │ └── main.css
│ ├── img
│ │ ├── chevrol-bel-air.png
│ │ └── react.png
│ ├── index.html
│ └── js
│ │ └── .gitkeep
├── readme.md
├── src
│ ├── app.js
│ ├── components
│ │ ├── comments.js
│ │ ├── not-found.js
│ │ ├── regions.js
│ │ ├── wine-app.js
│ │ ├── wine-list.js
│ │ └── wine.js
│ └── index.js
├── tests
│ ├── bootstrap.js
│ ├── components
│ │ ├── regions.spec.js
│ │ ├── wine-app.spec.js
│ │ ├── wine-list.spec.js
│ │ └── wine.spec.js
│ └── index.js
└── webpack.config.js
├── step-5-done
├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── package.json
├── public
│ ├── css
│ │ ├── avalanche.css
│ │ └── main.css
│ ├── img
│ │ ├── chevrol-bel-air.png
│ │ └── react.png
│ ├── index.html
│ └── js
│ │ └── .gitkeep
├── readme.md
├── src
│ ├── actions
│ │ └── index.js
│ ├── app.js
│ ├── components
│ │ ├── comments.js
│ │ ├── not-found.js
│ │ ├── regions.js
│ │ ├── stats.js
│ │ ├── wine-app.js
│ │ ├── wine-list.js
│ │ └── wine.js
│ ├── index.js
│ └── reducers
│ │ ├── comments.js
│ │ ├── index.js
│ │ └── likes.js
├── tests
│ ├── bootstrap.js
│ ├── components
│ │ ├── regions.spec.js
│ │ ├── wine-app.spec.js
│ │ ├── wine-list.spec.js
│ │ └── wine.spec.js
│ └── index.js
└── webpack.config.js
├── step-5
├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── package.json
├── public
│ ├── css
│ │ ├── avalanche.css
│ │ └── main.css
│ ├── img
│ │ ├── chevrol-bel-air.png
│ │ └── react.png
│ ├── index.html
│ └── js
│ │ └── .gitkeep
├── readme.md
├── src
│ ├── actions
│ │ └── index.js
│ ├── app.js
│ ├── components
│ │ ├── clicker.js
│ │ ├── comments.js
│ │ ├── not-found.js
│ │ ├── regions.js
│ │ ├── wine-app.js
│ │ ├── wine-list.js
│ │ └── wine.js
│ ├── index.js
│ └── reducers
│ │ ├── counter.js
│ │ └── index.js
├── tests
│ ├── bootstrap.js
│ ├── components
│ │ ├── regions.spec.js
│ │ ├── wine-app.spec.js
│ │ ├── wine-list.spec.js
│ │ └── wine.spec.js
│ └── index.js
├── view1.png
└── webpack.config.js
├── step-6-done
├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── package.json
├── public
│ ├── css
│ │ ├── avalanche.css
│ │ └── main.css
│ ├── img
│ │ ├── chevrol-bel-air.png
│ │ └── react.png
│ ├── index.html
│ └── js
│ │ └── .gitkeep
├── readme.md
├── src
│ ├── actions
│ │ └── index.js
│ ├── app.js
│ ├── components
│ │ ├── comments.js
│ │ ├── devtools.js
│ │ ├── not-found.js
│ │ ├── regions.js
│ │ ├── stats.js
│ │ ├── wine-app.js
│ │ ├── wine-list.js
│ │ └── wine.js
│ ├── index.js
│ └── reducers
│ │ ├── comments.js
│ │ ├── http.js
│ │ ├── index.js
│ │ ├── likes.js
│ │ ├── regions.js
│ │ ├── title.js
│ │ └── wines.js
├── tests
│ ├── bootstrap.js
│ ├── components
│ │ ├── regions.spec.js
│ │ ├── wine-app.spec.js
│ │ ├── wine-list.spec.js
│ │ └── wine.spec.js
│ └── index.js
└── webpack.config.js
├── step-6
├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── package.json
├── public
│ ├── css
│ │ ├── avalanche.css
│ │ └── main.css
│ ├── img
│ │ ├── chevrol-bel-air.png
│ │ └── react.png
│ ├── index.html
│ └── js
│ │ └── .gitkeep
├── readme.md
├── src
│ ├── actions
│ │ └── index.js
│ ├── app.js
│ ├── components
│ │ ├── comments.js
│ │ ├── devtools.js
│ │ ├── not-found.js
│ │ ├── regions.js
│ │ ├── stats.js
│ │ ├── wine-app.js
│ │ ├── wine-list.js
│ │ └── wine.js
│ ├── index.js
│ └── reducers
│ │ ├── comments.js
│ │ ├── http.js
│ │ ├── index.js
│ │ └── likes.js
├── tests
│ ├── bootstrap.js
│ ├── components
│ │ ├── regions.spec.js
│ │ ├── wine-app.spec.js
│ │ ├── wine-list.spec.js
│ │ └── wine.spec.js
│ └── index.js
└── webpack.config.js
├── step-7
├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── package.json
├── public
│ ├── css
│ │ ├── avalanche.css
│ │ └── main.css
│ ├── img
│ │ ├── chevrol-bel-air.png
│ │ └── react.png
│ ├── index.html
│ └── js
│ │ └── .gitkeep
├── readme.md
├── src
│ ├── actions
│ │ └── index.js
│ ├── app.js
│ ├── components
│ │ ├── comments.js
│ │ ├── devtools.js
│ │ ├── not-found.js
│ │ ├── regions.js
│ │ ├── stats.js
│ │ ├── wine-app.js
│ │ ├── wine-list.js
│ │ └── wine.js
│ ├── index.js
│ └── reducers
│ │ ├── comments.js
│ │ ├── http.js
│ │ ├── index.js
│ │ ├── likes.js
│ │ ├── regions.js
│ │ ├── title.js
│ │ └── wines.js
├── tests
│ ├── bootstrap.js
│ ├── components
│ │ ├── regions.spec.js
│ │ ├── wine-app.spec.js
│ │ ├── wine-list.spec.js
│ │ └── wine.spec.js
│ └── index.js
└── webpack.config.js
├── step-8-done
├── .eslintignore
├── .eslintrc
├── .flowconfig
├── .gitignore
├── .watchmanconfig
├── android
│ ├── app
│ │ ├── app.iml
│ │ ├── build.gradle
│ │ ├── proguard-rules.pro
│ │ ├── react.gradle
│ │ └── src
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── wines
│ │ │ │ └── MainActivity.java
│ │ │ └── res
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ └── values
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── settings.gradle
│ └── wines.iml
├── index.android.js
├── index.ios.js
├── ios
│ ├── wines.xcodeproj
│ │ ├── project.pbxproj
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── wines.xcscheme
│ ├── wines
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Base.lproj
│ │ │ └── LaunchScreen.xib
│ │ ├── Images.xcassets
│ │ │ └── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ ├── Info.plist
│ │ └── main.m
│ └── winesTests
│ │ ├── Info.plist
│ │ └── winesTests.m
├── package.json
└── src
│ ├── actions
│ └── index.js
│ ├── app.js
│ ├── components
│ ├── button.js
│ ├── comments.js
│ ├── liked.png
│ ├── loading.android.js
│ ├── loading.ios.js
│ ├── not-found.android.js
│ ├── region-cell.js
│ ├── regions.js
│ ├── style.js
│ ├── unliked.png
│ ├── wine-app.android.js
│ ├── wine-app.ios.js
│ ├── wine-cell.js
│ ├── wine-list.js
│ └── wine.js
│ └── reducers
│ ├── comments.js
│ ├── http.js
│ ├── index.js
│ ├── likes.js
│ ├── regions.js
│ ├── title.js
│ └── wines.js
├── step-8
├── .eslintignore
├── .eslintrc
├── .flowconfig
├── .gitignore
├── .watchmanconfig
├── android
│ ├── app
│ │ ├── app.iml
│ │ ├── build.gradle
│ │ ├── proguard-rules.pro
│ │ ├── react.gradle
│ │ └── src
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── wines
│ │ │ │ └── MainActivity.java
│ │ │ └── res
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ └── values
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── settings.gradle
│ └── wines.iml
├── index.android.js
├── index.ios.js
├── ios
│ ├── wines.xcodeproj
│ │ ├── project.pbxproj
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── wines.xcscheme
│ ├── wines
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Base.lproj
│ │ │ └── LaunchScreen.xib
│ │ ├── Images.xcassets
│ │ │ └── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ ├── Info.plist
│ │ └── main.m
│ └── winesTests
│ │ ├── Info.plist
│ │ └── winesTests.m
├── live-reload.png
├── package.json
├── reactnative-emulator.png
├── readme.md
├── regions-android.png
├── regions-ios.png
├── src
│ ├── actions
│ │ └── index.js
│ ├── app.js
│ ├── components
│ │ ├── button.js
│ │ ├── comments.js
│ │ ├── liked.png
│ │ ├── loading.android.js
│ │ ├── loading.ios.js
│ │ ├── region-cell.js
│ │ ├── regions.js
│ │ ├── style.js
│ │ ├── unliked.png
│ │ ├── wine-app.android.js
│ │ ├── wine-app.ios.js
│ │ ├── wine-cell.js
│ │ ├── wine-list.js
│ │ └── wine.js
│ └── reducers
│ │ ├── comments.js
│ │ ├── http.js
│ │ ├── index.js
│ │ ├── likes.js
│ │ ├── regions.js
│ │ ├── title.js
│ │ └── wines.js
├── wine-liked-android.png
├── wine-liked-ios.png
├── wine-unliked-android.png
├── wine-unliked-ios.png
├── wines-android.png
└── wines-ios.png
├── test-all-done.sh
└── test-all-undone.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | /step-live
2 | .DS_Store
3 |
--------------------------------------------------------------------------------
/api/.gitignore:
--------------------------------------------------------------------------------
1 | # Node.js
2 | node_modules
3 | npm-debug.log
4 |
--------------------------------------------------------------------------------
/api/apidoc.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-workshop-api-doc",
3 | "version": "1.0.0",
4 | "description": "React Workshop API documentation",
5 | "title": "React Workshop API",
6 | "url" : "http://localhost:3000/api"
7 | }
8 |
--------------------------------------------------------------------------------
/api/doc/api_project.js:
--------------------------------------------------------------------------------
1 | define({
"name": "react-workshop-api-doc",
"version": "1.0.0",
"description": "React Workshop API documentation",
"title": "React Workshop API",
"url": "http://localhost:3000/api",
"sampleUrl": false,
"apidoc": "0.2.0",
"generator": {
"name": "apidoc",
"time": "2016-04-11T08:48:33.421Z",
"url": "http://apidocjs.com",
"version": "0.15.1"
}
});
2 |
--------------------------------------------------------------------------------
/api/doc/api_project.json:
--------------------------------------------------------------------------------
1 | {
"name": "react-workshop-api-doc",
"version": "1.0.0",
"description": "React Workshop API documentation",
"title": "React Workshop API",
"url": "http://localhost:3000/api",
"sampleUrl": false,
"apidoc": "0.2.0",
"generator": {
"name": "apidoc",
"time": "2016-04-11T08:48:33.421Z",
"url": "http://apidocjs.com",
"version": "0.15.1"
}
}
2 |
--------------------------------------------------------------------------------
/api/doc/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/doc/img/favicon.ico
--------------------------------------------------------------------------------
/api/doc/img/glyphicons-halflings-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/doc/img/glyphicons-halflings-white.png
--------------------------------------------------------------------------------
/api/doc/img/glyphicons-halflings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/doc/img/glyphicons-halflings.png
--------------------------------------------------------------------------------
/api/doc/locales/zh.js:
--------------------------------------------------------------------------------
1 | define({
2 | zh: {
3 | 'Allowed values:' : '允許值:',
4 | 'Compare all with predecessor': '預先比較所有',
5 | 'compare changes to:' : '比較變更:',
6 | 'compared to' : '對比',
7 | 'Default value:' : '默認值:',
8 | 'Description' : '描述',
9 | 'Field' : '字段',
10 | 'General' : '概括',
11 | 'Generated with' : '生成工具',
12 | 'Name' : '名稱',
13 | 'No response values.' : '無對應資料.',
14 | 'optional' : '選項',
15 | 'Parameter' : '參數',
16 | 'Permission:' : '允許:',
17 | 'Response' : '回應',
18 | 'Send' : '發送',
19 | 'Send a Sample Request' : '發送試用需求',
20 | 'show up to version:' : '顯示到版本:',
21 | 'Size range:' : '尺寸範圍:',
22 | 'Type' : '類型',
23 | 'url' : '網址'
24 | }
25 | });
26 |
--------------------------------------------------------------------------------
/api/doc/locales/zh_cn.js:
--------------------------------------------------------------------------------
1 | define({
2 | 'zh_cn': {
3 | 'Allowed values:' : '允许值:',
4 | 'Compare all with predecessor': '与所有较早的比较',
5 | 'compare changes to:' : '将当前版本与指定版本比较:',
6 | 'compared to' : '相比于',
7 | 'Default value:' : '默认值:',
8 | 'Description' : '描述',
9 | 'Field' : '字段',
10 | 'General' : '概要',
11 | 'Generated with' : '基于',
12 | 'Name' : '名称',
13 | 'No response values.' : '无返回值.',
14 | 'optional' : '可选',
15 | 'Parameter' : '参数',
16 | 'Permission:' : '权限:',
17 | 'Response' : '返回',
18 | 'Send' : '发送',
19 | 'Send a Sample Request' : '发送示例请求',
20 | 'show up to version:' : '显示到指定版本:',
21 | 'Size range:' : '取值范围:',
22 | 'Type' : '类型',
23 | 'url' : '网址'
24 | }
25 | });
26 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-apollo.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["com",/^#[^\n\r]*/,null,"#"],["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,null,'"']],[["kwd",/^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\s/,
2 | null],["typ",/^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[ES]?BANK=?|BLOCK|BNKSUM|E?CADR|COUNT\*?|2?DEC\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\s/,null],["lit",/^'(?:-*(?:\w|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?)?/],["pln",/^-*(?:[!-z]|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?/],["pun",/^[^\w\t\n\r "'-);\\\xa0]+/]]),["apollo","agc","aea"]);
3 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-basic.js:
--------------------------------------------------------------------------------
1 | var a=null;
2 | PR.registerLangHandler(PR.createSimpleLexer([["str",/^"(?:[^\n\r"\\]|\\.)*(?:"|$)/,a,'"'],["pln",/^\s+/,a," \r\n\t\u00a0"]],[["com",/^REM[^\n\r]*/,a],["kwd",/^\b(?:AND|CLOSE|CLR|CMD|CONT|DATA|DEF ?FN|DIM|END|FOR|GET|GOSUB|GOTO|IF|INPUT|LET|LIST|LOAD|NEW|NEXT|NOT|ON|OPEN|OR|POKE|PRINT|READ|RESTORE|RETURN|RUN|SAVE|STEP|STOP|SYS|THEN|TO|VERIFY|WAIT)\b/,a],["pln",/^[a-z][^\W_]?(?:\$|%)?/i,a],["lit",/^(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?/i,a,"0123456789"],["pun",
3 | /^.[^\s\w"$%.]*/,a]]),["basic","cbm"]);
4 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-css.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n\u000c"]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]+)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],
2 | ["com",/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}\b/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]);
3 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-dart.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"]],[["com",/^#!.*/],["kwd",/^\b(?:import|library|part of|part|as|show|hide)\b/i],["com",/^\/\/.*/],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["kwd",/^\b(?:class|interface)\b/i],["kwd",/^\b(?:assert|break|case|catch|continue|default|do|else|finally|for|if|in|is|new|return|super|switch|this|throw|try|while)\b/i],["kwd",/^\b(?:abstract|const|extends|factory|final|get|implements|native|operator|set|static|typedef|var)\b/i],
2 | ["typ",/^\b(?:bool|double|dynamic|int|num|object|string|void)\b/i],["kwd",/^\b(?:false|null|true)\b/i],["str",/^r?'''[\S\s]*?[^\\]'''/],["str",/^r?"""[\S\s]*?[^\\]"""/],["str",/^r?'('|[^\n\f\r]*?[^\\]')/],["str",/^r?"("|[^\n\f\r]*?[^\\]")/],["pln",/^[$_a-z]\w*/i],["pun",/^[!%&*+/:<-?^|~-]/],["lit",/^\b0x[\da-f]+/i],["lit",/^\b\d+(?:\.\d*)?(?:e[+-]?\d+)?/i],["lit",/^\b\.\d+(?:e[+-]?\d+)?/i],["pun",/^[(),.;[\]{}]/]]),
3 | ["dart"]);
4 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-erlang.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t-\r ]+/,null,"\t\n\u000b\u000c\r "],["str",/^"(?:[^\n\f\r"\\]|\\[\S\s])*(?:"|$)/,null,'"'],["lit",/^[a-z]\w*/],["lit",/^'(?:[^\n\f\r'\\]|\\[^&])+'?/,null,"'"],["lit",/^\?[^\t\n ({]+/,null,"?"],["lit",/^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?)/i,null,"0123456789"]],[["com",/^%[^\n]*/],["kwd",/^(?:module|attributes|do|let|in|letrec|apply|call|primop|case|of|end|when|fun|try|catch|receive|after|char|integer|float,atom,string,var)\b/],
2 | ["kwd",/^-[_a-z]+/],["typ",/^[A-Z_]\w*/],["pun",/^[,.;]/]]),["erlang","erl"]);
3 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-go.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["pln",/^(?:"(?:[^"\\]|\\[\S\s])*(?:"|$)|'(?:[^'\\]|\\[\S\s])+(?:'|$)|`[^`]*(?:`|$))/,null,"\"'"]],[["com",/^(?:\/\/[^\n\r]*|\/\*[\S\s]*?\*\/)/],["pln",/^(?:[^"'/`]|\/(?![*/]))+/]]),["go"]);
2 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-hs.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t-\r ]+/,null,"\t\n\u000b\u000c\r "],["str",/^"(?:[^\n\f\r"\\]|\\[\S\s])*(?:"|$)/,null,'"'],["str",/^'(?:[^\n\f\r'\\]|\\[^&])'?/,null,"'"],["lit",/^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?)/i,null,"0123456789"]],[["com",/^(?:--+[^\n\f\r]*|{-(?:[^-]|-+[^}-])*-})/],["kwd",/^(?:case|class|data|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|module|newtype|of|then|type|where|_)(?=[^\d'A-Za-z]|$)/,
2 | null],["pln",/^(?:[A-Z][\w']*\.)*[A-Za-z][\w']*/],["pun",/^[^\d\t-\r "'A-Za-z]+/]]),["hs"]);
3 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-lisp.js:
--------------------------------------------------------------------------------
1 | var a=null;
2 | PR.registerLangHandler(PR.createSimpleLexer([["opn",/^\(+/,a,"("],["clo",/^\)+/,a,")"],["com",/^;[^\n\r]*/,a,";"],["pln",/^[\t\n\r \xa0]+/,a,"\t\n\r \u00a0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,a,'"']],[["kwd",/^(?:block|c[ad]+r|catch|con[ds]|def(?:ine|un)|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\b/,a],
3 | ["lit",/^[+-]?(?:[#0]x[\da-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[de][+-]?\d+)?)/i],["lit",/^'(?:-*(?:\w|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?)?/],["pln",/^-*(?:[_a-z]|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?/i],["pun",/^[^\w\t\n\r "'-);\\\xa0]+/]]),["cl","el","lisp","lsp","scm","ss","rkt"]);
4 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-llvm.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^!?"(?:[^"\\]|\\[\S\s])*(?:"|$)/,null,'"'],["com",/^;[^\n\r]*/,null,";"]],[["pln",/^[!%@](?:[$\-.A-Z_a-z][\w$\-.]*|\d+)/],["kwd",/^[^\W\d]\w*/,null],["lit",/^\d+\.\d+/],["lit",/^(?:\d+|0[Xx][\dA-Fa-f]+)/],["pun",/^[(-*,:<->[\]{}]|\.\.\.$/]]),["llvm","ll"]);
2 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-lua.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^(?:"(?:[^"\\]|\\[\S\s])*(?:"|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$))/,null,"\"'"]],[["com",/^--(?:\[(=*)\[[\S\s]*?(?:]\1]|$)|[^\n\r]*)/],["str",/^\[(=*)\[[\S\s]*?(?:]\1]|$)/],["kwd",/^(?:and|break|do|else|elseif|end|false|for|function|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,null],["lit",/^[+-]?(?:0x[\da-f]+|(?:\.\d+|\d+(?:\.\d*)?)(?:e[+-]?\d+)?)/i],
2 | ["pln",/^[_a-z]\w*/i],["pun",/^[^\w\t\n\r \xa0][^\w\t\n\r "'+=\xa0-]*/]]),["lua"]);
3 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-ml.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["com",/^#(?:if[\t\n\r \xa0]+(?:[$_a-z][\w']*|``[^\t\n\r`]*(?:``|$))|else|endif|light)/i,null,"#"],["str",/^(?:"(?:[^"\\]|\\[\S\s])*(?:"|$)|'(?:[^'\\]|\\[\S\s])(?:'|$))/,null,"\"'"]],[["com",/^(?:\/\/[^\n\r]*|\(\*[\S\s]*?\*\))/],["kwd",/^(?:abstract|and|as|assert|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|if|in|inherit|inline|interface|internal|lazy|let|match|member|module|mutable|namespace|new|null|of|open|or|override|private|public|rec|return|static|struct|then|to|true|try|type|upcast|use|val|void|when|while|with|yield|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|global|include|method|mixin|object|parallel|process|protected|pure|sealed|trait|virtual|volatile)\b/],
2 | ["lit",/^[+-]?(?:0x[\da-f]+|(?:\.\d+|\d+(?:\.\d*)?)(?:e[+-]?\d+)?)/i],["pln",/^(?:[_a-z][\w']*[!#?]?|``[^\t\n\r`]*(?:``|$))/i],["pun",/^[^\w\t\n\r "'\xa0]+/]]),["fs","ml"]);
3 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-mumps.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^"(?:[^"]|\\.)*"/,null,'"']],[["com",/^;[^\n\r]*/,null,";"],["dec",/^\$(?:d|device|ec|ecode|es|estack|et|etrap|h|horolog|i|io|j|job|k|key|p|principal|q|quit|st|stack|s|storage|sy|system|t|test|tl|tlevel|tr|trestart|x|y|z[a-z]*|a|ascii|c|char|d|data|e|extract|f|find|fn|fnumber|g|get|j|justify|l|length|na|name|o|order|p|piece|ql|qlength|qs|qsubscript|q|query|r|random|re|reverse|s|select|st|stack|t|text|tr|translate|nan)\b/i,
2 | null],["kwd",/^(?:[^$]b|break|c|close|d|do|e|else|f|for|g|goto|h|halt|h|hang|i|if|j|job|k|kill|l|lock|m|merge|n|new|o|open|q|quit|r|read|s|set|tc|tcommit|tre|trestart|tro|trollback|ts|tstart|u|use|v|view|w|write|x|xecute)\b/i,null],["lit",/^[+-]?(?:\.\d+|\d+(?:\.\d*)?)(?:e[+-]?\d+)?/i],["pln",/^[a-z][^\W_]*/i],["pun",/^[^\w\t\n\r"$%;^\xa0]|_/]]),["mumps"]);
3 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-pascal.js:
--------------------------------------------------------------------------------
1 | var a=null;
2 | PR.registerLangHandler(PR.createSimpleLexer([["str",/^'(?:[^\n\r'\\]|\\.)*(?:'|$)/,a,"'"],["pln",/^\s+/,a," \r\n\t\u00a0"]],[["com",/^\(\*[\S\s]*?(?:\*\)|$)|^{[\S\s]*?(?:}|$)/,a],["kwd",/^(?:absolute|and|array|asm|assembler|begin|case|const|constructor|destructor|div|do|downto|else|end|external|for|forward|function|goto|if|implementation|in|inline|interface|interrupt|label|mod|not|object|of|or|packed|procedure|program|record|repeat|set|shl|shr|then|to|type|unit|until|uses|var|virtual|while|with|xor)\b/i,a],
3 | ["lit",/^(?:true|false|self|nil)/i,a],["pln",/^[a-z][^\W_]*/i,a],["lit",/^(?:\$[\da-f]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?)/i,a,"0123456789"],["pun",/^.[^\s\w$'./@]*/,a]]),["pascal"]);
4 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-proto.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.sourceDecorator({keywords:"bytes,default,double,enum,extend,extensions,false,group,import,max,message,option,optional,package,repeated,required,returns,rpc,service,syntax,to,true",types:/^(bool|(double|s?fixed|[su]?int)(32|64)|float|string)\b/,cStyleComments:!0}),["proto"]);
2 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-r.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,null,'"'],["str",/^'(?:[^'\\]|\\[\S\s])*(?:'|$)/,null,"'"]],[["com",/^#.*/],["kwd",/^(?:if|else|for|while|repeat|in|next|break|return|switch|function)(?![\w.])/],["lit",/^0[Xx][\dA-Fa-f]+([Pp]\d+)?[Li]?/],["lit",/^[+-]?(\d+(\.\d+)?|\.\d+)([Ee][+-]?\d+)?[Li]?/],["lit",/^(?:NULL|NA(?:_(?:integer|real|complex|character)_)?|Inf|TRUE|FALSE|NaN|\.\.(?:\.|\d+))(?![\w.])/],
2 | ["pun",/^(?:<-|->>?|-|==|<=|>=|<|>|&&?|!=|\|\|?|[!*+/^]|%.*?%|[$=@~]|:{1,3}|[(),;?[\]{}])/],["pln",/^(?:[A-Za-z]+[\w.]*|\.[^\W\d][\w.]*)(?![\w.])/],["str",/^`.+`/]]),["r","s","R","S","Splus"]);
3 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-rd.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["com",/^%[^\n\r]*/,null,"%"]],[["lit",/^\\(?:cr|l?dots|R|tab)\b/],["kwd",/^\\[@-Za-z]+/],["kwd",/^#(?:ifn?def|endif)/],["pln",/^\\[{}]/],["pun",/^[()[\]{}]+/]]),["Rd","rd"]);
2 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-scala.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^"(?:""(?:""?(?!")|[^"\\]|\\.)*"{0,3}|(?:[^\n\r"\\]|\\.)*"?)/,null,'"'],["lit",/^`(?:[^\n\r\\`]|\\.)*`?/,null,"`"],["pun",/^[!#%&(--:-@[-^{-~]+/,null,"!#%&()*+,-:;<=>?@[\\]^{|}~"]],[["str",/^'(?:[^\n\r'\\]|\\(?:'|[^\n\r']+))'/],["lit",/^'[$A-Z_a-z][\w$]*(?![\w$'])/],["kwd",/^(?:abstract|case|catch|class|def|do|else|extends|final|finally|for|forSome|if|implicit|import|lazy|match|new|object|override|package|private|protected|requires|return|sealed|super|throw|trait|try|type|val|var|while|with|yield)\b/],
2 | ["lit",/^(?:true|false|null|this)\b/],["lit",/^(?:0(?:[0-7]+|x[\da-f]+)l?|(?:0|[1-9]\d*)(?:(?:\.\d+)?(?:e[+-]?\d+)?f?|l?)|\\.\d+(?:e[+-]?\d+)?f?)/i],["typ",/^[$_]*[A-Z][\d$A-Z_]*[a-z][\w$]*/],["pln",/^[$A-Z_a-z][\w$]*/],["com",/^\/(?:\/.*|\*(?:\/|\**[^*/])*(?:\*+\/?)?)/],["pun",/^(?:\.+|\/)/]]),["scala"]);
3 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-tcl.js:
--------------------------------------------------------------------------------
1 | var a=null;
2 | PR.registerLangHandler(PR.createSimpleLexer([["opn",/^{+/,a,"{"],["clo",/^}+/,a,"}"],["com",/^#[^\n\r]*/,a,"#"],["pln",/^[\t\n\r \xa0]+/,a,"\t\n\r \u00a0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,a,'"']],[["kwd",/^(?:after|append|apply|array|break|case|catch|continue|error|eval|exec|exit|expr|for|foreach|if|incr|info|proc|return|set|switch|trace|uplevel|upvar|while)\b/,a],["lit",/^[+-]?(?:[#0]x[\da-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[de][+-]?\d+)?)/i],["lit",
3 | /^'(?:-*(?:\w|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?)?/],["pln",/^-*(?:[_a-z]|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?/i],["pun",/^[^\w\t\n\r "'-);\\\xa0]+/]]),["tcl"]);
4 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-tex.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["com",/^%[^\n\r]*/,null,"%"]],[["kwd",/^\\[@-Za-z]+/],["kwd",/^\\./],["typ",/^[$&]/],["lit",/[+-]?(?:\.\d+|\d+(?:\.\d*)?)(cm|em|ex|in|pc|pt|bp|mm)/i],["pun",/^[()=[\]{}]+/]]),["latex","tex"]);
2 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-wiki.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\d\t a-gi-z\xa0]+/,null,"\t \u00a0abcdefgijklmnopqrstuvwxyz0123456789"],["pun",/^[*=[\]^~]+/,null,"=*~^[]"]],[["lang-wiki.meta",/(?:^^|\r\n?|\n)(#[a-z]+)\b/],["lit",/^[A-Z][a-z][\da-z]+[A-Z][a-z][^\W_]+\b/],["lang-",/^{{{([\S\s]+?)}}}/],["lang-",/^`([^\n\r`]+)`/],["str",/^https?:\/\/[^\s#/?]*(?:\/[^\s#?]*)?(?:\?[^\s#]*)?(?:#\S*)?/i],["pln",/^(?:\r\n|[\S\s])[^\n\r#*=A-[^`h{~]*/]]),["wiki"]);
2 | PR.registerLangHandler(PR.createSimpleLexer([["kwd",/^#[a-z]+/i,null,"#"]],[]),["wiki.meta"]);
3 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/lang-yaml.js:
--------------------------------------------------------------------------------
1 | var a=null;
2 | PR.registerLangHandler(PR.createSimpleLexer([["pun",/^[:>?|]+/,a,":|>?"],["dec",/^%(?:YAML|TAG)[^\n\r#]+/,a,"%"],["typ",/^&\S+/,a,"&"],["typ",/^!\S*/,a,"!"],["str",/^"(?:[^"\\]|\\.)*(?:"|$)/,a,'"'],["str",/^'(?:[^']|'')*(?:'|$)/,a,"'"],["com",/^#[^\n\r]*/,a,"#"],["pln",/^\s+/,a," \t\r\n"]],[["dec",/^(?:---|\.\.\.)(?:[\n\r]|$)/],["pun",/^-/],["kwd",/^\w+:[\n\r ]/],["pln",/^\w+/]]),["yaml","yml"]);
3 |
--------------------------------------------------------------------------------
/api/doc/vendor/prettify/prettify.css:
--------------------------------------------------------------------------------
1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
--------------------------------------------------------------------------------
/api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-workshop-api",
3 | "description": "React Workshop API",
4 | "version": "0.0.0",
5 | "dependencies": {
6 | "express": "4.13.4",
7 | "body-parser": "1.15.0"
8 | },
9 | "devDependencies": {
10 | "apidoc": "0.15.1"
11 | },
12 | "scripts" : {
13 | "start": "node src/server.js",
14 | "doc": "apidoc -i src/ -o doc/"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/api/src/data/images/aligote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/aligote.png
--------------------------------------------------------------------------------
/api/src/data/images/arcins.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/arcins.png
--------------------------------------------------------------------------------
/api/src/data/images/bel-air.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/bel-air.png
--------------------------------------------------------------------------------
/api/src/data/images/boisson.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/boisson.png
--------------------------------------------------------------------------------
/api/src/data/images/bollinger-special-cuvee.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/bollinger-special-cuvee.png
--------------------------------------------------------------------------------
/api/src/data/images/bonnamy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/bonnamy.png
--------------------------------------------------------------------------------
/api/src/data/images/chantalouette.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/chantalouette.png
--------------------------------------------------------------------------------
/api/src/data/images/charme-cos-labory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/charme-cos-labory.png
--------------------------------------------------------------------------------
/api/src/data/images/cheval-noir.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/cheval-noir.png
--------------------------------------------------------------------------------
/api/src/data/images/chevrol-bel-air.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/chevrol-bel-air.png
--------------------------------------------------------------------------------
/api/src/data/images/clarendelle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/clarendelle.png
--------------------------------------------------------------------------------
/api/src/data/images/cormeil-figeac.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/cormeil-figeac.png
--------------------------------------------------------------------------------
/api/src/data/images/cote-beaune-village.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/cote-beaune-village.png
--------------------------------------------------------------------------------
/api/src/data/images/deutz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/deutz.png
--------------------------------------------------------------------------------
/api/src/data/images/domaine-chatenoy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/domaine-chatenoy.png
--------------------------------------------------------------------------------
/api/src/data/images/domaine-desoucherie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/domaine-desoucherie.png
--------------------------------------------------------------------------------
/api/src/data/images/domaine-petit-coteau.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/domaine-petit-coteau.png
--------------------------------------------------------------------------------
/api/src/data/images/fleur-haut-bages-liberal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/fleur-haut-bages-liberal.png
--------------------------------------------------------------------------------
/api/src/data/images/jaillance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/jaillance.png
--------------------------------------------------------------------------------
/api/src/data/images/la-noe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/la-noe.png
--------------------------------------------------------------------------------
/api/src/data/images/la-roche.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/la-roche.png
--------------------------------------------------------------------------------
/api/src/data/images/lacaussade-saint-martin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/lacaussade-saint-martin.png
--------------------------------------------------------------------------------
/api/src/data/images/ladoix-pierre-andre.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/ladoix-pierre-andre.png
--------------------------------------------------------------------------------
/api/src/data/images/laniote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/laniote.png
--------------------------------------------------------------------------------
/api/src/data/images/lanson-blanc-de-blanc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/lanson-blanc-de-blanc.png
--------------------------------------------------------------------------------
/api/src/data/images/lanson.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/lanson.png
--------------------------------------------------------------------------------
/api/src/data/images/latour-camblanes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/latour-camblanes.png
--------------------------------------------------------------------------------
/api/src/data/images/laurent-perrier.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/laurent-perrier.png
--------------------------------------------------------------------------------
/api/src/data/images/les-cailloux.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/les-cailloux.png
--------------------------------------------------------------------------------
/api/src/data/images/les-champs-clos-blanc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/les-champs-clos-blanc.png
--------------------------------------------------------------------------------
/api/src/data/images/les-champs-clos-rouge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/les-champs-clos-rouge.png
--------------------------------------------------------------------------------
/api/src/data/images/les-hauts-de-tour-prignac.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/les-hauts-de-tour-prignac.png
--------------------------------------------------------------------------------
/api/src/data/images/les-vaillons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/les-vaillons.png
--------------------------------------------------------------------------------
/api/src/data/images/lestage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/lestage.png
--------------------------------------------------------------------------------
/api/src/data/images/macon-lugny.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/macon-lugny.png
--------------------------------------------------------------------------------
/api/src/data/images/marsannay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/marsannay.png
--------------------------------------------------------------------------------
/api/src/data/images/moet-chandon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/moet-chandon.png
--------------------------------------------------------------------------------
/api/src/data/images/mouton-cadet-rose.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/mouton-cadet-rose.png
--------------------------------------------------------------------------------
/api/src/data/images/mouton-cadet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/mouton-cadet.png
--------------------------------------------------------------------------------
/api/src/data/images/oratoire-chasse-spleen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/oratoire-chasse-spleen.png
--------------------------------------------------------------------------------
/api/src/data/images/patache-d-aux.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/patache-d-aux.png
--------------------------------------------------------------------------------
/api/src/data/images/philippe-de-valois.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/philippe-de-valois.png
--------------------------------------------------------------------------------
/api/src/data/images/pol-roger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/pol-roger.png
--------------------------------------------------------------------------------
/api/src/data/images/rahoul.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/rahoul.png
--------------------------------------------------------------------------------
/api/src/data/images/reserve-des-vignerons-blanc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/reserve-des-vignerons-blanc.png
--------------------------------------------------------------------------------
/api/src/data/images/reserve-des-vignerons-rouge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/reserve-des-vignerons-rouge.png
--------------------------------------------------------------------------------
/api/src/data/images/roc-de-boissac.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/roc-de-boissac.png
--------------------------------------------------------------------------------
/api/src/data/images/teynac.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/teynac.png
--------------------------------------------------------------------------------
/api/src/data/images/thomas-barton-reserve.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/thomas-barton-reserve.png
--------------------------------------------------------------------------------
/api/src/data/images/tour-des-termes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/tour-des-termes.png
--------------------------------------------------------------------------------
/api/src/data/images/vin-de-messe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/api/src/data/images/vin-de-messe.png
--------------------------------------------------------------------------------
/dependencies/.gitignore:
--------------------------------------------------------------------------------
1 | *.zip
2 | node_modules
3 |
--------------------------------------------------------------------------------
/dependencies/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-workshop-dependencies",
3 | "version": "1.0.0",
4 | "description": "Just a project to fetch all npm dependencies",
5 | "dependencies": {
6 | "express": "4.13.4",
7 | "body-parser": "1.15.0",
8 | "react": "0.14.7",
9 | "react-dom": "0.14.7",
10 | "whatwg-fetch": "0.11.0",
11 | "react-router": "2.0.1",
12 | "react-redux": "4.4.1",
13 | "redux": "3.3.1",
14 | "react-router-redux": "4.0.0",
15 | "redux-thunk": "2.0.1"
16 | },
17 | "devDependencies": {
18 | "apidoc": "0.15.1",
19 | "babel-loader": "6.2.4",
20 | "babel-preset-es2015": "6.6.0",
21 | "babel-preset-react": "6.5.0",
22 | "babel-register": "6.7.2",
23 | "chai": "3.5.0",
24 | "eslint": "2.4.0",
25 | "eslint-plugin-react": "4.2.3",
26 | "jsdom": "8.1.0",
27 | "mocha": "2.4.5",
28 | "react-addons-test-utils": "0.14.7",
29 | "redux-devtools": "3.1.1",
30 | "redux-devtools-dock-monitor": "1.1.0",
31 | "redux-devtools-log-monitor": "1.0.5",
32 | "webpack": "1.12.14",
33 | "webpack-dev-server": "1.14.1",
34 | "enzyme": "2.2.0",
35 | "sinon": "1.17.3"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | APP_PATH=`pwd`
4 |
5 | STEPS=`find $APP_PATH -type d -name "step-*"`
6 |
7 | for item in ${STEPS}
8 | do
9 | if [ -f "$item/package.json" ];
10 | then
11 | cd "$item"
12 | echo "fetching dependencies for $item"
13 | npm install
14 | else
15 | echo "nothing to do for $item"
16 | fi
17 | done
18 |
19 | cd "$APP_PATH/api"
20 | echo "fetching dependencies for the Wine API"
21 | npm install
22 |
23 | cd "$APP_PATH"
24 |
--------------------------------------------------------------------------------
/print/pdf/all.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/print/pdf/all.pdf
--------------------------------------------------------------------------------
/print/pdf/index.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/print/pdf/index.pdf
--------------------------------------------------------------------------------
/print/pdf/step-0.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/print/pdf/step-0.pdf
--------------------------------------------------------------------------------
/print/pdf/step-1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/print/pdf/step-1.pdf
--------------------------------------------------------------------------------
/print/pdf/step-2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/print/pdf/step-2.pdf
--------------------------------------------------------------------------------
/print/pdf/step-3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/print/pdf/step-3.pdf
--------------------------------------------------------------------------------
/print/pdf/step-4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/print/pdf/step-4.pdf
--------------------------------------------------------------------------------
/print/pdf/step-5.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/print/pdf/step-5.pdf
--------------------------------------------------------------------------------
/print/pdf/step-6.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/print/pdf/step-6.pdf
--------------------------------------------------------------------------------
/print/pdf/step-7.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/print/pdf/step-7.pdf
--------------------------------------------------------------------------------
/print/pdf/step-8.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/print/pdf/step-8.pdf
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # React Workshop
2 |
3 | Le workshop a été déplacé [dans l'organisation react-bootcamp](https://github.com/react-bootcamp/react-workshop)
4 |
--------------------------------------------------------------------------------
/step-0-done/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/step-0-done/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | webpack.config.js
3 | public
4 | README.md
5 |
--------------------------------------------------------------------------------
/step-0-done/.gitignore:
--------------------------------------------------------------------------------
1 | # Node.js
2 | node_modules
3 | npm-debug.log
4 |
5 | # Bundles
6 | bundle.js
7 | bundle.js.map
8 |
--------------------------------------------------------------------------------
/step-0-done/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-workshop",
3 | "description": "React Workshop",
4 | "version": "0.1.0",
5 | "dependencies": {
6 | "react": "0.14.7",
7 | "react-dom": "0.14.7"
8 | },
9 | "devDependencies": {
10 | "babel-loader": "6.2.4",
11 | "babel-preset-es2015": "6.6.0",
12 | "babel-preset-react": "6.5.0",
13 | "babel-register": "6.7.2",
14 | "eslint": "2.4.0",
15 | "eslint-plugin-react": "4.2.3",
16 | "webpack": "1.12.14",
17 | "webpack-dev-server": "1.14.1"
18 | },
19 | "scripts": {
20 | "lint": "eslint src",
21 | "bundle": "webpack -p --colors --progress",
22 | "start": "webpack-dev-server -d --colors --inline --content-base public",
23 | "build": "npm run lint && npm run bundle"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/step-0-done/public/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: 'Roboto', sans-serif;
3 | }
4 |
--------------------------------------------------------------------------------
/step-0-done/public/img/chevrol-bel-air.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-0-done/public/img/chevrol-bel-air.png
--------------------------------------------------------------------------------
/step-0-done/public/img/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-0-done/public/img/react.png
--------------------------------------------------------------------------------
/step-0-done/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React Workshop
6 |
7 |
8 |
9 |
10 |
11 | Wines
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/step-0-done/public/js/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-0-done/public/js/.gitkeep
--------------------------------------------------------------------------------
/step-0-done/readme.md:
--------------------------------------------------------------------------------
1 | # Etape 0
2 |
3 | Ce dossier contient la version finale de [l'étape 0]('../step-0')
4 |
--------------------------------------------------------------------------------
/step-0-done/src/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | import Wine from './components/wine';
5 |
6 | ReactDOM.render(
7 | ,
8 | document.getElementById('main')
9 | );
10 |
--------------------------------------------------------------------------------
/step-0-done/src/components/wine.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const WineStyle = {
4 | padding: 8,
5 | boxShadow: '0 1px 6px rgba(0,0,0,0.12), 0 1px 4px rgba(0,0,0,0.12)'
6 | };
7 |
8 | const Wine = React.createClass({
9 | propTypes: {
10 | name: React.PropTypes.string
11 | },
12 |
13 | render() {
14 | return (
15 |
16 | {this.props.name}
17 |
18 | );
19 | }
20 | });
21 |
22 | export default Wine;
23 |
--------------------------------------------------------------------------------
/step-0-done/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 |
3 | module.exports = {
4 | output: {
5 | path: './public/js/',
6 | publicPath: '/js/',
7 | filename: 'bundle.js'
8 | },
9 | entry: {
10 | app: ['./src/app.js']
11 | },
12 | resolve: {
13 | extensions: ['', '.js', '.jsx']
14 | },
15 | module: {
16 | loaders: [
17 | {
18 | test: /\.js$/,
19 | exclude: /node_modules/,
20 | loader: 'babel'
21 | }
22 | ]
23 | },
24 | devServer: {
25 | historyApiFallback: true,
26 | proxy: {
27 | '/api/*': {
28 | target: 'http://localhost:3000'
29 | }
30 | }
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/step-1-done/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/step-1-done/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | webpack.config.js
3 | public
4 | README.md
5 |
--------------------------------------------------------------------------------
/step-1-done/.gitignore:
--------------------------------------------------------------------------------
1 | # Node.js
2 | node_modules
3 | npm-debug.log
4 |
5 | # Bundles
6 | bundle.js
7 | bundle.js.map
8 |
--------------------------------------------------------------------------------
/step-1-done/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-workshop",
3 | "description": "React Workshop",
4 | "version": "0.1.0",
5 | "dependencies": {
6 | "react": "0.14.7",
7 | "react-dom": "0.14.7"
8 | },
9 | "devDependencies": {
10 | "babel-loader": "6.2.4",
11 | "babel-preset-es2015": "6.6.0",
12 | "babel-preset-react": "6.5.0",
13 | "babel-register": "6.7.2",
14 | "chai": "3.5.0",
15 | "eslint": "2.4.0",
16 | "eslint-plugin-react": "4.2.3",
17 | "jsdom": "8.1.0",
18 | "mocha": "2.4.5",
19 | "react-addons-test-utils": "0.14.7",
20 | "webpack": "1.12.14",
21 | "webpack-dev-server": "1.14.1"
22 | },
23 | "scripts": {
24 | "lint": "eslint src tests",
25 | "test": "mocha --compilers js:babel-register tests/index.js",
26 | "bundle": "webpack -p --colors --progress",
27 | "start": "webpack-dev-server -d --colors --inline --content-base public",
28 | "build": "npm run test && npm run lint && npm run bundle"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/step-1-done/public/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: 'Roboto', sans-serif;
3 | }
4 |
--------------------------------------------------------------------------------
/step-1-done/public/img/chevrol-bel-air.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-1-done/public/img/chevrol-bel-air.png
--------------------------------------------------------------------------------
/step-1-done/public/img/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-1-done/public/img/react.png
--------------------------------------------------------------------------------
/step-1-done/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React Workshop
6 |
7 |
8 |
9 |
10 |
11 | Wines
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/step-1-done/public/js/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-1-done/public/js/.gitkeep
--------------------------------------------------------------------------------
/step-1-done/readme.md:
--------------------------------------------------------------------------------
1 | # Etape 1
2 |
3 | Ce dossier contient la version finale de [l'étape 1]('../step-1')
4 |
--------------------------------------------------------------------------------
/step-1-done/src/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | import Wine from './components/wine';
5 |
6 | ReactDOM.render(
7 | ,
8 | document.getElementById('main')
9 | );
10 |
--------------------------------------------------------------------------------
/step-1-done/src/components/wine.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const WineStyle = {
4 | padding: 8,
5 | boxShadow: '0 1px 6px rgba(0,0,0,0.12), 0 1px 4px rgba(0,0,0,0.12)'
6 | };
7 |
8 | const Wine = React.createClass({
9 | propTypes: {
10 | name: React.PropTypes.string
11 | },
12 |
13 | render() {
14 | return (
15 |
16 | {this.props.name}
17 |
18 | );
19 | }
20 | });
21 |
22 | export default Wine;
23 |
--------------------------------------------------------------------------------
/step-1-done/tests/bootstrap.js:
--------------------------------------------------------------------------------
1 | /* eslint no-console: 0 */
2 |
3 | import jsdom from 'jsdom';
4 |
5 | export function bootstrapEnv(body = '') {
6 | const doc = jsdom.jsdom(`${body}`);
7 | const win = doc.defaultView;
8 | function propagateToGlobal(window) {
9 | for (const key in window) {
10 | if (!window.hasOwnProperty(key)) continue;
11 | if (key in global) continue;
12 | global[key] = window[key];
13 | }
14 | }
15 | global.document = doc;
16 | global.window = win;
17 | propagateToGlobal(win);
18 | console.log('\nENV setup is done !!!');
19 | }
20 |
--------------------------------------------------------------------------------
/step-1-done/tests/components/wine.spec.js:
--------------------------------------------------------------------------------
1 | /* eslint no-undef:0 */
2 |
3 | import React from 'react';
4 | import { expect } from 'chai';
5 | import ReactTestUtils from 'react-addons-test-utils';
6 |
7 | import Wine from '../../src/components/wine';
8 |
9 | describe('Wine', () => {
10 | it('affiche le nom du vin', () => {
11 | const wine = ReactTestUtils.renderIntoDocument();
12 | const div = ReactTestUtils.findRenderedDOMComponentWithTag(wine, 'div');
13 | expect(div.textContent).to.be.equal('Un bon Bourgogne');
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/step-1-done/tests/index.js:
--------------------------------------------------------------------------------
1 | /* eslint no-unused-vars:0, no-console: 0 */
2 |
3 | import { bootstrapEnv } from './bootstrap';
4 |
5 | bootstrapEnv();
6 |
7 | console.log('===================================================================\n');
8 | console.log('If you want to run other tests, don\'t forget ton include them in the "tests" array.');
9 | console.log('of $ROOT/tests/index.js)');
10 | console.log('\n===================================================================\n');
11 |
12 | const tests = [
13 | require('./components/wine.spec.js')
14 | ];
15 |
--------------------------------------------------------------------------------
/step-1-done/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 |
3 | module.exports = {
4 | output: {
5 | path: './public/js/',
6 | publicPath: '/js/',
7 | filename: 'bundle.js'
8 | },
9 | entry: {
10 | app: ['./src/app.js']
11 | },
12 | resolve: {
13 | extensions: ['', '.js', '.jsx']
14 | },
15 | module: {
16 | loaders: [
17 | {
18 | test: /\.js$/,
19 | exclude: /node_modules/,
20 | loader: 'babel'
21 | }
22 | ]
23 | },
24 | devServer: {
25 | historyApiFallback: true,
26 | proxy: {
27 | '/api/*': {
28 | target: 'http://localhost:3000'
29 | }
30 | }
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/step-1/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/step-1/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | webpack.config.js
3 | public
4 | README.md
5 |
--------------------------------------------------------------------------------
/step-1/.gitignore:
--------------------------------------------------------------------------------
1 | # Node.js
2 | node_modules
3 | npm-debug.log
4 |
5 | # Bundles
6 | bundle.js
7 | bundle.js.map
8 |
--------------------------------------------------------------------------------
/step-1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-workshop",
3 | "description": "React Workshop",
4 | "version": "0.1.0",
5 | "dependencies": {
6 | "react": "0.14.7",
7 | "react-dom": "0.14.7"
8 | },
9 | "devDependencies": {
10 | "babel-loader": "6.2.4",
11 | "babel-preset-es2015": "6.6.0",
12 | "babel-preset-react": "6.5.0",
13 | "babel-register": "6.7.2",
14 | "chai": "3.5.0",
15 | "eslint": "2.4.0",
16 | "eslint-plugin-react": "4.2.3",
17 | "jsdom": "8.1.0",
18 | "mocha": "2.4.5",
19 | "react-addons-test-utils": "0.14.7",
20 | "webpack": "1.12.14",
21 | "webpack-dev-server": "1.14.1"
22 | },
23 | "scripts": {
24 | "lint": "eslint src tests",
25 | "test": "mocha --compilers js:babel-register tests/index.js",
26 | "bundle": "webpack -p --colors --progress",
27 | "start": "webpack-dev-server -d --colors --inline --content-base public",
28 | "build": "npm run test && npm run lint && npm run bundle"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/step-1/public/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: 'Roboto', sans-serif;
3 | }
4 |
--------------------------------------------------------------------------------
/step-1/public/img/chevrol-bel-air.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-1/public/img/chevrol-bel-air.png
--------------------------------------------------------------------------------
/step-1/public/img/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-1/public/img/react.png
--------------------------------------------------------------------------------
/step-1/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React Workshop
6 |
7 |
8 |
9 |
10 |
11 | Wines
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/step-1/public/js/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-1/public/js/.gitkeep
--------------------------------------------------------------------------------
/step-1/src/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | import Wine from './components/wine';
5 |
6 | ReactDOM.render(
7 | ,
8 | document.getElementById('main')
9 | );
10 |
--------------------------------------------------------------------------------
/step-1/src/components/wine.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const WineStyle = {
4 | padding: 8,
5 | boxShadow: '0 1px 6px rgba(0,0,0,0.12), 0 1px 4px rgba(0,0,0,0.12)'
6 | };
7 |
8 | const Wine = React.createClass({
9 | propTypes: {
10 | name: React.PropTypes.string
11 | },
12 |
13 | render() {
14 | return (
15 |
16 | {this.props.name}
17 |
18 | );
19 | }
20 | });
21 |
22 | export default Wine;
23 |
--------------------------------------------------------------------------------
/step-1/tests/bootstrap.js:
--------------------------------------------------------------------------------
1 | import jsdom from 'jsdom';
2 |
3 | export function bootstrapEnv(body = '') {
4 | const doc = jsdom.jsdom(`${body}`);
5 | const win = doc.defaultView;
6 | function propagateToGlobal(window) {
7 | for (const key in window) {
8 | if (!window.hasOwnProperty(key)) continue;
9 | if (key in global) continue;
10 | global[key] = window[key];
11 | }
12 | }
13 | global.document = doc;
14 | global.window = win;
15 | propagateToGlobal(win);
16 | console.log('\nENV setup is done !!!');
17 | }
18 |
--------------------------------------------------------------------------------
/step-1/tests/index.js:
--------------------------------------------------------------------------------
1 | import { bootstrapEnv } from './bootstrap';
2 |
3 | bootstrapEnv();
4 |
5 | const tests = [
6 | // TODO : add you tests here !!!
7 | ];
8 |
--------------------------------------------------------------------------------
/step-1/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 |
3 | module.exports = {
4 | output: {
5 | path: './public/js/',
6 | publicPath: '/js/',
7 | filename: 'bundle.js'
8 | },
9 | entry: {
10 | app: ['./src/app.js']
11 | },
12 | resolve: {
13 | extensions: ['', '.js', '.jsx']
14 | },
15 | module: {
16 | loaders: [
17 | {
18 | test: /\.js$/,
19 | exclude: /node_modules/,
20 | loader: 'babel'
21 | }
22 | ]
23 | },
24 | devServer: {
25 | historyApiFallback: true,
26 | proxy: {
27 | '/api/*': {
28 | target: 'http://localhost:3000'
29 | }
30 | }
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/step-2-done/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/step-2-done/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | webpack.config.js
3 | public
4 | README.md
5 |
--------------------------------------------------------------------------------
/step-2-done/.gitignore:
--------------------------------------------------------------------------------
1 | # Node.js
2 | node_modules
3 | npm-debug.log
4 |
5 | # Bundles
6 | bundle.js
7 | bundle.js.map
8 |
--------------------------------------------------------------------------------
/step-2-done/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-workshop",
3 | "description": "React Workshop",
4 | "version": "0.1.0",
5 | "dependencies": {
6 | "react": "0.14.7",
7 | "react-dom": "0.14.7",
8 | "whatwg-fetch": "0.11.0"
9 | },
10 | "devDependencies": {
11 | "babel-loader": "6.2.4",
12 | "babel-preset-es2015": "6.6.0",
13 | "babel-preset-react": "6.5.0",
14 | "babel-register": "6.7.2",
15 | "chai": "3.5.0",
16 | "enzyme": "2.2.0",
17 | "eslint": "2.4.0",
18 | "eslint-plugin-react": "4.2.3",
19 | "jsdom": "8.1.0",
20 | "mocha": "2.4.5",
21 | "react-addons-test-utils": "0.14.7",
22 | "sinon": "1.17.3",
23 | "webpack": "1.12.14",
24 | "webpack-dev-server": "1.14.1"
25 | },
26 | "scripts": {
27 | "lint": "eslint src",
28 | "test": "mocha --compilers js:babel-register tests/index.js",
29 | "bundle": "webpack -p --colors --progress",
30 | "start": "webpack-dev-server -d --colors --inline --content-base public",
31 | "build": "npm run lint && npm run bundle"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/step-2-done/public/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: 'Roboto', sans-serif;
3 | }
4 |
--------------------------------------------------------------------------------
/step-2-done/public/img/chevrol-bel-air.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-2-done/public/img/chevrol-bel-air.png
--------------------------------------------------------------------------------
/step-2-done/public/img/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-2-done/public/img/react.png
--------------------------------------------------------------------------------
/step-2-done/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React Workshop
6 |
7 |
8 |
9 |
10 |
11 |
12 | Wines
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/step-2-done/public/js/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-2-done/public/js/.gitkeep
--------------------------------------------------------------------------------
/step-2-done/readme.md:
--------------------------------------------------------------------------------
1 | # Etape 2
2 |
3 | Ce dossier contient la version finale de [l'étape 2]('../step-2')
4 |
--------------------------------------------------------------------------------
/step-2-done/src/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | import WineApp from './components/wine-app';
5 |
6 | ReactDOM.render(
7 | ,
8 | document.getElementById('main')
9 | );
10 |
--------------------------------------------------------------------------------
/step-2-done/src/components/regions.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 |
3 | const computeRegionStyle = function(region, selected) {
4 | let style = {
5 | padding: 16
6 | };
7 | if (region === selected) {
8 | style['fontWeight'] = 'bold';
9 | style['backgroundColor'] = 'lightGrey';
10 | }
11 | return style;
12 | }
13 |
14 | const Regions = React.createClass({
15 | propTypes: {
16 | onRegionChange: PropTypes.func,
17 | regions: PropTypes.arrayOf(PropTypes.string),
18 | selected: PropTypes.string
19 | },
20 |
21 | handleRegionClick(event) {
22 | this.props.onRegionChange(event.target.textContent);
23 | },
24 |
25 | render () {
26 | return (
27 |
28 | {
29 | this.props.regions.map(region =>
30 |
34 | {region}
35 |
36 | )
37 | }
38 |
39 | )
40 | }
41 | })
42 |
43 | export default Regions
44 |
--------------------------------------------------------------------------------
/step-2-done/tests/bootstrap.js:
--------------------------------------------------------------------------------
1 | /* eslint no-console: 0 */
2 |
3 | import jsdom from 'jsdom';
4 |
5 | export function bootstrapEnv(body = '') {
6 | const doc = jsdom.jsdom(`${body}`);
7 | const win = doc.defaultView;
8 | function propagateToGlobal(window) {
9 | for (const key in window) {
10 | if (!window.hasOwnProperty(key)) continue;
11 | if (key in global) continue;
12 | global[key] = window[key];
13 | }
14 | }
15 | global.document = doc;
16 | global.window = win;
17 | propagateToGlobal(win);
18 | // console.log('\nENV setup is done !!!');
19 | }
20 |
--------------------------------------------------------------------------------
/step-2-done/tests/index.js:
--------------------------------------------------------------------------------
1 | /* eslint no-unused-vars:0, no-console: 0 */
2 |
3 | import { bootstrapEnv } from './bootstrap';
4 |
5 | bootstrapEnv();
6 |
7 | require('./components/regions.spec.js')
8 | require('./components/wine-list.spec.js')
9 | require('./components/wine.spec.js')
10 | require('./components/wine-app.spec.js')
11 |
--------------------------------------------------------------------------------
/step-2-done/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 |
3 | module.exports = {
4 | output: {
5 | path: './public/js/',
6 | publicPath: '/js/',
7 | filename: 'bundle.js'
8 | },
9 | entry: {
10 | app: ['./src/app.js']
11 | },
12 | resolve: {
13 | extensions: ['', '.js', '.jsx']
14 | },
15 | module: {
16 | loaders: [
17 | {
18 | test: /\.js$/,
19 | exclude: /node_modules/,
20 | loader: 'babel'
21 | }
22 | ]
23 | },
24 | devServer: {
25 | historyApiFallback: true,
26 | proxy: {
27 | '/api/*': {
28 | target: 'http://localhost:3000'
29 | }
30 | }
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/step-2/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/step-2/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | webpack.config.js
3 | public
4 | README.md
5 |
--------------------------------------------------------------------------------
/step-2/.gitignore:
--------------------------------------------------------------------------------
1 | # Node.js
2 | node_modules
3 | npm-debug.log
4 |
5 | # Bundles
6 | bundle.js
7 | bundle.js.map
8 |
--------------------------------------------------------------------------------
/step-2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-workshop",
3 | "description": "React Workshop",
4 | "version": "0.1.0",
5 | "dependencies": {
6 | "react": "0.14.7",
7 | "react-dom": "0.14.7",
8 | "whatwg-fetch": "0.11.0"
9 | },
10 | "devDependencies": {
11 | "babel-loader": "6.2.4",
12 | "babel-preset-es2015": "6.6.0",
13 | "babel-preset-react": "6.5.0",
14 | "babel-register": "6.7.2",
15 | "chai": "3.5.0",
16 | "eslint": "2.4.0",
17 | "eslint-plugin-react": "4.2.3",
18 | "enzyme": "2.2.0",
19 | "jsdom": "8.1.0",
20 | "mocha": "2.4.5",
21 | "react-addons-test-utils": "0.14.7",
22 | "sinon": "1.17.3",
23 | "webpack": "1.12.14",
24 | "webpack-dev-server": "1.14.1"
25 | },
26 | "scripts": {
27 | "lint": "eslint src",
28 | "test": "mocha --compilers js:babel-register tests/index.js",
29 | "bundle": "webpack -p --colors --progress",
30 | "start": "webpack-dev-server -d --colors --inline --content-base public",
31 | "build": "npm run lint && npm run bundle"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/step-2/public/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: 'Roboto', sans-serif;
3 | }
4 |
--------------------------------------------------------------------------------
/step-2/public/img/chevrol-bel-air.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-2/public/img/chevrol-bel-air.png
--------------------------------------------------------------------------------
/step-2/public/img/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-2/public/img/react.png
--------------------------------------------------------------------------------
/step-2/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React Workshop
6 |
7 |
8 |
9 |
10 |
11 |
12 | Wines
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/step-2/public/js/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-2/public/js/.gitkeep
--------------------------------------------------------------------------------
/step-2/src/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | import WineApp from './components/wine-app';
5 |
6 | ReactDOM.render(
7 | ,
8 | document.getElementById('main')
9 | );
10 |
--------------------------------------------------------------------------------
/step-2/src/components/regions.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'; // eslint-disable-line
2 |
3 | // vous devriez utiliser cette fonction pour le style de chaque région
4 | function computeRegionStyle(region, selected) { // eslint-disable-line
5 | let style = {
6 | padding: 16
7 | };
8 | if (region === selected) {
9 | style['fontWeight'] = 'bold';
10 | style['backgroundColor'] = 'lightGrey';
11 | }
12 | return style;
13 | }
14 |
15 | const Regions = React.createClass({
16 | render () {
17 | return (
18 |
19 |
TODO : Regions
20 |
21 | )
22 | }
23 | })
24 |
25 | export default Regions
26 |
--------------------------------------------------------------------------------
/step-2/src/components/wine-app.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'; // eslint-disable-line
2 |
3 | const WineApp = React.createClass({
4 | render () {
5 | return (
6 |
7 |
8 |
Regions
9 | ...
10 |
11 |
12 |
Wine List
13 | ...
14 |
15 |
16 |
Wine Description
17 | ...
18 |
19 |
20 | )
21 | }
22 | })
23 |
24 | export default WineApp
25 |
--------------------------------------------------------------------------------
/step-2/src/components/wine-list.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'; // eslint-disable-line
2 |
3 | // vous devriez utiliser cette fonction pour le style de chaque région
4 | function computeWineStyle(region, selected) { // eslint-disable-line
5 | let style = {
6 | padding: 16
7 | };
8 | if (region === selected) {
9 | style['fontWeight'] = 'bold';
10 | style['backgroundColor'] = 'lightGrey';
11 | }
12 | return style;
13 | }
14 |
15 | const WineList = React.createClass({
16 | render () {
17 | return (
18 |
19 |
TODO : WineList
20 |
21 | )
22 | }
23 | })
24 |
25 | export default WineList
26 |
--------------------------------------------------------------------------------
/step-2/src/components/wine.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const WineStyle = {
4 | padding: 8,
5 | boxShadow: '0 1px 6px rgba(0,0,0,0.12), 0 1px 4px rgba(0,0,0,0.12)'
6 | };
7 |
8 | const Styles = { // eslint-disable-line
9 | Card: {
10 | padding: 8,
11 | boxSizing: 'border-box',
12 | boxShadow: '0 1px 6px rgba(0,0,0,0.12), 0 1px 4px rgba(0,0,0,0.12)',
13 | minHeight: 280
14 | },
15 | Title: {
16 | fontWeight: 'bold',
17 | fontSize: '1.2em'
18 | },
19 | Info: {
20 | marginTop: 16,
21 | marginBottom: 16
22 | },
23 | Label: {
24 | color: 'white',
25 | marginRight: 8,
26 | padding: 4,
27 | background: 'grey',
28 | borderRadius: '4px'
29 | },
30 | Image: {
31 | float: 'left'
32 | }
33 | };
34 |
35 | const Wine = React.createClass({
36 | propTypes: {
37 | name: React.PropTypes.string
38 | },
39 |
40 | render() {
41 | return (
42 |
43 | {this.props.name}
44 |
45 | );
46 | }
47 | });
48 |
49 | export default Wine;
50 |
--------------------------------------------------------------------------------
/step-2/tests/bootstrap.js:
--------------------------------------------------------------------------------
1 | /* eslint no-console: 0 */
2 |
3 | import jsdom from 'jsdom';
4 |
5 | export function bootstrapEnv(body = '') {
6 | const doc = jsdom.jsdom(`${body}`);
7 | const win = doc.defaultView;
8 | function propagateToGlobal(window) {
9 | for (const key in window) {
10 | if (!window.hasOwnProperty(key)) continue;
11 | if (key in global) continue;
12 | global[key] = window[key];
13 | }
14 | }
15 | global.document = doc;
16 | global.window = win;
17 | propagateToGlobal(win);
18 | // console.log('\nENV setup is done !!!');
19 | }
20 |
--------------------------------------------------------------------------------
/step-2/tests/index.js:
--------------------------------------------------------------------------------
1 | /* eslint no-unused-vars:0, no-console: 0 */
2 |
3 | import { bootstrapEnv } from './bootstrap';
4 |
5 | bootstrapEnv();
6 |
7 | require('./components/regions.spec.js')
8 | require('./components/wine-list.spec.js')
9 | require('./components/wine.spec.js')
10 | require('./components/wine-app.spec.js')
11 |
--------------------------------------------------------------------------------
/step-2/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 |
3 | module.exports = {
4 | output: {
5 | path: './public/js/',
6 | publicPath: '/js/',
7 | filename: 'bundle.js'
8 | },
9 | entry: {
10 | app: ['./src/app.js']
11 | },
12 | resolve: {
13 | extensions: ['', '.js', '.jsx']
14 | },
15 | module: {
16 | loaders: [
17 | {
18 | test: /\.js$/,
19 | exclude: /node_modules/,
20 | loader: 'babel'
21 | }
22 | ]
23 | },
24 | devServer: {
25 | historyApiFallback: true,
26 | proxy: {
27 | '/api/*': {
28 | target: 'http://localhost:3000'
29 | }
30 | }
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/step-2/wines-components.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-2/wines-components.png
--------------------------------------------------------------------------------
/step-2/wines.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-2/wines.png
--------------------------------------------------------------------------------
/step-3-done/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/step-3-done/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | webpack.config.js
3 | public
4 | README.md
5 |
--------------------------------------------------------------------------------
/step-3-done/.gitignore:
--------------------------------------------------------------------------------
1 | # Node.js
2 | node_modules
3 | npm-debug.log
4 |
5 | # Bundles
6 | bundle.js
7 | bundle.js.map
8 |
--------------------------------------------------------------------------------
/step-3-done/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-workshop",
3 | "description": "React Workshop",
4 | "version": "0.1.0",
5 | "dependencies": {
6 | "react": "0.14.7",
7 | "react-dom": "0.14.7",
8 | "react-router": "2.0.1",
9 | "whatwg-fetch": "0.11.0"
10 | },
11 | "devDependencies": {
12 | "babel-loader": "6.2.4",
13 | "babel-preset-es2015": "6.6.0",
14 | "babel-preset-react": "6.5.0",
15 | "babel-register": "6.7.2",
16 | "chai": "3.5.0",
17 | "enzyme": "2.2.0",
18 | "eslint": "2.4.0",
19 | "eslint-plugin-react": "4.2.3",
20 | "jsdom": "8.1.0",
21 | "mocha": "2.4.5",
22 | "react-addons-test-utils": "0.14.7",
23 | "sinon": "1.17.3",
24 | "webpack": "1.12.14",
25 | "webpack-dev-server": "1.14.1"
26 | },
27 | "scripts": {
28 | "lint": "eslint src",
29 | "test": "mocha --compilers js:babel-register tests/index.js",
30 | "bundle": "webpack -p --colors --progress",
31 | "start": "webpack-dev-server -d --colors --inline --content-base public",
32 | "build": "npm run lint && npm run bundle"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/step-3-done/public/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: 'Roboto', sans-serif;
3 | }
4 |
--------------------------------------------------------------------------------
/step-3-done/public/img/chevrol-bel-air.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-3-done/public/img/chevrol-bel-air.png
--------------------------------------------------------------------------------
/step-3-done/public/img/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-3-done/public/img/react.png
--------------------------------------------------------------------------------
/step-3-done/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React Workshop
6 |
7 |
8 |
9 |
10 |
11 |
12 | Wines
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/step-3-done/public/js/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-3-done/public/js/.gitkeep
--------------------------------------------------------------------------------
/step-3-done/readme.md:
--------------------------------------------------------------------------------
1 | # Etape 3
2 |
3 | Ce dossier contient la version finale de [l'étape 3]('../step-3')
4 |
--------------------------------------------------------------------------------
/step-3-done/src/app.js:
--------------------------------------------------------------------------------
1 | /* eslint react/jsx-max-props-per-line: 0 */
2 |
3 | import 'whatwg-fetch';
4 |
5 | import React, { PropTypes } from 'react';
6 |
7 | import WineApp from './components/wine-app';
8 | import { RegionsPage } from './components/regions';
9 | import { WineListPage } from './components/wine-list';
10 | import { WinePage } from './components/wine';
11 | import { NotFound } from './components/not-found';
12 |
13 | import { Router, Route, browserHistory, IndexRoute } from 'react-router';
14 |
15 | export const App = React.createClass({
16 | propTypes: {
17 | history: PropTypes.object, // eslint-disable-line
18 | },
19 | render() {
20 | const history = this.props.history || browserHistory;
21 | return (
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | );
31 | }
32 | });
33 |
--------------------------------------------------------------------------------
/step-3-done/src/components/not-found.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export const NotFound = React.createClass({
4 | render() {
5 | return (
6 | Il semble que vous n'êtes pas au bon endroit !!!
7 | );
8 | }
9 | });
10 |
--------------------------------------------------------------------------------
/step-3-done/src/components/wine-app.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 |
3 | const WineApp = React.createClass({
4 |
5 | propTypes: {
6 | children: PropTypes.element
7 | },
8 |
9 | contextTypes: {
10 | router: React.PropTypes.object
11 | },
12 |
13 | getInitialState() {
14 | return {
15 | title: ''
16 | };
17 | },
18 |
19 | setTitle(title) {
20 | this.setState({ title });
21 | },
22 |
23 | goBack() {
24 | this.context.router.goBack();
25 | },
26 |
27 | render () {
28 | return (
29 |
30 |
31 |
{this.state.title}
32 | {this.props.children && React.cloneElement(this.props.children, {
33 | setTitle: this.setTitle
34 | })}
35 |
36 |
37 | );
38 | }
39 | })
40 |
41 | export default WineApp
42 |
--------------------------------------------------------------------------------
/step-3-done/src/index.js:
--------------------------------------------------------------------------------
1 | import 'whatwg-fetch';
2 |
3 | import React from 'react';
4 | import ReactDOM from 'react-dom';
5 |
6 | import { App } from './app';
7 |
8 | ReactDOM.render(, document.getElementById('main'));
9 |
--------------------------------------------------------------------------------
/step-3-done/tests/bootstrap.js:
--------------------------------------------------------------------------------
1 | /* eslint no-console: 0 */
2 |
3 | import jsdom from 'jsdom';
4 |
5 | export function bootstrapEnv(body = '') {
6 | const doc = jsdom.jsdom(`${body}`);
7 | const win = doc.defaultView;
8 | function propagateToGlobal(window) {
9 | for (const key in window) {
10 | if (!window.hasOwnProperty(key)) continue;
11 | if (key in global) continue;
12 | global[key] = window[key];
13 | }
14 | }
15 | global.document = doc;
16 | global.window = win;
17 | propagateToGlobal(win);
18 | // console.log('\nENV setup is done !!!');
19 | }
20 |
--------------------------------------------------------------------------------
/step-3-done/tests/index.js:
--------------------------------------------------------------------------------
1 | /* eslint no-unused-vars:0, no-console: 0 */
2 |
3 | import { bootstrapEnv } from './bootstrap';
4 |
5 | bootstrapEnv();
6 |
7 | require('./components/regions.spec.js')
8 | require('./components/wine-list.spec.js')
9 | require('./components/wine.spec.js')
10 | require('./components/wine-app.spec.js')
11 |
--------------------------------------------------------------------------------
/step-3-done/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 |
3 | module.exports = {
4 | output: {
5 | path: './public/js/',
6 | publicPath: '/js/',
7 | filename: 'bundle.js'
8 | },
9 | entry: {
10 | app: ['./src/index.js']
11 | },
12 | resolve: {
13 | extensions: ['', '.js', '.jsx']
14 | },
15 | module: {
16 | loaders: [
17 | {
18 | test: /\.js$/,
19 | exclude: /node_modules/,
20 | loader: 'babel'
21 | }
22 | ]
23 | },
24 | devServer: {
25 | historyApiFallback: true,
26 | proxy: {
27 | '/api/*': {
28 | target: 'http://localhost:3000'
29 | }
30 | }
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/step-3/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/step-3/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | webpack.config.js
3 | public
4 | README.md
5 |
--------------------------------------------------------------------------------
/step-3/.gitignore:
--------------------------------------------------------------------------------
1 | # Node.js
2 | node_modules
3 | npm-debug.log
4 |
5 | # Bundles
6 | bundle.js
7 | bundle.js.map
8 |
--------------------------------------------------------------------------------
/step-3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-workshop",
3 | "description": "React Workshop",
4 | "version": "0.1.0",
5 | "dependencies": {
6 | "react": "0.14.7",
7 | "react-dom": "0.14.7",
8 | "react-router": "2.0.1",
9 | "whatwg-fetch": "0.11.0"
10 | },
11 | "devDependencies": {
12 | "babel-loader": "6.2.4",
13 | "babel-preset-es2015": "6.6.0",
14 | "babel-preset-react": "6.5.0",
15 | "babel-register": "6.7.2",
16 | "chai": "3.5.0",
17 | "enzyme": "2.2.0",
18 | "eslint": "2.4.0",
19 | "eslint-plugin-react": "4.2.3",
20 | "jsdom": "8.1.0",
21 | "mocha": "2.4.5",
22 | "react-addons-test-utils": "0.14.7",
23 | "sinon": "1.17.3",
24 | "webpack": "1.12.14",
25 | "webpack-dev-server": "1.14.1"
26 | },
27 | "scripts": {
28 | "lint": "eslint src",
29 | "test": "mocha --compilers js:babel-register tests/index.js",
30 | "bundle": "webpack -p --colors --progress",
31 | "start": "webpack-dev-server -d --colors --inline --content-base public",
32 | "build": "npm run lint && npm run bundle"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/step-3/public/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: 'Roboto', sans-serif;
3 | }
4 |
--------------------------------------------------------------------------------
/step-3/public/img/chevrol-bel-air.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-3/public/img/chevrol-bel-air.png
--------------------------------------------------------------------------------
/step-3/public/img/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-3/public/img/react.png
--------------------------------------------------------------------------------
/step-3/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React Workshop
6 |
7 |
8 |
9 |
10 |
11 |
12 | Wines
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/step-3/public/js/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-3/public/js/.gitkeep
--------------------------------------------------------------------------------
/step-3/src/app.js:
--------------------------------------------------------------------------------
1 | /* eslint react/jsx-max-props-per-line: 0 */
2 |
3 | import 'whatwg-fetch';
4 |
5 | import React, { PropTypes } from 'react';
6 |
7 | import WineApp from './components/wine-app';
8 | import { RegionsPage } from './components/regions';
9 | import { WineListPage } from './components/wine-list';
10 | import { WinePage } from './components/wine';
11 | import { NotFound } from './components/not-found';
12 |
13 | import { Router, Route, browserHistory, IndexRoute } from 'react-router';
14 |
15 | export const App = React.createClass({
16 | propTypes: {
17 | history: PropTypes.object, // eslint-disable-line
18 | },
19 | render() {
20 | const history = this.props.history || browserHistory;
21 | return (
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | );
31 | }
32 | });
33 |
--------------------------------------------------------------------------------
/step-3/src/components/not-found.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export const NotFound = React.createClass({
4 | render() {
5 | return (
6 | TODO : NotFound
7 | );
8 | }
9 | });
10 |
--------------------------------------------------------------------------------
/step-3/src/components/wine-app.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const WineApp = React.createClass({
4 | render () {
5 | return (
6 |
7 |
8 | {this.props.children}
9 |
10 |
11 | );
12 | }
13 | })
14 |
15 | export default WineApp
16 |
--------------------------------------------------------------------------------
/step-3/src/index.js:
--------------------------------------------------------------------------------
1 | import 'whatwg-fetch';
2 |
3 | import React from 'react';
4 | import ReactDOM from 'react-dom';
5 |
6 | import { App } from './app';
7 |
8 | ReactDOM.render(, document.getElementById('main'));
9 |
--------------------------------------------------------------------------------
/step-3/tests/bootstrap.js:
--------------------------------------------------------------------------------
1 | /* eslint no-console: 0 */
2 |
3 | import jsdom from 'jsdom';
4 |
5 | export function bootstrapEnv(body = '') {
6 | const doc = jsdom.jsdom(`${body}`);
7 | const win = doc.defaultView;
8 | function propagateToGlobal(window) {
9 | for (const key in window) {
10 | if (!window.hasOwnProperty(key)) continue;
11 | if (key in global) continue;
12 | global[key] = window[key];
13 | }
14 | }
15 | global.document = doc;
16 | global.window = win;
17 | propagateToGlobal(win);
18 | // console.log('\nENV setup is done !!!');
19 | }
20 |
--------------------------------------------------------------------------------
/step-3/tests/index.js:
--------------------------------------------------------------------------------
1 | /* eslint no-unused-vars:0, no-console: 0 */
2 |
3 | import { bootstrapEnv } from './bootstrap';
4 |
5 | bootstrapEnv();
6 |
7 | require('./components/regions.spec.js')
8 | require('./components/wine-list.spec.js')
9 | require('./components/wine.spec.js')
10 | require('./components/wine-app.spec.js')
11 |
--------------------------------------------------------------------------------
/step-3/view1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-3/view1.png
--------------------------------------------------------------------------------
/step-3/view2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-3/view2.png
--------------------------------------------------------------------------------
/step-3/view3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-3/view3.png
--------------------------------------------------------------------------------
/step-3/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 |
3 | module.exports = {
4 | output: {
5 | path: './public/js/',
6 | publicPath: '/js/',
7 | filename: 'bundle.js'
8 | },
9 | entry: {
10 | app: ['./src/index.js']
11 | },
12 | resolve: {
13 | extensions: ['', '.js', '.jsx']
14 | },
15 | module: {
16 | loaders: [
17 | {
18 | test: /\.js$/,
19 | exclude: /node_modules/,
20 | loader: 'babel'
21 | }
22 | ]
23 | },
24 | devServer: {
25 | historyApiFallback: true,
26 | proxy: {
27 | '/api/*': {
28 | target: 'http://localhost:3000'
29 | }
30 | }
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/step-4-done/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/step-4-done/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | webpack.config.js
3 | public
4 | README.md
5 |
--------------------------------------------------------------------------------
/step-4-done/.gitignore:
--------------------------------------------------------------------------------
1 | # Node.js
2 | node_modules
3 | npm-debug.log
4 |
5 | # Bundles
6 | bundle.js
7 | bundle.js.map
8 |
--------------------------------------------------------------------------------
/step-4-done/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-workshop",
3 | "description": "React Workshop",
4 | "version": "0.1.0",
5 | "dependencies": {
6 | "react": "0.14.7",
7 | "react-dom": "0.14.7",
8 | "react-router": "2.0.1",
9 | "whatwg-fetch": "0.11.0"
10 | },
11 | "devDependencies": {
12 | "babel-loader": "6.2.4",
13 | "babel-preset-es2015": "6.6.0",
14 | "babel-preset-react": "6.5.0",
15 | "babel-register": "6.7.2",
16 | "chai": "3.5.0",
17 | "enzyme": "2.2.0",
18 | "eslint": "2.4.0",
19 | "eslint-plugin-react": "4.2.3",
20 | "jsdom": "8.1.0",
21 | "mocha": "2.4.5",
22 | "react-addons-test-utils": "0.14.7",
23 | "sinon": "1.17.3",
24 | "webpack": "1.12.14",
25 | "webpack-dev-server": "1.14.1"
26 | },
27 | "scripts": {
28 | "lint": "eslint src",
29 | "test": "mocha --compilers js:babel-register tests/index.js",
30 | "bundle": "webpack -p --colors --progress",
31 | "start": "webpack-dev-server -d --colors --inline --content-base public",
32 | "build": "npm run lint && npm run bundle"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/step-4-done/public/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: 'Roboto', sans-serif;
3 | }
4 |
--------------------------------------------------------------------------------
/step-4-done/public/img/chevrol-bel-air.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-4-done/public/img/chevrol-bel-air.png
--------------------------------------------------------------------------------
/step-4-done/public/img/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-4-done/public/img/react.png
--------------------------------------------------------------------------------
/step-4-done/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React Workshop
6 |
7 |
8 |
9 |
10 |
11 |
12 | Wines
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/step-4-done/public/js/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-4-done/public/js/.gitkeep
--------------------------------------------------------------------------------
/step-4-done/readme.md:
--------------------------------------------------------------------------------
1 | # Etape 4
2 |
3 | Ce dossier contient la version finale de [l'étape 4]('../step-4')
4 |
--------------------------------------------------------------------------------
/step-4-done/src/app.js:
--------------------------------------------------------------------------------
1 | /* eslint react/jsx-max-props-per-line: 0 */
2 |
3 | import 'whatwg-fetch';
4 |
5 | import React, { PropTypes } from 'react';
6 |
7 | import WineApp from './components/wine-app';
8 | import { RegionsPage } from './components/regions';
9 | import { WineListPage } from './components/wine-list';
10 | import { WinePage } from './components/wine';
11 | import { NotFound } from './components/not-found';
12 |
13 | import { Router, Route, browserHistory, IndexRoute } from 'react-router';
14 |
15 | export const App = React.createClass({
16 | propTypes: {
17 | history: PropTypes.object, // eslint-disable-line
18 | },
19 | render() {
20 | const history = this.props.history || browserHistory;
21 | return (
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | );
31 | }
32 | });
33 |
--------------------------------------------------------------------------------
/step-4-done/src/components/not-found.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export const NotFound = React.createClass({
4 | render() {
5 | return (
6 | Il semble que vous n'êtes pas au bon endroit !!!
7 | );
8 | }
9 | });
10 |
--------------------------------------------------------------------------------
/step-4-done/src/components/wine-app.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 |
3 | const WineApp = React.createClass({
4 |
5 | propTypes: {
6 | children: PropTypes.element
7 | },
8 |
9 | contextTypes: {
10 | router: React.PropTypes.object
11 | },
12 |
13 | getInitialState() {
14 | return {
15 | title: ''
16 | };
17 | },
18 |
19 | setTitle(title) {
20 | this.setState({ title });
21 | },
22 |
23 | goBack() {
24 | this.context.router.goBack();
25 | },
26 |
27 | render () {
28 | return (
29 |
30 |
31 |
{this.state.title}
32 | {this.props.children && React.cloneElement(this.props.children, {
33 | setTitle: this.setTitle
34 | })}
35 |
36 |
37 | );
38 | }
39 | })
40 |
41 | export default WineApp
42 |
--------------------------------------------------------------------------------
/step-4-done/src/index.js:
--------------------------------------------------------------------------------
1 | import 'whatwg-fetch';
2 |
3 | import React from 'react';
4 | import ReactDOM from 'react-dom';
5 |
6 | import { App } from './app';
7 |
8 | ReactDOM.render(, document.getElementById('main'));
9 |
--------------------------------------------------------------------------------
/step-4-done/tests/bootstrap.js:
--------------------------------------------------------------------------------
1 | /* eslint no-console: 0 */
2 |
3 | import jsdom from 'jsdom';
4 |
5 | export function bootstrapEnv(body = '') {
6 | const doc = jsdom.jsdom(`${body}`);
7 | const win = doc.defaultView;
8 | function propagateToGlobal(window) {
9 | for (const key in window) {
10 | if (!window.hasOwnProperty(key)) continue;
11 | if (key in global) continue;
12 | global[key] = window[key];
13 | }
14 | }
15 | global.document = doc;
16 | global.window = win;
17 | global.TEST = true;
18 | global.window.TEST = true;
19 | propagateToGlobal(win);
20 | // console.log('\nENV setup is done !!!');
21 | }
22 |
--------------------------------------------------------------------------------
/step-4-done/tests/index.js:
--------------------------------------------------------------------------------
1 | /* eslint no-unused-vars:0, no-console: 0 */
2 |
3 | import { bootstrapEnv } from './bootstrap';
4 |
5 | bootstrapEnv();
6 |
7 | require('./components/regions.spec.js')
8 | require('./components/wine-list.spec.js')
9 | require('./components/wine.spec.js')
10 | require('./components/wine-app.spec.js')
11 |
--------------------------------------------------------------------------------
/step-4-done/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 |
3 | module.exports = {
4 | output: {
5 | path: './public/js/',
6 | publicPath: '/js/',
7 | filename: 'bundle.js'
8 | },
9 | entry: {
10 | app: ['./src/index.js']
11 | },
12 | resolve: {
13 | extensions: ['', '.js', '.jsx']
14 | },
15 | module: {
16 | loaders: [
17 | {
18 | test: /\.js$/,
19 | exclude: /node_modules/,
20 | loader: 'babel'
21 | }
22 | ]
23 | },
24 | devServer: {
25 | historyApiFallback: true,
26 | proxy: {
27 | '/api/*': {
28 | target: 'http://localhost:3000'
29 | }
30 | }
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/step-4/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/step-4/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | webpack.config.js
3 | public
4 | README.md
5 |
--------------------------------------------------------------------------------
/step-4/.gitignore:
--------------------------------------------------------------------------------
1 | # Node.js
2 | node_modules
3 | npm-debug.log
4 |
5 | # Bundles
6 | bundle.js
7 | bundle.js.map
8 |
--------------------------------------------------------------------------------
/step-4/mockup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-4/mockup.png
--------------------------------------------------------------------------------
/step-4/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-workshop",
3 | "description": "React Workshop",
4 | "version": "0.1.0",
5 | "dependencies": {
6 | "react": "0.14.7",
7 | "react-dom": "0.14.7",
8 | "react-router": "2.0.1",
9 | "whatwg-fetch": "0.11.0"
10 | },
11 | "devDependencies": {
12 | "babel-loader": "6.2.4",
13 | "babel-preset-es2015": "6.6.0",
14 | "babel-preset-react": "6.5.0",
15 | "babel-register": "6.7.2",
16 | "chai": "3.5.0",
17 | "enzyme": "2.2.0",
18 | "eslint": "2.4.0",
19 | "eslint-plugin-react": "4.2.3",
20 | "jsdom": "8.1.0",
21 | "mocha": "2.4.5",
22 | "react-addons-test-utils": "0.14.7",
23 | "sinon": "1.17.3",
24 | "webpack": "1.12.14",
25 | "webpack-dev-server": "1.14.1"
26 | },
27 | "scripts": {
28 | "lint": "eslint src",
29 | "test": "mocha --compilers js:babel-register tests/index.js",
30 | "bundle": "webpack -p --colors --progress",
31 | "start": "webpack-dev-server -d --colors --inline --content-base public",
32 | "build": "npm run lint && npm run bundle"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/step-4/public/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: 'Roboto', sans-serif;
3 | }
4 |
--------------------------------------------------------------------------------
/step-4/public/img/chevrol-bel-air.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-4/public/img/chevrol-bel-air.png
--------------------------------------------------------------------------------
/step-4/public/img/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-4/public/img/react.png
--------------------------------------------------------------------------------
/step-4/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React Workshop
6 |
7 |
8 |
9 |
10 |
11 |
12 | Wines
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/step-4/public/js/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-4/public/js/.gitkeep
--------------------------------------------------------------------------------
/step-4/src/app.js:
--------------------------------------------------------------------------------
1 | /* eslint react/jsx-max-props-per-line: 0 */
2 |
3 | import 'whatwg-fetch';
4 |
5 | import React, { PropTypes } from 'react';
6 |
7 | import WineApp from './components/wine-app';
8 | import { RegionsPage } from './components/regions';
9 | import { WineListPage } from './components/wine-list';
10 | import { WinePage } from './components/wine';
11 | import { NotFound } from './components/not-found';
12 |
13 | import { Router, Route, browserHistory, IndexRoute } from 'react-router';
14 |
15 | export const App = React.createClass({
16 | propTypes: {
17 | history: PropTypes.object, // eslint-disable-line
18 | },
19 | render() {
20 | const history = this.props.history || browserHistory;
21 | return (
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | );
31 | }
32 | });
33 |
--------------------------------------------------------------------------------
/step-4/src/components/not-found.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export const NotFound = React.createClass({
4 | render() {
5 | return (
6 | Il semble que vous n'êtes pas au bon endroit !!!
7 | );
8 | }
9 | });
10 |
--------------------------------------------------------------------------------
/step-4/src/components/wine-app.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 |
3 | const WineApp = React.createClass({
4 |
5 | propTypes: {
6 | children: PropTypes.element
7 | },
8 |
9 | contextTypes: {
10 | router: React.PropTypes.object
11 | },
12 |
13 | getInitialState() {
14 | return {
15 | title: ''
16 | };
17 | },
18 |
19 | setTitle(title) {
20 | this.setState({ title });
21 | },
22 |
23 | goBack() {
24 | this.context.router.goBack();
25 | },
26 |
27 | render () {
28 | return (
29 |
30 |
31 |
{this.state.title}
32 | {this.props.children && React.cloneElement(this.props.children, {
33 | setTitle: this.setTitle
34 | })}
35 |
36 |
37 | );
38 | }
39 | })
40 |
41 | export default WineApp
42 |
--------------------------------------------------------------------------------
/step-4/src/index.js:
--------------------------------------------------------------------------------
1 | import 'whatwg-fetch';
2 |
3 | import React from 'react';
4 | import ReactDOM from 'react-dom';
5 |
6 | import { App } from './app';
7 |
8 | ReactDOM.render(, document.getElementById('main'));
9 |
--------------------------------------------------------------------------------
/step-4/tests/bootstrap.js:
--------------------------------------------------------------------------------
1 | /* eslint no-console: 0 */
2 |
3 | import jsdom from 'jsdom';
4 |
5 | export function bootstrapEnv(body = '') {
6 | const doc = jsdom.jsdom(`${body}`);
7 | const win = doc.defaultView;
8 | function propagateToGlobal(window) {
9 | for (const key in window) {
10 | if (!window.hasOwnProperty(key)) continue;
11 | if (key in global) continue;
12 | global[key] = window[key];
13 | }
14 | }
15 | global.document = doc;
16 | global.window = win;
17 | global.TEST = true;
18 | global.window.TEST = true;
19 | propagateToGlobal(win);
20 | // console.log('\nENV setup is done !!!');
21 | }
22 |
--------------------------------------------------------------------------------
/step-4/tests/index.js:
--------------------------------------------------------------------------------
1 | /* eslint no-unused-vars:0, no-console: 0 */
2 |
3 | import { bootstrapEnv } from './bootstrap';
4 |
5 | bootstrapEnv();
6 |
7 | require('./components/regions.spec.js')
8 | require('./components/wine-list.spec.js')
9 | require('./components/wine.spec.js')
10 | require('./components/wine-app.spec.js')
11 |
--------------------------------------------------------------------------------
/step-4/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 |
3 | module.exports = {
4 | output: {
5 | path: './public/js/',
6 | publicPath: '/js/',
7 | filename: 'bundle.js'
8 | },
9 | entry: {
10 | app: ['./src/index.js']
11 | },
12 | resolve: {
13 | extensions: ['', '.js', '.jsx']
14 | },
15 | module: {
16 | loaders: [
17 | {
18 | test: /\.js$/,
19 | exclude: /node_modules/,
20 | loader: 'babel'
21 | }
22 | ]
23 | },
24 | devServer: {
25 | historyApiFallback: true,
26 | proxy: {
27 | '/api/*': {
28 | target: 'http://localhost:3000'
29 | }
30 | }
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/step-5-done/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/step-5-done/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | webpack.config.js
3 | public
4 | README.md
5 |
--------------------------------------------------------------------------------
/step-5-done/.gitignore:
--------------------------------------------------------------------------------
1 | # Node.js
2 | node_modules
3 | npm-debug.log
4 |
5 | # Bundles
6 | bundle.js
7 | bundle.js.map
8 |
--------------------------------------------------------------------------------
/step-5-done/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-workshop",
3 | "description": "React Workshop",
4 | "version": "0.1.0",
5 | "dependencies": {
6 | "react": "0.14.7",
7 | "react-dom": "0.14.7",
8 | "react-redux": "4.4.1",
9 | "react-router": "2.0.1",
10 | "redux": "3.3.1",
11 | "whatwg-fetch": "0.11.0"
12 | },
13 | "devDependencies": {
14 | "babel-loader": "6.2.4",
15 | "babel-preset-es2015": "6.6.0",
16 | "babel-preset-react": "6.5.0",
17 | "babel-register": "6.7.2",
18 | "chai": "3.5.0",
19 | "enzyme": "2.2.0",
20 | "eslint": "2.4.0",
21 | "eslint-plugin-react": "4.2.3",
22 | "jsdom": "8.1.0",
23 | "mocha": "2.4.5",
24 | "react-addons-test-utils": "0.14.7",
25 | "sinon": "1.17.3",
26 | "webpack": "1.12.14",
27 | "webpack-dev-server": "1.14.1"
28 | },
29 | "scripts": {
30 | "lint": "eslint src",
31 | "test": "mocha --compilers js:babel-register tests/index.js",
32 | "bundle": "webpack -p --colors --progress",
33 | "start": "webpack-dev-server -d --colors --inline --content-base public",
34 | "build": "npm run lint && npm run bundle"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/step-5-done/public/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: 'Roboto', sans-serif;
3 | }
4 |
--------------------------------------------------------------------------------
/step-5-done/public/img/chevrol-bel-air.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-5-done/public/img/chevrol-bel-air.png
--------------------------------------------------------------------------------
/step-5-done/public/img/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-5-done/public/img/react.png
--------------------------------------------------------------------------------
/step-5-done/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React Workshop
6 |
7 |
8 |
9 |
10 |
11 |
12 | Wines
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/step-5-done/public/js/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-5-done/public/js/.gitkeep
--------------------------------------------------------------------------------
/step-5-done/readme.md:
--------------------------------------------------------------------------------
1 | # Etape 5
2 |
3 | Ce dossier contient la version finale de [l'étape 5]('../step-5')
4 |
--------------------------------------------------------------------------------
/step-5-done/src/actions/index.js:
--------------------------------------------------------------------------------
1 | export const addLike = () => {
2 | return {
3 | type: 'ADD_LIKE',
4 | increment: 1
5 | };
6 | }
7 |
8 | export const removeLike = () => {
9 | return {
10 | type: 'REMOVE_LIKE',
11 | decrement: 1
12 | };
13 | }
14 |
15 | export const setLikes = (likes) => {
16 | return {
17 | type: 'SET_LIKES',
18 | likes
19 | };
20 | }
21 |
22 | export const addComment = () => {
23 | return {
24 | type: 'ADD_COMMENT',
25 | increment: 1
26 | };
27 | }
28 |
29 | export const setComments = (comments) => {
30 | return {
31 | type: 'SET_COMMENTS',
32 | comments
33 | };
34 | }
35 |
--------------------------------------------------------------------------------
/step-5-done/src/components/not-found.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export const NotFound = React.createClass({
4 | render() {
5 | return (
6 | Il semble que vous n'êtes pas au bon endroit !!!
7 | );
8 | }
9 | });
10 |
--------------------------------------------------------------------------------
/step-5-done/src/components/stats.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import { connect } from 'react-redux';
3 |
4 | export const Stats = React.createClass({
5 | propTypes: {
6 | comments: PropTypes.number.isRequired,
7 | likes: PropTypes.number.isRequired
8 | },
9 |
10 | render() {
11 | return (
12 |
13 |
Global stats
14 |
comments : {this.props.comments}
15 |
likes : {this.props.likes}
16 |
17 | );
18 | }
19 | });
20 |
21 | const mapStateToProps = (state) => {
22 | return {
23 | comments: state.comments,
24 | likes: state.likes
25 | };
26 | };
27 |
28 | export const GlobalStats = connect(mapStateToProps)(Stats);
29 |
--------------------------------------------------------------------------------
/step-5-done/src/index.js:
--------------------------------------------------------------------------------
1 | import 'whatwg-fetch';
2 |
3 | import React from 'react';
4 | import ReactDOM from 'react-dom';
5 |
6 | import { App } from './app';
7 |
8 | ReactDOM.render(, document.getElementById('main'));
9 |
--------------------------------------------------------------------------------
/step-5-done/src/reducers/comments.js:
--------------------------------------------------------------------------------
1 | const comments = (state = 0, action) => {
2 | switch (action.type) {
3 | case 'ADD_COMMENT':
4 | return state + action.increment;
5 | case 'SET_COMMENTS':
6 | return action.comments;
7 | default:
8 | return state;
9 | }
10 | }
11 |
12 | export default comments;
13 |
--------------------------------------------------------------------------------
/step-5-done/src/reducers/index.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux';
2 | import comments from './comments';
3 | import likes from './likes';
4 |
5 | const app = combineReducers({
6 | comments,
7 | likes
8 | });
9 |
10 | export default app;
11 |
--------------------------------------------------------------------------------
/step-5-done/src/reducers/likes.js:
--------------------------------------------------------------------------------
1 | const likes = (state = 0, action) => {
2 | switch (action.type) {
3 | case 'ADD_LIKE':
4 | return state + action.increment;
5 | case 'REMOVE_LIKE':
6 | return state - action.decrement;
7 | case 'SET_LIKES':
8 | return action.likes;
9 | default:
10 | return state;
11 | }
12 | }
13 |
14 | export default likes;
15 |
--------------------------------------------------------------------------------
/step-5-done/tests/bootstrap.js:
--------------------------------------------------------------------------------
1 | /* eslint no-console: 0 */
2 |
3 | import jsdom from 'jsdom';
4 |
5 | export function bootstrapEnv(body = '') {
6 | const doc = jsdom.jsdom(`${body}`);
7 | const win = doc.defaultView;
8 | function propagateToGlobal(window) {
9 | for (const key in window) {
10 | if (!window.hasOwnProperty(key)) continue;
11 | if (key in global) continue;
12 | global[key] = window[key];
13 | }
14 | }
15 | global.document = doc;
16 | global.window = win;
17 | global.TEST = true;
18 | global.window.TEST = true;
19 | propagateToGlobal(win);
20 | // console.log('\nENV setup is done !!!');
21 | }
22 |
--------------------------------------------------------------------------------
/step-5-done/tests/index.js:
--------------------------------------------------------------------------------
1 | /* eslint no-unused-vars:0, no-console: 0 */
2 |
3 | import { bootstrapEnv } from './bootstrap';
4 |
5 | bootstrapEnv();
6 |
7 | require('./components/regions.spec.js')
8 | require('./components/wine-list.spec.js')
9 | require('./components/wine.spec.js')
10 | require('./components/wine-app.spec.js')
11 |
--------------------------------------------------------------------------------
/step-5-done/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 |
3 | module.exports = {
4 | output: {
5 | path: './public/js/',
6 | publicPath: '/js/',
7 | filename: 'bundle.js'
8 | },
9 | entry: {
10 | app: ['./src/index.js']
11 | },
12 | resolve: {
13 | extensions: ['', '.js', '.jsx']
14 | },
15 | module: {
16 | loaders: [
17 | {
18 | test: /\.js$/,
19 | exclude: /node_modules/,
20 | loader: 'babel'
21 | }
22 | ]
23 | },
24 | devServer: {
25 | historyApiFallback: true,
26 | proxy: {
27 | '/api/*': {
28 | target: 'http://localhost:3000'
29 | }
30 | }
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/step-5/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/step-5/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | webpack.config.js
3 | public
4 | README.md
5 |
--------------------------------------------------------------------------------
/step-5/.gitignore:
--------------------------------------------------------------------------------
1 | # Node.js
2 | node_modules
3 | npm-debug.log
4 |
5 | # Bundles
6 | bundle.js
7 | bundle.js.map
8 |
--------------------------------------------------------------------------------
/step-5/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-workshop",
3 | "description": "React Workshop",
4 | "version": "0.1.0",
5 | "dependencies": {
6 | "react": "0.14.7",
7 | "react-dom": "0.14.7",
8 | "react-redux": "4.4.1",
9 | "react-router": "2.0.1",
10 | "redux": "3.3.1",
11 | "whatwg-fetch": "0.11.0"
12 | },
13 | "devDependencies": {
14 | "babel-loader": "6.2.4",
15 | "babel-preset-es2015": "6.6.0",
16 | "babel-preset-react": "6.5.0",
17 | "babel-register": "6.7.2",
18 | "chai": "3.5.0",
19 | "enzyme": "2.2.0",
20 | "eslint": "2.4.0",
21 | "eslint-plugin-react": "4.2.3",
22 | "jsdom": "8.1.0",
23 | "mocha": "2.4.5",
24 | "react-addons-test-utils": "0.14.7",
25 | "sinon": "1.17.3",
26 | "webpack": "1.12.14",
27 | "webpack-dev-server": "1.14.1"
28 | },
29 | "scripts": {
30 | "lint": "eslint src",
31 | "test": "mocha --compilers js:babel-register tests/index.js",
32 | "bundle": "webpack -p --colors --progress",
33 | "start": "webpack-dev-server -d --colors --inline --content-base public",
34 | "build": "npm run lint && npm run bundle"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/step-5/public/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: 'Roboto', sans-serif;
3 | }
4 |
--------------------------------------------------------------------------------
/step-5/public/img/chevrol-bel-air.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-5/public/img/chevrol-bel-air.png
--------------------------------------------------------------------------------
/step-5/public/img/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-5/public/img/react.png
--------------------------------------------------------------------------------
/step-5/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React Workshop
6 |
7 |
8 |
9 |
10 |
11 |
12 | Wines
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/step-5/public/js/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-5/public/js/.gitkeep
--------------------------------------------------------------------------------
/step-5/src/actions/index.js:
--------------------------------------------------------------------------------
1 | export const increment = () => {
2 | return {
3 | type: 'INCREMENT',
4 | increment: 1
5 | };
6 | }
7 |
--------------------------------------------------------------------------------
/step-5/src/components/clicker.js:
--------------------------------------------------------------------------------
1 | import { increment } from '../actions';
2 | import { connect } from 'react-redux';
3 | import React, { PropTypes } from 'react';
4 |
5 | const SimpleClicker = React.createClass({
6 | propTypes: {
7 | counter: PropTypes.number,
8 | dispatch: PropTypes.func
9 | },
10 | handleButtonClick() {
11 | this.props.dispatch(increment());
12 | },
13 | render() {
14 | return (
15 |
16 | Clicked : {this.props.counter}
17 |
18 |
19 | );
20 | }
21 | });
22 |
23 | const mapStateToProps = (state) => {
24 | return {
25 | counter: state.counter
26 | }
27 | };
28 |
29 | export const Clicker = connect(mapStateToProps)(SimpleClicker);
30 |
--------------------------------------------------------------------------------
/step-5/src/components/not-found.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export const NotFound = React.createClass({
4 | render() {
5 | return (
6 | Il semble que vous n'êtes pas au bon endroit !!!
7 | );
8 | }
9 | });
10 |
--------------------------------------------------------------------------------
/step-5/src/index.js:
--------------------------------------------------------------------------------
1 | import 'whatwg-fetch';
2 |
3 | import React from 'react';
4 | import ReactDOM from 'react-dom';
5 |
6 | import { App } from './app';
7 |
8 | ReactDOM.render(, document.getElementById('main'));
9 |
--------------------------------------------------------------------------------
/step-5/src/reducers/counter.js:
--------------------------------------------------------------------------------
1 | const counter = (state = 0, action) => {
2 | switch (action.type) {
3 | case 'INCREMENT':
4 | return state + action.increment;
5 | default:
6 | return state;
7 | }
8 | }
9 |
10 | export default counter;
11 |
--------------------------------------------------------------------------------
/step-5/src/reducers/index.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux';
2 | import counter from './counter';
3 |
4 | const app = combineReducers({
5 | counter
6 | });
7 |
8 | export default app;
9 |
--------------------------------------------------------------------------------
/step-5/tests/bootstrap.js:
--------------------------------------------------------------------------------
1 | /* eslint no-console: 0 */
2 |
3 | import jsdom from 'jsdom';
4 |
5 | export function bootstrapEnv(body = '') {
6 | const doc = jsdom.jsdom(`${body}`);
7 | const win = doc.defaultView;
8 | function propagateToGlobal(window) {
9 | for (const key in window) {
10 | if (!window.hasOwnProperty(key)) continue;
11 | if (key in global) continue;
12 | global[key] = window[key];
13 | }
14 | }
15 | global.document = doc;
16 | global.window = win;
17 | global.TEST = true;
18 | global.window.TEST = true;
19 | propagateToGlobal(win);
20 | // console.log('\nENV setup is done !!!');
21 | }
22 |
--------------------------------------------------------------------------------
/step-5/tests/index.js:
--------------------------------------------------------------------------------
1 | /* eslint no-unused-vars:0, no-console: 0 */
2 |
3 | import { bootstrapEnv } from './bootstrap';
4 |
5 | bootstrapEnv();
6 |
7 | require('./components/regions.spec.js')
8 | require('./components/wine-list.spec.js')
9 | require('./components/wine.spec.js')
10 | require('./components/wine-app.spec.js')
11 |
--------------------------------------------------------------------------------
/step-5/view1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-5/view1.png
--------------------------------------------------------------------------------
/step-5/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 |
3 | module.exports = {
4 | output: {
5 | path: './public/js/',
6 | publicPath: '/js/',
7 | filename: 'bundle.js'
8 | },
9 | entry: {
10 | app: ['./src/index.js']
11 | },
12 | resolve: {
13 | extensions: ['', '.js', '.jsx']
14 | },
15 | module: {
16 | loaders: [
17 | {
18 | test: /\.js$/,
19 | exclude: /node_modules/,
20 | loader: 'babel'
21 | }
22 | ]
23 | },
24 | devServer: {
25 | historyApiFallback: true,
26 | proxy: {
27 | '/api/*': {
28 | target: 'http://localhost:3000'
29 | }
30 | }
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/step-6-done/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/step-6-done/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | webpack.config.js
3 | public
4 | README.md
5 |
--------------------------------------------------------------------------------
/step-6-done/.gitignore:
--------------------------------------------------------------------------------
1 | # Node.js
2 | node_modules
3 | npm-debug.log
4 |
5 | # Bundles
6 | bundle.js
7 | bundle.js.map
8 |
--------------------------------------------------------------------------------
/step-6-done/public/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: 'Roboto', sans-serif;
3 | }
4 |
--------------------------------------------------------------------------------
/step-6-done/public/img/chevrol-bel-air.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-6-done/public/img/chevrol-bel-air.png
--------------------------------------------------------------------------------
/step-6-done/public/img/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-6-done/public/img/react.png
--------------------------------------------------------------------------------
/step-6-done/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React Workshop
6 |
7 |
8 |
9 |
10 |
11 |
12 | Wines
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/step-6-done/public/js/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-6-done/public/js/.gitkeep
--------------------------------------------------------------------------------
/step-6-done/readme.md:
--------------------------------------------------------------------------------
1 | # Etape 6
2 |
3 | Ce dossier contient la version finale de [l'étape 6]('../step-6')
4 |
--------------------------------------------------------------------------------
/step-6-done/src/components/devtools.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { createDevTools } from 'redux-devtools';
3 | import LogMonitor from 'redux-devtools-log-monitor';
4 | import DockMonitor from 'redux-devtools-dock-monitor';
5 |
6 | export const DevTools = createDevTools(
7 |
8 |
9 |
10 | );
11 |
--------------------------------------------------------------------------------
/step-6-done/src/components/not-found.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export const NotFound = React.createClass({
4 | render() {
5 | return (
6 | Il semble que vous n'êtes pas au bon endroit !!!
7 | );
8 | }
9 | });
10 |
--------------------------------------------------------------------------------
/step-6-done/src/components/stats.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import { connect } from 'react-redux';
3 |
4 | const mapStateToProps = (state) => {
5 | return {
6 | comments: state.comments.count,
7 | likes: state.likes.count
8 | };
9 | }
10 |
11 | export const GlobalStats = connect(mapStateToProps)(React.createClass({
12 | propTypes: {
13 | comments: PropTypes.number.isRequired,
14 | likes: PropTypes.number.isRequired
15 | },
16 |
17 | render() {
18 | return (
19 |
20 |
Global stats
21 |
comments : {this.props.comments}
22 |
likes : {this.props.likes}
23 |
24 | );
25 | }
26 | }))
27 |
--------------------------------------------------------------------------------
/step-6-done/src/index.js:
--------------------------------------------------------------------------------
1 | import 'whatwg-fetch';
2 |
3 | import React from 'react';
4 | import ReactDOM from 'react-dom';
5 |
6 | import { App } from './app';
7 |
8 | ReactDOM.render(, document.getElementById('main'));
9 |
--------------------------------------------------------------------------------
/step-6-done/src/reducers/comments.js:
--------------------------------------------------------------------------------
1 | export const comments = (state = { count: 0 }, action) => {
2 | switch (action.type) {
3 | case 'ADD_COMMENT':
4 | return Object.assign({}, state, { count: state.count + action.increment });
5 | case 'SET_COMMENTS':
6 | return Object.assign({}, state, { count: action.comments });
7 | default:
8 | return state;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/step-6-done/src/reducers/http.js:
--------------------------------------------------------------------------------
1 | export const http = (state = { state: 'LOADED', error: undefined }, action) => {
2 | switch (action.type) {
3 | case 'LOADING':
4 | return Object.assign({}, state, { state: 'LOADING', error: undefined });
5 | case 'LOADED':
6 | return Object.assign({}, state, { state: 'LOADED', error: undefined });
7 | case 'ERROR':
8 | return Object.assign({}, state, { state: 'ERROR', error: action.error });
9 | default:
10 | return state;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/step-6-done/src/reducers/likes.js:
--------------------------------------------------------------------------------
1 | export const likes = (state = { count: 0 }, action) => {
2 | switch (action.type) {
3 | case 'ADD_LIKE':
4 | return Object.assign({}, state, { count: state.count + action.increment });
5 | case 'REMOVE_LIKE':
6 | return Object.assign({}, state, { count: state.count - action.decrement });
7 | case 'SET_LIKES':
8 | return Object.assign({}, state, { count: action.likes });
9 | default:
10 | return state;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/step-6-done/src/reducers/regions.js:
--------------------------------------------------------------------------------
1 | export const regions = (state = { data: [], lastUpdated: 0 }, action) => {
2 | switch (action.type) {
3 | case 'SET_REGIONS':
4 | return Object.assign({}, state, { data: action.regions });
5 | case 'UPDATE_REGIONS_TIMESTAMP':
6 | return Object.assign({}, state, { lastUpdated: Date.now() });
7 | default:
8 | return state;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/step-6-done/src/reducers/title.js:
--------------------------------------------------------------------------------
1 | export const title = (state = '', action) => {
2 | switch (action.type) {
3 | case 'SET_TITLE':
4 | return action.title;
5 | default:
6 | return state;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/step-6-done/src/reducers/wines.js:
--------------------------------------------------------------------------------
1 | export const wines = (state = {}, action) => {
2 | switch (action.type) {
3 | case 'SET_WINES':
4 | return Object.assign({}, state, { [action.region]: { lastUpdated: Date.now(), data: action.wines }});
5 | case 'UPDATE_WINES_TIMESTAMP':
6 | return Object.assign({}, state, Object.assign({}, state[action.region], { lastUpdated: Date.now() }));
7 | default:
8 | return state;
9 | }
10 | }
11 |
12 | export const currentWine = (state = { wine: undefined, comments: [], liked: false }, action) => {
13 | switch (action.type) {
14 | case 'SET_CURRENT_WINE':
15 | return Object.assign({}, state, { wine: action.wine, liked: false });
16 | case 'SET_CURRENT_COMMENTS':
17 | return Object.assign({}, state, { comments: action.comments });
18 | case 'SET_CURRENT_LIKED':
19 | return Object.assign({}, state, { liked: action.liked });
20 | default:
21 | return state;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/step-6-done/tests/bootstrap.js:
--------------------------------------------------------------------------------
1 | /* eslint no-console: 0 */
2 |
3 | import jsdom from 'jsdom';
4 |
5 | export function bootstrapEnv(body = '') {
6 | const doc = jsdom.jsdom(`${body}`);
7 | const win = doc.defaultView;
8 | function propagateToGlobal(window) {
9 | for (const key in window) {
10 | if (!window.hasOwnProperty(key)) continue;
11 | if (key in global) continue;
12 | global[key] = window[key];
13 | }
14 | }
15 | global.document = doc;
16 | global.window = win;
17 | global.TEST = true;
18 | global.window.TEST = true;
19 | propagateToGlobal(win);
20 | // console.log('\nENV setup is done !!!');
21 | }
22 |
--------------------------------------------------------------------------------
/step-6-done/tests/index.js:
--------------------------------------------------------------------------------
1 | /* eslint no-unused-vars:0, no-console: 0 */
2 |
3 | import { bootstrapEnv } from './bootstrap';
4 |
5 | bootstrapEnv();
6 |
7 | require('./components/regions.spec.js')
8 | require('./components/wine-list.spec.js')
9 | require('./components/wine.spec.js')
10 | require('./components/wine-app.spec.js')
11 |
--------------------------------------------------------------------------------
/step-6-done/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 |
3 | module.exports = {
4 | output: {
5 | path: './public/js/',
6 | publicPath: '/js/',
7 | filename: 'bundle.js'
8 | },
9 | devServer: {
10 | historyApiFallback: true,
11 | proxy: {
12 | '/api/*': {
13 | target: 'http://localhost:3000'
14 | }
15 | }
16 | },
17 | entry: {
18 | app: ['./src/index.js']
19 | },
20 | resolve: {
21 | extensions: ['', '.js', '.jsx']
22 | },
23 | module: {
24 | loaders: [{
25 | test: /\.js$/,
26 | exclude: /node_modules/,
27 | loader: 'babel'
28 | }]
29 | }
30 | };
31 |
--------------------------------------------------------------------------------
/step-6/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/step-6/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | webpack.config.js
3 | public
4 | README.md
5 |
--------------------------------------------------------------------------------
/step-6/.gitignore:
--------------------------------------------------------------------------------
1 | # Node.js
2 | node_modules
3 | npm-debug.log
4 |
5 | # Bundles
6 | bundle.js
7 | bundle.js.map
8 |
--------------------------------------------------------------------------------
/step-6/public/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: 'Roboto', sans-serif;
3 | }
4 |
--------------------------------------------------------------------------------
/step-6/public/img/chevrol-bel-air.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-6/public/img/chevrol-bel-air.png
--------------------------------------------------------------------------------
/step-6/public/img/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-6/public/img/react.png
--------------------------------------------------------------------------------
/step-6/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React Workshop
6 |
7 |
8 |
9 |
10 |
11 |
12 | Wines
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/step-6/public/js/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-6/public/js/.gitkeep
--------------------------------------------------------------------------------
/step-6/src/components/devtools.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { createDevTools } from 'redux-devtools';
3 | import LogMonitor from 'redux-devtools-log-monitor';
4 | import DockMonitor from 'redux-devtools-dock-monitor';
5 |
6 | export const DevTools = createDevTools(
7 |
8 |
9 |
10 | );
11 |
--------------------------------------------------------------------------------
/step-6/src/components/not-found.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export const NotFound = React.createClass({
4 | render() {
5 | return (
6 | Il semble que vous n'êtes pas au bon endroit !!!
7 | );
8 | }
9 | });
10 |
--------------------------------------------------------------------------------
/step-6/src/components/stats.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import { connect } from 'react-redux';
3 |
4 | const mapStateToProps = (state) => {
5 | return {
6 | comments: state.comments.count,
7 | likes: state.likes.count
8 | };
9 | }
10 |
11 | export const GlobalStats = connect(mapStateToProps)(React.createClass({
12 | propTypes: {
13 | comments: PropTypes.number.isRequired,
14 | likes: PropTypes.number.isRequired
15 | },
16 |
17 | render() {
18 | return (
19 |
20 |
Global stats
21 |
comments : {this.props.comments}
22 |
likes : {this.props.likes}
23 |
24 | );
25 | }
26 | }))
27 |
--------------------------------------------------------------------------------
/step-6/src/index.js:
--------------------------------------------------------------------------------
1 | import 'whatwg-fetch';
2 |
3 | import React from 'react';
4 | import ReactDOM from 'react-dom';
5 |
6 | import { App } from './app';
7 |
8 | ReactDOM.render(, document.getElementById('main'));
9 |
--------------------------------------------------------------------------------
/step-6/src/reducers/comments.js:
--------------------------------------------------------------------------------
1 | export const comments = (state = { count: 0 }, action) => {
2 | switch (action.type) {
3 | case 'ADD_COMMENT':
4 | return Object.assign({}, state, { count: state.count + action.increment });
5 | case 'SET_COMMENTS':
6 | return Object.assign({}, state, { count: action.comments });
7 | default:
8 | return state;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/step-6/src/reducers/http.js:
--------------------------------------------------------------------------------
1 | export const http = (state = { state: 'LOADED', error: undefined }, action) => {
2 | switch (action.type) {
3 | case 'LOADING':
4 | return Object.assign({}, state, { state: 'LOADING', error: undefined });
5 | case 'LOADED':
6 | return Object.assign({}, state, { state: 'LOADED', error: undefined });
7 | case 'ERROR':
8 | return Object.assign({}, state, { state: 'ERROR', error: action.error });
9 | default:
10 | return state;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/step-6/src/reducers/index.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux';
2 | import { comments } from './comments';
3 | import { likes } from './likes';
4 | import { http } from './http';
5 | import { routerReducer } from 'react-router-redux';
6 |
7 | export const app = combineReducers({
8 | comments,
9 | likes,
10 | http,
11 | routing: routerReducer
12 | })
13 |
--------------------------------------------------------------------------------
/step-6/src/reducers/likes.js:
--------------------------------------------------------------------------------
1 | export const likes = (state = { count: 0 }, action) => {
2 | switch (action.type) {
3 | case 'ADD_LIKE':
4 | return Object.assign({}, state, { count: state.count + action.increment });
5 | case 'REMOVE_LIKE':
6 | return Object.assign({}, state, { count: state.count - action.decrement });
7 | case 'SET_LIKES':
8 | return Object.assign({}, state, { count: action.likes });
9 | default:
10 | return state;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/step-6/tests/bootstrap.js:
--------------------------------------------------------------------------------
1 | /* eslint no-console: 0 */
2 |
3 | import jsdom from 'jsdom';
4 |
5 | export function bootstrapEnv(body = '') {
6 | const doc = jsdom.jsdom(`${body}`);
7 | const win = doc.defaultView;
8 | function propagateToGlobal(window) {
9 | for (const key in window) {
10 | if (!window.hasOwnProperty(key)) continue;
11 | if (key in global) continue;
12 | global[key] = window[key];
13 | }
14 | }
15 | global.document = doc;
16 | global.window = win;
17 | global.TEST = true;
18 | global.window.TEST = true;
19 | propagateToGlobal(win);
20 | // console.log('\nENV setup is done !!!');
21 | }
22 |
--------------------------------------------------------------------------------
/step-6/tests/index.js:
--------------------------------------------------------------------------------
1 | /* eslint no-unused-vars:0, no-console: 0 */
2 |
3 | import { bootstrapEnv } from './bootstrap';
4 |
5 | bootstrapEnv();
6 |
7 | require('./components/regions.spec.js')
8 | require('./components/wine-list.spec.js')
9 | require('./components/wine.spec.js')
10 | require('./components/wine-app.spec.js')
11 |
--------------------------------------------------------------------------------
/step-6/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 |
3 | module.exports = {
4 | output: {
5 | path: './public/js/',
6 | publicPath: '/js/',
7 | filename: 'bundle.js'
8 | },
9 | entry: {
10 | app: ['./src/index.js']
11 | },
12 | resolve: {
13 | extensions: ['', '.js', '.jsx']
14 | },
15 | module: {
16 | loaders: [
17 | {
18 | test: /\.js$/,
19 | exclude: /node_modules/,
20 | loader: 'babel'
21 | }
22 | ]
23 | },
24 | devServer: {
25 | historyApiFallback: true,
26 | proxy: {
27 | '/api/*': {
28 | target: 'http://localhost:3000'
29 | }
30 | }
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/step-7/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/step-7/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | webpack.config.js
3 | public
4 | README.md
5 |
--------------------------------------------------------------------------------
/step-7/.gitignore:
--------------------------------------------------------------------------------
1 | # Node.js
2 | node_modules
3 | npm-debug.log
4 |
5 | # Bundles
6 | bundle.js
7 | bundle.js.map
8 |
--------------------------------------------------------------------------------
/step-7/public/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: 'Roboto', sans-serif;
3 | }
4 |
--------------------------------------------------------------------------------
/step-7/public/img/chevrol-bel-air.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-7/public/img/chevrol-bel-air.png
--------------------------------------------------------------------------------
/step-7/public/img/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-7/public/img/react.png
--------------------------------------------------------------------------------
/step-7/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React Workshop
6 |
7 |
8 |
9 |
10 |
11 |
12 | Wines
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/step-7/public/js/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-7/public/js/.gitkeep
--------------------------------------------------------------------------------
/step-7/src/components/devtools.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { createDevTools } from 'redux-devtools';
3 | import LogMonitor from 'redux-devtools-log-monitor';
4 | import DockMonitor from 'redux-devtools-dock-monitor';
5 |
6 | export const DevTools = createDevTools(
7 |
8 |
9 |
10 | );
11 |
--------------------------------------------------------------------------------
/step-7/src/components/not-found.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export const NotFound = React.createClass({
4 | render() {
5 | return (
6 | Il semble que vous n'êtes pas au bon endroit !!!
7 | );
8 | }
9 | });
10 |
--------------------------------------------------------------------------------
/step-7/src/components/stats.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import { connect } from 'react-redux';
3 |
4 | const mapStateToProps = (state) => {
5 | return {
6 | comments: state.comments.count,
7 | likes: state.likes.count
8 | };
9 | }
10 |
11 | export const GlobalStats = connect(mapStateToProps)(React.createClass({
12 | propTypes: {
13 | comments: PropTypes.number.isRequired,
14 | likes: PropTypes.number.isRequired
15 | },
16 |
17 | render() {
18 | return (
19 |
20 |
Global stats
21 |
comments : {this.props.comments}
22 |
likes : {this.props.likes}
23 |
24 | );
25 | }
26 | }))
27 |
--------------------------------------------------------------------------------
/step-7/src/index.js:
--------------------------------------------------------------------------------
1 | import 'whatwg-fetch';
2 |
3 | import React from 'react';
4 | import ReactDOM from 'react-dom';
5 |
6 | import { App } from './app';
7 |
8 | ReactDOM.render(, document.getElementById('main'));
9 |
--------------------------------------------------------------------------------
/step-7/src/reducers/comments.js:
--------------------------------------------------------------------------------
1 | export const comments = (state = { count: 0 }, action) => {
2 | switch (action.type) {
3 | case 'ADD_COMMENT':
4 | return Object.assign({}, state, { count: state.count + action.increment });
5 | case 'SET_COMMENTS':
6 | return Object.assign({}, state, { count: action.comments });
7 | default:
8 | return state;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/step-7/src/reducers/http.js:
--------------------------------------------------------------------------------
1 | export const http = (state = { state: 'LOADED', error: undefined }, action) => {
2 | switch (action.type) {
3 | case 'LOADING':
4 | return Object.assign({}, state, { state: 'LOADING', error: undefined });
5 | case 'LOADED':
6 | return Object.assign({}, state, { state: 'LOADED', error: undefined });
7 | case 'ERROR':
8 | return Object.assign({}, state, { state: 'ERROR', error: action.error });
9 | default:
10 | return state;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/step-7/src/reducers/likes.js:
--------------------------------------------------------------------------------
1 | export const likes = (state = { count: 0 }, action) => {
2 | switch (action.type) {
3 | case 'ADD_LIKE':
4 | return Object.assign({}, state, { count: state.count + action.increment });
5 | case 'REMOVE_LIKE':
6 | return Object.assign({}, state, { count: state.count - action.decrement });
7 | case 'SET_LIKES':
8 | return Object.assign({}, state, { count: action.likes });
9 | default:
10 | return state;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/step-7/src/reducers/regions.js:
--------------------------------------------------------------------------------
1 | export const regions = (state = { data: [], lastUpdated: 0 }, action) => {
2 | switch (action.type) {
3 | case 'SET_REGIONS':
4 | return Object.assign({}, state, { data: action.regions });
5 | case 'UPDATE_REGIONS_TIMESTAMP':
6 | return Object.assign({}, state, { lastUpdated: Date.now() });
7 | default:
8 | return state;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/step-7/src/reducers/title.js:
--------------------------------------------------------------------------------
1 | export const title = (state = '', action) => {
2 | switch (action.type) {
3 | case 'SET_TITLE':
4 | return action.title;
5 | default:
6 | return state;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/step-7/src/reducers/wines.js:
--------------------------------------------------------------------------------
1 | export const wines = (state = {}, action) => {
2 | switch (action.type) {
3 | case 'SET_WINES':
4 | return Object.assign({}, state, { [action.region]: { lastUpdated: Date.now(), data: action.wines }});
5 | case 'UPDATE_WINES_TIMESTAMP':
6 | return Object.assign({}, state, Object.assign({}, state[action.region], { lastUpdated: Date.now() }));
7 | default:
8 | return state;
9 | }
10 | }
11 |
12 | export const currentWine = (state = { wine: undefined, comments: [], liked: false }, action) => {
13 | switch (action.type) {
14 | case 'SET_CURRENT_WINE':
15 | return Object.assign({}, state, { wine: action.wine, liked: false });
16 | case 'SET_CURRENT_COMMENTS':
17 | return Object.assign({}, state, { comments: action.comments });
18 | case 'SET_CURRENT_LIKED':
19 | return Object.assign({}, state, { liked: action.liked });
20 | default:
21 | return state;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/step-7/tests/bootstrap.js:
--------------------------------------------------------------------------------
1 | /* eslint no-console: 0 */
2 |
3 | import jsdom from 'jsdom';
4 |
5 | export function bootstrapEnv(body = '') {
6 | const doc = jsdom.jsdom(`${body}`);
7 | const win = doc.defaultView;
8 | function propagateToGlobal(window) {
9 | for (const key in window) {
10 | if (!window.hasOwnProperty(key)) continue;
11 | if (key in global) continue;
12 | global[key] = window[key];
13 | }
14 | }
15 | global.document = doc;
16 | global.window = win;
17 | global.TEST = true;
18 | global.window.TEST = true;
19 | propagateToGlobal(win);
20 | // console.log('\nENV setup is done !!!');
21 | }
22 |
--------------------------------------------------------------------------------
/step-7/tests/index.js:
--------------------------------------------------------------------------------
1 | /* eslint no-unused-vars:0, no-console: 0 */
2 |
3 | import { bootstrapEnv } from './bootstrap';
4 |
5 | bootstrapEnv();
6 |
7 | require('./components/regions.spec.js')
8 | require('./components/wine-list.spec.js')
9 | require('./components/wine.spec.js')
10 | require('./components/wine-app.spec.js')
11 |
--------------------------------------------------------------------------------
/step-7/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 |
3 | module.exports = {
4 | output: {
5 | path: './public/js/',
6 | publicPath: '/js/',
7 | filename: 'bundle.js'
8 | },
9 | devServer: {
10 | historyApiFallback: true,
11 | proxy: {
12 | '/api/*': {
13 | target: 'http://localhost:3000'
14 | }
15 | }
16 | },
17 | entry: {
18 | app: ['./src/index.js']
19 | },
20 | resolve: {
21 | extensions: ['', '.js', '.jsx']
22 | },
23 | module: {
24 | loaders: [{
25 | test: /\.js$/,
26 | exclude: /node_modules/,
27 | loader: 'babel'
28 | }]
29 | }
30 | };
31 |
--------------------------------------------------------------------------------
/step-8-done/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | webpack.config.js
3 | public
4 | README.md
5 |
--------------------------------------------------------------------------------
/step-8-done/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | project.xcworkspace
24 |
25 | # Android/IJ
26 | #
27 | .idea
28 | .gradle
29 | local.properties
30 |
31 | # node.js
32 | #
33 | node_modules/
34 | npm-debug.log
35 |
--------------------------------------------------------------------------------
/step-8-done/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/step-8-done/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/step-8-done/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8-done/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/step-8-done/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8-done/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/step-8-done/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8-done/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/step-8-done/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8-done/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/step-8-done/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | wines
3 |
4 |
--------------------------------------------------------------------------------
/step-8-done/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/step-8-done/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:1.3.1'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | mavenLocal()
18 | jcenter()
19 | maven {
20 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
21 | url "$projectDir/../../node_modules/react-native/android"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/step-8-done/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | android.useDeprecatedNdk=true
21 |
--------------------------------------------------------------------------------
/step-8-done/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8-done/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/step-8-done/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
6 |
--------------------------------------------------------------------------------
/step-8-done/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'wines'
2 |
3 | include ':app'
4 |
--------------------------------------------------------------------------------
/step-8-done/android/wines.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/step-8-done/index.android.js:
--------------------------------------------------------------------------------
1 | import { AppRegistry } from 'react-native';
2 | import { App } from './src/app';
3 |
4 | AppRegistry.registerComponent('wines', () => App);
5 |
--------------------------------------------------------------------------------
/step-8-done/index.ios.js:
--------------------------------------------------------------------------------
1 | import { AppRegistry } from 'react-native';
2 | import { App } from './src/app';
3 |
4 | AppRegistry.registerComponent('wines', () => App);
5 |
--------------------------------------------------------------------------------
/step-8-done/ios/wines/AppDelegate.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | @interface AppDelegate : UIResponder
13 |
14 | @property (nonatomic, strong) UIWindow *window;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/step-8-done/ios/wines/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/step-8-done/ios/wines/main.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | #import "AppDelegate.h"
13 |
14 | int main(int argc, char * argv[]) {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/step-8-done/ios/winesTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/step-8-done/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wines",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "start": "node node_modules/react-native/local-cli/cli.js start",
7 | "install-android": "cd ./android && ./gradlew :app:installDebug",
8 | "run-adv": "$ANDROID_HOME/tools/emulator -netdelay none -netspeed full -avd reactnative",
9 | "start-android": "node node_modules/react-native/local-cli/cli.js run-android hot",
10 | "android-log": "adb logcat *:S ReactNative:V ReactNativeJS:V"
11 | },
12 | "dependencies": {
13 | "moment": "2.12.0",
14 | "react": "0.14.8",
15 | "react-native": "0.24.0-rc2",
16 | "react-redux": "4.4.1",
17 | "redux": "3.3.1",
18 | "redux-thunk": "2.0.1"
19 | },
20 | "devDependencies": {
21 | "eslint": "2.4.0",
22 | "eslint-plugin-react": "4.2.3"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/step-8-done/src/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react-native';
2 |
3 | import { Provider } from 'react-redux';
4 | import { createStore, applyMiddleware } from 'redux';
5 | import thunk from 'redux-thunk';
6 | import { app } from './reducers';
7 |
8 | import { WineApp } from './components/wine-app';
9 |
10 | const store = createStore(app, applyMiddleware(thunk));
11 |
12 | export const App = React.createClass({
13 | render() {
14 | return (
15 |
16 |
17 |
18 | );
19 | }
20 | });
21 |
--------------------------------------------------------------------------------
/step-8-done/src/components/button.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes, View, Text, StyleSheet } from 'react-native';
2 |
3 | const styles = StyleSheet.create({
4 | button: {
5 | borderColor: 'black',
6 | borderRadius: 4,
7 | borderWidth: 1,
8 | padding: 15,
9 | alignItems: 'center',
10 | justifyContent: 'center',
11 | alignItems: 'center',
12 | }
13 | });
14 |
15 | export const Button = React.createClass({
16 | propTypes: {
17 | action: PropTypes.func
18 | },
19 | onAction() {
20 | (this.props.action || function() {})();
21 | },
22 | render() {
23 | return (
24 |
25 | {this.props.title || this.props.children}
26 |
27 | );
28 | }
29 | });
30 |
--------------------------------------------------------------------------------
/step-8-done/src/components/liked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8-done/src/components/liked.png
--------------------------------------------------------------------------------
/step-8-done/src/components/loading.android.js:
--------------------------------------------------------------------------------
1 | import React, {
2 | PropTypes,
3 | ProgressBarAndroid,
4 | Text,
5 | View
6 | } from 'react-native';
7 | import { styles } from './style';
8 |
9 | export const Loading = React.createClass({
10 | propTypes: {
11 | what: PropTypes.string
12 | },
13 | render() {
14 | return(
15 |
16 |
17 |
18 | Loading {this.props.what}
19 |
20 |
24 |
25 |
26 | );
27 | }
28 | });
29 |
--------------------------------------------------------------------------------
/step-8-done/src/components/loading.ios.js:
--------------------------------------------------------------------------------
1 | import React, {
2 | PropTypes,
3 | ActivityIndicatorIOS,
4 | Text,
5 | View
6 | } from 'react-native';
7 | import { styles } from './style';
8 |
9 | export const Loading = React.createClass({
10 | propTypes: {
11 | what: PropTypes.string
12 | },
13 | render() {
14 | return(
15 |
16 |
17 |
18 | Loading {this.props.what}
19 |
20 |
24 |
25 |
26 | );
27 | }
28 | });
29 |
--------------------------------------------------------------------------------
/step-8-done/src/components/not-found.android.js:
--------------------------------------------------------------------------------
1 | import React, {
2 | View,
3 | Text
4 | } from 'react-native';
5 |
6 | export const NotFound = React.createClass({
7 | render() {
8 | return (
9 |
10 | Il semble que vous n'êtes pas au bon endroit !!!
11 |
12 | );
13 | }
14 | });
15 |
--------------------------------------------------------------------------------
/step-8-done/src/components/region-cell.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes, Text, TouchableHighlight, View } from 'react-native';
2 | import { styles } from './style';
3 |
4 | export const RegionCell = React.createClass({
5 | propTypes: {
6 | onSelect: PropTypes.func,
7 | region: PropTypes.string
8 | },
9 | render() {
10 | return (
11 |
12 |
13 |
14 | {this.props.region}
15 |
16 |
17 |
18 | );
19 | }
20 | });
21 |
--------------------------------------------------------------------------------
/step-8-done/src/components/unliked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8-done/src/components/unliked.png
--------------------------------------------------------------------------------
/step-8-done/src/components/wine-app.ios.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes, NavigatorIOS } from 'react-native';
2 | import { connect } from 'react-redux';
3 | import { Regions } from './regions';
4 | import { styles } from './style';
5 |
6 | const mapStateToProps = (state) => {
7 | return {
8 | title: state.title,
9 | httpState: state.http.state,
10 | httpError: state.http.error
11 | };
12 | }
13 |
14 | export const WineApp = connect(mapStateToProps)(React.createClass({
15 | propTypes: {
16 | children: PropTypes.element,
17 | dispatch: PropTypes.func.isRequired,
18 | httpError: PropTypes.string,
19 | httpState: PropTypes.string,
20 | title: PropTypes.string.isRequired
21 | },
22 |
23 | render() {
24 | return (
25 |
31 | );
32 | }
33 |
34 | }));
35 |
--------------------------------------------------------------------------------
/step-8-done/src/components/wine-cell.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes, Text, TouchableHighlight, View } from 'react-native';
2 | import { styles } from './style';
3 |
4 | export const WineCell = React.createClass({
5 | propTypes: {
6 | onSelect: PropTypes.func,
7 | wine: PropTypes.shape({
8 | name: PropTypes.string
9 | })
10 | },
11 | render() {
12 | return (
13 |
14 |
15 |
16 | {this.props.wine.name}
17 |
18 |
19 |
20 | );
21 | }
22 | });
23 |
--------------------------------------------------------------------------------
/step-8-done/src/reducers/comments.js:
--------------------------------------------------------------------------------
1 | export const comments = (state = { count: 0 }, action) => {
2 | switch (action.type) {
3 | case 'ADD_COMMENT':
4 | return Object.assign({}, state, { count: state.count + action.increment });
5 | case 'SET_COMMENTS':
6 | return Object.assign({}, state, { count: action.comments });
7 | default:
8 | return state;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/step-8-done/src/reducers/http.js:
--------------------------------------------------------------------------------
1 | export const http = (state = { state: 'LOADED', error: undefined }, action) => {
2 | switch (action.type) {
3 | case 'LOADING':
4 | return Object.assign({}, state, { state: 'LOADING', error: undefined });
5 | case 'LOADED':
6 | return Object.assign({}, state, { state: 'LOADED', error: undefined });
7 | case 'ERROR':
8 | return Object.assign({}, state, { state: 'ERROR', error: action.error });
9 | default:
10 | return state;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/step-8-done/src/reducers/index.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux';
2 | import { comments } from './comments';
3 | import { likes } from './likes';
4 | import { regions } from './regions';
5 | import { wines, currentWine } from './wines';
6 | import { title } from './title';
7 | import { http } from './http';
8 |
9 | /**
10 | * shape of the global state
11 | *
12 | * {
13 | * comments: {
14 | * count: 42
15 | * },
16 | * likes: {
17 | * count: 42
18 | * },
19 | * regions: {
20 | * lastUpdated: 0,
21 | * data: [...]
22 | * },
23 | * wines: {
24 | * bordeaux: {
25 | * lastUpdated: 0,
26 | * data: [...]
27 | * },
28 | * ...
29 | * },
30 | * currentWine: {
31 | * wine: {...},
32 | * liked: true,
33 | * comments: [...],
34 | * },
35 | * title: 'Bordeaux',
36 | * http: {
37 | * state: 'LOADING', // LOADED, ERROR
38 | * error: '...'
39 | * }
40 | * }
41 | */
42 |
43 | export const app = combineReducers({
44 | comments,
45 | likes,
46 | regions,
47 | wines,
48 | currentWine,
49 | title,
50 | http
51 | })
52 |
--------------------------------------------------------------------------------
/step-8-done/src/reducers/likes.js:
--------------------------------------------------------------------------------
1 | export const likes = (state = { count: 0 }, action) => {
2 | switch (action.type) {
3 | case 'ADD_LIKE':
4 | return Object.assign({}, state, { count: state.count + action.increment });
5 | case 'REMOVE_LIKE':
6 | return Object.assign({}, state, { count: state.count - action.decrement });
7 | case 'SET_LIKES':
8 | return Object.assign({}, state, { count: action.likes });
9 | default:
10 | return state;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/step-8-done/src/reducers/regions.js:
--------------------------------------------------------------------------------
1 | export const regions = (state = { data: [], lastUpdated: 0 }, action) => {
2 | switch (action.type) {
3 | case 'SET_REGIONS':
4 | return Object.assign({}, state, { data: action.regions });
5 | case 'UPDATE_REGIONS_TIMESTAMP':
6 | return Object.assign({}, state, { lastUpdated: Date.now() });
7 | default:
8 | return state;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/step-8-done/src/reducers/title.js:
--------------------------------------------------------------------------------
1 | export const title = (state = '', action) => {
2 | switch (action.type) {
3 | case 'SET_TITLE':
4 | return action.title;
5 | default:
6 | return state;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/step-8-done/src/reducers/wines.js:
--------------------------------------------------------------------------------
1 | export const wines = (state = {}, action) => {
2 | switch (action.type) {
3 | case 'SET_WINES':
4 | return Object.assign({}, state, { [action.region]: { lastUpdated: Date.now(), data: action.wines }});
5 | case 'UPDATE_WINES_TIMESTAMP':
6 | return Object.assign({}, state, Object.assign({}, state[action.region], { lastUpdated: Date.now() }));
7 | default:
8 | return state;
9 | }
10 | }
11 |
12 | export const currentWine = (state = { wine: undefined, comments: [], liked: false }, action) => {
13 | switch (action.type) {
14 | case 'SET_CURRENT_WINE':
15 | return Object.assign({}, state, { wine: action.wine, liked: false });
16 | case 'SET_CURRENT_COMMENTS':
17 | return Object.assign({}, state, { comments: action.comments });
18 | case 'SET_CURRENT_LIKED':
19 | return Object.assign({}, state, { liked: action.liked });
20 | default:
21 | return state;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/step-8/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | webpack.config.js
3 | public
4 | README.md
5 |
--------------------------------------------------------------------------------
/step-8/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | project.xcworkspace
24 |
25 | # Android/IJ
26 | #
27 | .idea
28 | .gradle
29 | local.properties
30 |
31 | # node.js
32 | #
33 | node_modules/
34 | npm-debug.log
35 |
--------------------------------------------------------------------------------
/step-8/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/step-8/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/step-8/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/step-8/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/step-8/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/step-8/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/step-8/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | wines
3 |
4 |
--------------------------------------------------------------------------------
/step-8/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/step-8/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:1.3.1'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | mavenLocal()
18 | jcenter()
19 | maven {
20 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
21 | url "$projectDir/../../node_modules/react-native/android"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/step-8/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | android.useDeprecatedNdk=true
21 |
--------------------------------------------------------------------------------
/step-8/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/step-8/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
6 |
--------------------------------------------------------------------------------
/step-8/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'wines'
2 |
3 | include ':app'
4 |
--------------------------------------------------------------------------------
/step-8/android/wines.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/step-8/index.android.js:
--------------------------------------------------------------------------------
1 | import { AppRegistry } from 'react-native';
2 | import { App } from './src/app';
3 |
4 | AppRegistry.registerComponent('wines', () => App);
5 |
--------------------------------------------------------------------------------
/step-8/index.ios.js:
--------------------------------------------------------------------------------
1 | import { AppRegistry } from 'react-native';
2 | import { App } from './src/app';
3 |
4 | AppRegistry.registerComponent('wines', () => App);
5 |
--------------------------------------------------------------------------------
/step-8/ios/wines/AppDelegate.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | @interface AppDelegate : UIResponder
13 |
14 | @property (nonatomic, strong) UIWindow *window;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/step-8/ios/wines/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/step-8/ios/wines/main.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | #import "AppDelegate.h"
13 |
14 | int main(int argc, char * argv[]) {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/step-8/ios/winesTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/step-8/live-reload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8/live-reload.png
--------------------------------------------------------------------------------
/step-8/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wines",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "start": "node node_modules/react-native/local-cli/cli.js start",
7 | "install-android": "cd ./android && ./gradlew :app:installDebug",
8 | "run-adv": "$ANDROID_HOME/tools/emulator -netdelay none -netspeed full -avd reactnative",
9 | "start-android": "node node_modules/react-native/local-cli/cli.js run-android hot",
10 | "android-log": "adb logcat *:S ReactNative:V ReactNativeJS:V"
11 | },
12 | "dependencies": {
13 | "moment": "2.12.0",
14 | "react": "0.14.8",
15 | "react-native": "0.24.0-rc2",
16 | "react-redux": "4.4.1",
17 | "redux": "3.3.1",
18 | "redux-thunk": "2.0.1"
19 | },
20 | "devDependencies": {
21 | "eslint": "2.4.0",
22 | "eslint-plugin-react": "4.2.3"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/step-8/reactnative-emulator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8/reactnative-emulator.png
--------------------------------------------------------------------------------
/step-8/regions-android.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8/regions-android.png
--------------------------------------------------------------------------------
/step-8/regions-ios.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8/regions-ios.png
--------------------------------------------------------------------------------
/step-8/src/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react-native';
2 | import thunk from 'redux-thunk';
3 |
4 | import { Provider } from 'react-redux';
5 | import { app } from './reducers';
6 | import { createStore, applyMiddleware } from 'redux';
7 |
8 | import { WineApp } from './components/wine-app';
9 |
10 | const store = createStore(app, applyMiddleware(thunk));
11 |
12 | export const App = React.createClass({
13 | render() {
14 | return (
15 |
16 |
17 |
18 | );
19 | }
20 | });
21 |
--------------------------------------------------------------------------------
/step-8/src/components/button.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes, View, Text, StyleSheet } from 'react-native';
2 |
3 | const styles = StyleSheet.create({
4 | button: {
5 | borderColor: 'black',
6 | borderRadius: 4,
7 | borderWidth: 1,
8 | padding: 15,
9 | alignItems: 'center',
10 | justifyContent: 'center'
11 | }
12 | });
13 |
14 | export const Button = React.createClass({
15 | propTypes: {
16 | action: PropTypes.func,
17 | style: PropTypes.object,
18 | title: PropTypes.string,
19 | titleStyle: PropTypes.object
20 | },
21 | getDefaultProps() {
22 | return {
23 | action() {},
24 | style: {},
25 | titleStyle: {},
26 | title: ''
27 | };
28 | },
29 | handleAction() {
30 | (this.props.action || function() {})();
31 | },
32 | render() {
33 | return (
34 |
37 |
40 | {this.props.title || this.props.children}
41 |
42 |
43 | );
44 | }
45 | });
46 |
--------------------------------------------------------------------------------
/step-8/src/components/comments.js:
--------------------------------------------------------------------------------
1 | /* eslint react/no-multi-comp: 0, react/jsx-max-props-per-line: 0 */
2 |
3 | import React, { PropTypes, View, Text, TextInput } from 'react-native';
4 | import moment from 'moment';
5 | import { connect } from 'react-redux';
6 | import { addComment, fetchComments, postComment } from '../actions';
7 | import { styles } from './style';
8 | import { Button } from './button';
9 |
10 | const mapStateToProps = (state) => {
11 | return {
12 | comments: state.currentWine.comments
13 | };
14 | }
15 |
16 | export const Comments = connect(mapStateToProps)(React.createClass({
17 | getInitialState() {
18 | return {
19 | commentTitle: '',
20 | commentBody: ''
21 | };
22 | },
23 |
24 | handlePostComment() {
25 | const payload = { title: this.state.commentTitle, content: this.state.commentBody };
26 | this.props.dispatch(postComment(this.props.wineId, payload)).then(() => {
27 | this.setState({ commentTitle: '', commentBody: '' });
28 | });
29 | },
30 |
31 | render() {
32 | return (
33 | comments
34 | );
35 | }
36 | }));
37 |
--------------------------------------------------------------------------------
/step-8/src/components/liked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8/src/components/liked.png
--------------------------------------------------------------------------------
/step-8/src/components/loading.android.js:
--------------------------------------------------------------------------------
1 | import React, {
2 | PropTypes,
3 | ProgressBarAndroid,
4 | Text,
5 | View
6 | } from 'react-native';
7 | import { styles } from './style';
8 |
9 | export const Loading = React.createClass({
10 | propTypes: {
11 | what: PropTypes.string
12 | },
13 | render() {
14 | return(
15 |
16 |
17 |
18 | Loading {this.props.what}
19 |
20 |
24 |
25 |
26 | );
27 | }
28 | });
29 |
--------------------------------------------------------------------------------
/step-8/src/components/loading.ios.js:
--------------------------------------------------------------------------------
1 | import React, {
2 | PropTypes,
3 | ActivityIndicatorIOS,
4 | Text,
5 | View
6 | } from 'react-native';
7 | import { styles } from './style';
8 |
9 | export const Loading = React.createClass({
10 | propTypes: {
11 | what: PropTypes.string
12 | },
13 | render() {
14 | return(
15 |
16 |
17 |
18 | Loading {this.props.what}
19 |
20 |
24 |
25 |
26 | );
27 | }
28 | });
29 |
--------------------------------------------------------------------------------
/step-8/src/components/region-cell.js:
--------------------------------------------------------------------------------
1 | import React, { Text } from 'react-native';
2 |
3 | export const RegionCell = React.createClass({
4 | render() {
5 | return (
6 | Item
7 | );
8 | }
9 | });
10 |
--------------------------------------------------------------------------------
/step-8/src/components/regions.js:
--------------------------------------------------------------------------------
1 | /* eslint react/jsx-no-bind: 0, react/no-multi-comp: 0, react/jsx-closing-bracket-location: 0 */
2 |
3 | import React from 'react-native';
4 |
5 | import { connect } from 'react-redux';
6 |
7 | const mapStateToProps = (state) => {
8 | return {
9 | regions: state.regions.data
10 | };
11 | }
12 |
13 | export const Regions = connect(mapStateToProps)(React.createClass({
14 | render() {
15 | return (
16 | Items
17 | );
18 | }
19 | }));
20 |
--------------------------------------------------------------------------------
/step-8/src/components/unliked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8/src/components/unliked.png
--------------------------------------------------------------------------------
/step-8/src/components/wine-app.android.js:
--------------------------------------------------------------------------------
1 | import React, { Navigator, BackAndroid } from 'react-native';
2 | import { Loading } from './loading';
3 |
4 | export const WineApp = React.createClass({
5 | componentWillUnmount() {
6 | BackAndroid.removeEventListener('hardwareBackPress', this.handleBackButton);
7 | },
8 |
9 | handleBackButton() {
10 | if (!this.isOnMainScreen) {
11 | this.navigator.pop();
12 | return true;
13 | }
14 | return false;
15 | },
16 |
17 | configureScene(route) {
18 | if (route.sceneConfig) {
19 | return route.sceneConfig;
20 | }
21 | return Navigator.SceneConfigs.FloatFromBottom;
22 | },
23 |
24 | renderScene(route, nav) {
25 | if (!this.navigator) {
26 | this.navigator = nav;
27 | BackAndroid.addEventListener('hardwareBackPress', this.handleBackButton);
28 | }
29 | // return view for each route
30 | },
31 |
32 | render() {
33 | return (
34 |
35 | );
36 | }
37 | });
38 |
--------------------------------------------------------------------------------
/step-8/src/components/wine-app.ios.js:
--------------------------------------------------------------------------------
1 | import React from 'react-native';
2 | import { Loading } from './loading';
3 |
4 | export const WineApp = React.createClass({
5 | render() {
6 | return (
7 |
8 | );
9 | }
10 | });
11 |
--------------------------------------------------------------------------------
/step-8/src/components/wine-cell.js:
--------------------------------------------------------------------------------
1 | import React, { Text } from 'react-native';
2 |
3 | export const WineCell = React.createClass({
4 | render() {
5 | return (
6 | Item
7 | );
8 | }
9 | });
10 |
--------------------------------------------------------------------------------
/step-8/src/components/wine-list.js:
--------------------------------------------------------------------------------
1 | /* eslint react/jsx-no-bind: 0, react/no-multi-comp: 0, react/jsx-closing-bracket-location: 0 */
2 |
3 | import React from 'react-native';
4 |
5 | import { connect } from 'react-redux';
6 |
7 | const mapStateToProps = (state) => {
8 | return {
9 | wines: state.wines
10 | };
11 | }
12 |
13 | export const WineList = connect(mapStateToProps)(React.createClass({
14 | render() {
15 | return (
16 | Items
17 | );
18 | }
19 | }));
20 |
--------------------------------------------------------------------------------
/step-8/src/components/wine.js:
--------------------------------------------------------------------------------
1 | /* eslint react/no-multi-comp: 0, react/jsx-max-props-per-line: 0 */
2 |
3 | import React, { PropTypes, Image, View, Text, ScrollView, TouchableWithoutFeedback } from 'react-native';
4 | import { connect } from 'react-redux';
5 | import { fetchWine, fetchWineLiked, setTitle, toggleWineLiked } from '../actions';
6 | import { styles } from './style';
7 | import { Comments } from './comments';
8 | import { apiHost } from '../actions';
9 |
10 | const mapStateToProps = (state) => {
11 | return {
12 | currentWine: state.currentWine.wine,
13 | liked: state.currentWine.liked
14 | };
15 | }
16 |
17 | export const Wine = connect(mapStateToProps)(React.createClass({
18 | componentDidMount() {
19 | this.props.dispatch(fetchWine(this.props.wine.id)).then(() => {
20 | this.props.dispatch(fetchWineLiked(this.props.wine.id));
21 | });
22 | },
23 |
24 | handleToggleLike() {
25 | this.props.dispatch(toggleWineLiked(this.props.wine.id));
26 | },
27 |
28 | render() {
29 | const { wine, liked } = this.props;
30 | return (
31 | Wine
32 | );
33 | }
34 | }));
35 |
--------------------------------------------------------------------------------
/step-8/src/reducers/comments.js:
--------------------------------------------------------------------------------
1 | export const comments = (state = { count: 0 }, action) => {
2 | switch (action.type) {
3 | case 'ADD_COMMENT':
4 | return Object.assign({}, state, { count: state.count + action.increment });
5 | case 'SET_COMMENTS':
6 | return Object.assign({}, state, { count: action.comments });
7 | default:
8 | return state;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/step-8/src/reducers/http.js:
--------------------------------------------------------------------------------
1 | export const http = (state = { state: 'LOADED', error: undefined }, action) => {
2 | switch (action.type) {
3 | case 'LOADING':
4 | return Object.assign({}, state, { state: 'LOADING', error: undefined });
5 | case 'LOADED':
6 | return Object.assign({}, state, { state: 'LOADED', error: undefined });
7 | case 'ERROR':
8 | return Object.assign({}, state, { state: 'ERROR', error: action.error });
9 | default:
10 | return state;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/step-8/src/reducers/index.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux';
2 | import { comments } from './comments';
3 | import { likes } from './likes';
4 | import { regions } from './regions';
5 | import { wines, currentWine } from './wines';
6 | import { title } from './title';
7 | import { http } from './http';
8 |
9 | /**
10 | * shape of the global state
11 | *
12 | * {
13 | * comments: {
14 | * count: 42
15 | * },
16 | * likes: {
17 | * count: 42
18 | * },
19 | * regions: {
20 | * lastUpdated: 0,
21 | * data: [...]
22 | * },
23 | * wines: {
24 | * bordeaux: {
25 | * lastUpdated: 0,
26 | * data: [...]
27 | * },
28 | * ...
29 | * },
30 | * currentWine: {
31 | * wine: {...},
32 | * liked: true,
33 | * comments: [...],
34 | * },
35 | * title: 'Bordeaux',
36 | * http: {
37 | * state: 'LOADING', // LOADED, ERROR
38 | * error: '...'
39 | * }
40 | * }
41 | */
42 |
43 | export const app = combineReducers({
44 | comments,
45 | likes,
46 | regions,
47 | wines,
48 | currentWine,
49 | title,
50 | http
51 | })
52 |
--------------------------------------------------------------------------------
/step-8/src/reducers/likes.js:
--------------------------------------------------------------------------------
1 | export const likes = (state = { count: 0 }, action) => {
2 | switch (action.type) {
3 | case 'ADD_LIKE':
4 | return Object.assign({}, state, { count: state.count + action.increment });
5 | case 'REMOVE_LIKE':
6 | return Object.assign({}, state, { count: state.count - action.decrement });
7 | case 'SET_LIKES':
8 | return Object.assign({}, state, { count: action.likes });
9 | default:
10 | return state;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/step-8/src/reducers/regions.js:
--------------------------------------------------------------------------------
1 | export const regions = (state = { data: [], lastUpdated: 0 }, action) => {
2 | switch (action.type) {
3 | case 'SET_REGIONS':
4 | return Object.assign({}, state, { data: action.regions });
5 | case 'UPDATE_REGIONS_TIMESTAMP':
6 | return Object.assign({}, state, { lastUpdated: Date.now() });
7 | default:
8 | return state;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/step-8/src/reducers/title.js:
--------------------------------------------------------------------------------
1 | export const title = (state = '', action) => {
2 | switch (action.type) {
3 | case 'SET_TITLE':
4 | return action.title;
5 | default:
6 | return state;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/step-8/src/reducers/wines.js:
--------------------------------------------------------------------------------
1 | export const wines = (state = {}, action) => {
2 | switch (action.type) {
3 | case 'SET_WINES':
4 | return Object.assign({}, state, { [action.region]: { lastUpdated: Date.now(), data: action.wines }});
5 | case 'UPDATE_WINES_TIMESTAMP':
6 | return Object.assign({}, state, Object.assign({}, state[action.region], { lastUpdated: Date.now() }));
7 | default:
8 | return state;
9 | }
10 | }
11 |
12 | export const currentWine = (state = { wine: undefined, comments: [], liked: false }, action) => {
13 | switch (action.type) {
14 | case 'SET_CURRENT_WINE':
15 | return Object.assign({}, state, { wine: action.wine, liked: false });
16 | case 'SET_CURRENT_COMMENTS':
17 | return Object.assign({}, state, { comments: action.comments });
18 | case 'SET_CURRENT_LIKED':
19 | return Object.assign({}, state, { liked: action.liked });
20 | default:
21 | return state;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/step-8/wine-liked-android.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8/wine-liked-android.png
--------------------------------------------------------------------------------
/step-8/wine-liked-ios.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8/wine-liked-ios.png
--------------------------------------------------------------------------------
/step-8/wine-unliked-android.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8/wine-unliked-android.png
--------------------------------------------------------------------------------
/step-8/wine-unliked-ios.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8/wine-unliked-ios.png
--------------------------------------------------------------------------------
/step-8/wines-android.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8/wines-android.png
--------------------------------------------------------------------------------
/step-8/wines-ios.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathieuancelin/react-workshop/59b3e809eaa4392f4f5c66c9bb5d0f460cff73ad/step-8/wines-ios.png
--------------------------------------------------------------------------------
/test-all-done.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | APP_PATH=`pwd`
4 |
5 | cd "$APP_PATH/step-1-done"
6 | npm test
7 | cd "$APP_PATH/step-2-done"
8 | npm test
9 | cd "$APP_PATH/step-3-done"
10 | npm test
11 | cd "$APP_PATH/step-4-done"
12 | npm test
13 | cd "$APP_PATH/step-5-done"
14 | npm test
15 | cd "$APP_PATH/step-6-done"
16 | npm test
17 | cd "$APP_PATH/step-7"
18 | npm test
19 |
20 | cd "$APP_PATH"
21 |
--------------------------------------------------------------------------------
/test-all-undone.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | APP_PATH=`pwd`
4 |
5 | cd "$APP_PATH/step-2"
6 | npm test
7 | cd "$APP_PATH/step-3"
8 | npm test
9 | cd "$APP_PATH/step-4"
10 | npm test
11 | cd "$APP_PATH/step-5"
12 | npm test
13 | cd "$APP_PATH/step-6"
14 | npm test
15 | cd "$APP_PATH/step-7"
16 | npm test
17 |
18 | cd "$APP_PATH"
19 |
--------------------------------------------------------------------------------