├── src
├── sass
│ ├── styles.scss
│ ├── _basic.scss
│ └── _beanStyles.scss
├── js
│ ├── flux
│ │ ├── alt.js
│ │ ├── stores
│ │ │ ├── BeanListStore.js
│ │ │ └── BeanItemStore.js
│ │ └── actions
│ │ │ ├── BeanItemActions.js
│ │ │ └── BeanListActions.js
│ ├── index.js
│ ├── react
│ │ ├── router.js
│ │ ├── pages
│ │ │ ├── BeanItemEditPage.js
│ │ │ ├── BeanListPage.js
│ │ │ └── BeanItemPage.js
│ │ ├── components
│ │ │ ├── BeanPowerListItem.js
│ │ │ ├── BeanListItem.js
│ │ │ └── BeanProfile.js
│ │ ├── routes.js
│ │ └── App.js
│ └── api
│ │ ├── BeanWebAPI.js
│ │ └── EXAMPLE_DATA.js
└── image
│ └── bean_stencil.png
├── .gitignore
├── public
├── image
│ └── bean_stencil.png
└── stylesheets
│ ├── styles.min.css
│ └── styles.css
├── gulpfile.js
├── gulp
├── tasks
│ ├── clean.js
│ ├── watch.js
│ ├── liveserver.js
│ ├── webserver.js
│ ├── webpack.js
│ ├── reloadserver.js
│ ├── images.js
│ ├── xDEPx_reactscripts.js
│ ├── _default.js
│ ├── xDEPx_scripts.js
│ └── styles.js
└── webpack.config.js
├── index.html
├── README.md
├── package.json
└── npm-debug.log
/src/sass/styles.scss:
--------------------------------------------------------------------------------
1 | @import "basic";
2 | @import "beanStyles";
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /.idea
3 | /.sass-cache
4 | /_projectfiles
--------------------------------------------------------------------------------
/src/js/flux/alt.js:
--------------------------------------------------------------------------------
1 | var Alt = require('alt');
2 |
3 | var alt = new Alt();
4 |
5 | module.exports = alt;
--------------------------------------------------------------------------------
/src/image/bean_stencil.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lostpebble/alt-react-router-example/HEAD/src/image/bean_stencil.png
--------------------------------------------------------------------------------
/public/image/bean_stencil.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lostpebble/alt-react-router-example/HEAD/public/image/bean_stencil.png
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var requireDir = require('require-dir');
2 | var gulp = require('gulp');
3 |
4 | requireDir('./gulp/tasks', {recurse: true});
--------------------------------------------------------------------------------
/gulp/tasks/clean.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var del = require('del');
3 |
4 | gulp.task('clean', function(cb) {
5 | del(['public/stylesheets', 'public/js', 'public/images'], cb);
6 | });
--------------------------------------------------------------------------------
/src/sass/_basic.scss:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: sans-serif;
3 | color: #091521;
4 | background-color : #fffefd;
5 | }
6 |
7 | ul {
8 | list-style-type: none;
9 | padding: 0px;
10 | }
--------------------------------------------------------------------------------
/gulp/tasks/watch.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 |
3 | gulp.task('watch', function() {
4 | gulp.watch('src/sass/**/*.scss', ['styles']);
5 | gulp.watch('src/image/**/*', ['images']);
6 | });
--------------------------------------------------------------------------------
/src/js/index.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var router = require('./react/router');
3 |
4 | router.run((Handler, state) => {
5 | React.render(, document.body);
6 | });
--------------------------------------------------------------------------------
/src/js/react/router.js:
--------------------------------------------------------------------------------
1 | var ReactRouter = require('react-router');
2 | var routes = require('./routes');
3 |
4 | var router = ReactRouter.create({
5 | location : ReactRouter.HashLocation,
6 | routes : routes
7 | });
8 |
9 | module.exports = router;
--------------------------------------------------------------------------------
/gulp/tasks/liveserver.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 |
3 | // Starts webserver
4 | //
5 | // Reloads server on changes to output folder
6 |
7 | gulp.task('liveserver', ['webserver'], function() {
8 | gulp.watch('./public/**/*', ['reloadserver']);
9 | });
--------------------------------------------------------------------------------
/gulp/tasks/webserver.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var connect = require('gulp-connect');
3 |
4 | var webserverOptions = {
5 | livereload : true,
6 | root : [__dirname+"/../../"]
7 | };
8 |
9 | gulp.task('webserver', function() {
10 | connect.server(webserverOptions);
11 | });
--------------------------------------------------------------------------------
/gulp/tasks/webpack.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var webpack = require("gulp-webpack");
3 | var webpackconfig = require("../webpack.config");
4 |
5 | gulp.task("webpack", function() {
6 | return gulp.src('./src/js/index.js')
7 | .pipe(webpack(webpackconfig))
8 | .pipe(gulp.dest('public/js/'));
9 | });
10 |
--------------------------------------------------------------------------------
/gulp/tasks/reloadserver.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var connect = require('gulp-connect');
3 | var notify = require('gulp-notify');
4 |
5 | gulp.task('reloadserver', function() {
6 | gulp.src("index.html")
7 | .pipe(connect.reload())
8 | .pipe(notify({message: "Server reloaded"}));
9 | });
--------------------------------------------------------------------------------
/gulp/tasks/images.js:
--------------------------------------------------------------------------------
1 | gulp = require('gulp');
2 | imagemin = require('gulp-imagemin');
3 | notify = require('gulp-notify');
4 |
5 | gulp.task('images', function() {
6 | return gulp.src('src/image/*')
7 | .pipe(imagemin({
8 | progressive: true
9 | }))
10 | .pipe(gulp.dest('public/image'))
11 | .pipe(notify({message: "Image task complete"}));
12 | });
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | alt react-router example
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/js/react/pages/BeanItemEditPage.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | // Editing beans is not implemented yet
4 | // Todo: Make the edit page
5 |
6 | var BeanItemEditPage = React.createClass({
7 | render() {
8 | return (
9 |
10 |
e.d.i.t.i.n.g bean : {this.props.params.beanID}
11 |
12 | );
13 | }
14 | });
15 |
16 | module.exports = BeanItemEditPage;
--------------------------------------------------------------------------------
/gulp/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 |
3 | module.exports = {
4 | entry: [
5 | './src/js/index'
6 | ],
7 | output: {
8 | filename: 'bundle.js'
9 | },
10 | resolve: {
11 | extensions: ['', '.js', '.jsx']
12 | },
13 | watch: true,
14 | module: {
15 | loaders: [
16 | { test: /\.js$/, loaders: ['jsx?harmony'], exclude: /node_modules/ }
17 | ]
18 | }
19 | };
20 |
--------------------------------------------------------------------------------
/src/js/react/components/BeanPowerListItem.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var BeanPowerListItem = React.createClass({
4 |
5 | render() {
6 | return(
7 |
8 | {this.props.power.power_name}
9 | {this.props.power.power_description}
10 |
11 | )
12 | }
13 | });
14 |
15 | module.exports = BeanPowerListItem;
--------------------------------------------------------------------------------
/src/js/react/components/BeanListItem.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var { Link } = require('react-router');
3 |
4 | var BeanListItem = React.createClass({
5 |
6 | render() {
7 | var itemStyle = {
8 | color: this.props.bean.bean_color
9 | };
10 |
11 | return(
12 |
13 |
14 | {this.props.bean.bean_name}
15 |
16 |
17 | )
18 | }
19 | });
20 |
21 | module.exports = BeanListItem;
--------------------------------------------------------------------------------
/src/js/flux/stores/BeanListStore.js:
--------------------------------------------------------------------------------
1 | var BeanListActions = require('../actions/BeanListActions');
2 | var alt = require('../alt');
3 |
4 | class BeanListStore {
5 | constructor() {
6 | this.bindActions(BeanListActions);
7 |
8 | this.loadingBeanList = false;
9 | this.beanList = [];
10 | }
11 |
12 | onRequestBeanList() {
13 | this.loadingBeanList = true;
14 | }
15 |
16 | onReceiveBeanList(rawList) {
17 | this._init(rawList);
18 | this.loadingBeanList = false;
19 | }
20 |
21 | _init(rawList) {
22 | this.beanList = rawList;
23 | }
24 | }
25 |
26 | module.exports = alt.createStore(BeanListStore);
--------------------------------------------------------------------------------
/gulp/tasks/xDEPx_reactscripts.js:
--------------------------------------------------------------------------------
1 | // DEPRECIATED : only here if you decide to switch the JS bundling to Gulp again for some reason
2 | //
3 | // Remember to add the required packages back into your package.json file
4 | //
5 | //var gulp = require('gulp');
6 | //var concat = require('gulp-concat');
7 | //var notify = require('gulp-notify');
8 | //var react = require('gulp-react');
9 | //
10 | //gulp.task('reactscripts', function() {
11 | // return gulp.src('src/react/**/*.jsx')
12 | // .pipe(react())
13 | // .pipe(concat('reactscripts.js'))
14 | // .pipe(gulp.dest('src/scripts'))
15 | // .pipe(notify({ message: 'React task complete' }));
16 | //});
--------------------------------------------------------------------------------
/src/js/react/routes.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var { Route, DefaultRoute } = require('react-router');
3 |
4 | var App = require('./App');
5 |
6 | var BeanListPage = require('./pages/BeanListPage');
7 | var BeanItemPage = require('./pages/BeanItemPage');
8 | var BeanItemEditPage = require('./pages/BeanItemEditPage');
9 |
10 | var routes = (
11 |
12 |
13 |
14 |
15 |
16 | );
17 |
18 | module.exports = routes;
--------------------------------------------------------------------------------
/gulp/tasks/_default.js:
--------------------------------------------------------------------------------
1 | gulp = require('gulp');
2 | runSequence = require('run-sequence');
3 |
4 | // DEFAULT TASK
5 | // ************
6 | //
7 | // { CLEANS output folders } then
8 | // { COMPILES images, scripts and styles } and
9 | // { WATCHES images, scripts and styles for changes }
10 | //
11 | // TASKS
12 | //
13 | // clean output folders : clean
14 | // compile images : images
15 | // javascript compile + watch : webpack
16 | // styles compile : styles
17 | // styles and images watch : watch
18 |
19 | gulp.task('default', ['clean'], function() {
20 | runSequence( ['images', 'webpack', 'styles', 'watch'] );
21 | });
--------------------------------------------------------------------------------
/src/js/react/App.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var { RouteHandler, Link } = require('react-router');
3 | var { PropTypes } = React;
4 |
5 | var App = React.createClass({
6 |
7 | propTypes: {
8 | params: PropTypes.object.isRequired,
9 | query: PropTypes.object.isRequired
10 | },
11 |
12 | render: function() {
13 | return (
14 |
15 |
Beans of War
16 |
19 |
20 |
21 | );
22 | }
23 | });
24 |
25 | module.exports = App;
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | alt react-router example
2 | ========================
3 |
4 | An example project showing a way to create react-router React projects with the Alt flux implementation.
5 |
6 | ### Install and run
7 |
8 | ```
9 | npm install
10 | npm start
11 | ```
12 |
13 | ### Building on top of this project
14 |
15 | I used gulp to compile all the scripts (forwarded to webpack), images and the SCSS styles.
16 |
17 | To compile and watch scripts, styles and images just run:
18 | ```
19 | gulp
20 | ```
21 |
22 | Then, to start a live server, in a different console window, you can run **either**:
23 | ```
24 | gulp liveserver
25 | npm start
26 | ```
27 |
28 | This also will refresh the live server if any changes to scripts, styles or images are detected.
--------------------------------------------------------------------------------
/gulp/tasks/xDEPx_scripts.js:
--------------------------------------------------------------------------------
1 | // DEPRECIATED : only here if you decide to switch the JS bundling to Gulp again for some reason
2 | //
3 | // Remember to add the required packages back into your package.json file
4 | //
5 | //var gulp = require('gulp');
6 | //var concat = require('gulp-concat');
7 | //var notify = require('gulp-notify');
8 | //var rename = require('gulp-rename');
9 | //var uglify = require('gulp-uglify');
10 | //var connect = require('gulp-connect');
11 | //
12 | //gulp.task('scripts', function() {
13 | // return gulp.src('src/scripts/**/*.js')
14 | // .pipe(concat('main.js'))
15 | // .pipe(gulp.dest('public/js'))
16 | // .pipe(rename({suffix: '.min'}))
17 | // .pipe(uglify())
18 | // .pipe(gulp.dest('public/js'))
19 | // .pipe(notify({ message: 'Scripts task complete' }))
20 | // .pipe(connect.reload());
21 | //});
--------------------------------------------------------------------------------
/src/js/flux/stores/BeanItemStore.js:
--------------------------------------------------------------------------------
1 | var alt = require('../alt');
2 | var BeanItemActions = require('../actions/BeanItemActions');
3 |
4 | class BeanItemStore {
5 | constructor() {
6 | this.bindActions(BeanItemActions);
7 |
8 | this.loadingBeanItem = false;
9 | this.beanItem = {};
10 | this.beanItemError = null;
11 | }
12 |
13 | onRequestBeanItem() {
14 | this.loadingBeanItem = true;
15 | this.beanItemError = null;
16 | }
17 |
18 | onReceiveBeanItem(rawBeanItem) {
19 | this._init(rawBeanItem);
20 | this.loadingBeanItem = false;
21 | }
22 |
23 | onReceiveBeanItemError(error) {
24 | this.beanItemError = error;
25 | this.loadingBeanItem = false;
26 | }
27 |
28 | _init(rawBeanItem) {
29 | this.beanItem = rawBeanItem;
30 | }
31 | }
32 |
33 | module.exports = alt.createStore(BeanItemStore);
--------------------------------------------------------------------------------
/src/js/flux/actions/BeanItemActions.js:
--------------------------------------------------------------------------------
1 | var alt = require('../alt');
2 | var BeanWebAPI = require('../../api/BeanWebAPI');
3 |
4 | class BeanItemActions {
5 |
6 | receiveBeanItem(beanItem) {
7 | this.dispatch(beanItem);
8 | }
9 |
10 | receiveBeanItemError(error) {
11 | this.dispatch(error);
12 | }
13 |
14 | requestBeanItem(beanID) {
15 | var actionDispatcher = this;
16 |
17 | actionDispatcher.dispatch();
18 |
19 | BeanWebAPI.requestBeanItem(beanID).then(function(beanItem) {
20 |
21 | actionDispatcher.actions.receiveBeanItem(beanItem);
22 | console.log("received bean item");
23 |
24 | }).catch(function(error) {
25 |
26 | actionDispatcher.actions.receiveBeanItemError(error);
27 | console.log(error);
28 |
29 | });
30 |
31 | console.log("requested bean item");
32 | }
33 | }
34 |
35 | module.exports = alt.createActions(BeanItemActions);
--------------------------------------------------------------------------------
/gulp/tasks/styles.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var sass = require('gulp-ruby-sass');
3 | var autoprefixer = require('gulp-autoprefixer');
4 | var rename = require('gulp-rename');
5 | var minifycss = require('gulp-minify-css');
6 | var notify = require('gulp-notify');
7 |
8 | var autoprefixerCompatibility =
9 | ['> 1%',
10 | 'last 2 versions',
11 | 'Opera >= 12',
12 | 'Chrome >= 25',
13 | 'Firefox >= 13',
14 | 'ie >= 9'];
15 |
16 | gulp.task('styles', function() {
17 | return gulp.src('src/sass/styles.scss')
18 | .pipe(sass({ style: 'expanded', "sourcemap=none": true }))
19 | .pipe(autoprefixer({browsers: autoprefixerCompatibility, cascade: false}))
20 | .pipe(gulp.dest('public/stylesheets'))
21 | .pipe(rename({suffix: '.min'}))
22 | .pipe(minifycss())
23 | .pipe(gulp.dest('public/stylesheets'))
24 | .pipe(notify({ message:'Styles task complete' }));
25 | });
--------------------------------------------------------------------------------
/src/js/flux/actions/BeanListActions.js:
--------------------------------------------------------------------------------
1 | var alt = require('../alt');
2 | var BeanWebAPI = require('../../api/BeanWebAPI');
3 |
4 | class BeanListActions {
5 |
6 | receiveBeanList(list) {
7 | this.dispatch(list);
8 | }
9 |
10 | requestBeanList() {
11 | // Have to reference "this" so we can call
12 | // our own actions inside the promise return
13 | var actionDispatcher = this;
14 |
15 | // Call this action
16 | actionDispatcher.dispatch();
17 |
18 | // Promise is returned, when resolved call the received bean list action
19 | BeanWebAPI.requestBeanList().then(function(list) {
20 |
21 | actionDispatcher.actions.receiveBeanList(list);
22 | console.log("received the bean list");
23 |
24 | }).catch(function(error) {
25 | console.log(error);
26 | });
27 |
28 | console.log("requested the bean list");
29 | }
30 | }
31 |
32 | module.exports = alt.createActions(BeanListActions);
33 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "alt-react-router-example",
3 | "version": "1.0.0",
4 | "description": "Starter for React projects",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "start": "gulp liveserver"
9 | },
10 | "author": "Paul Myburgh",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "del": "^1.1.0",
14 | "gulp": "^3.8.10",
15 | "gulp-autoprefixer": "^2.0.0",
16 | "gulp-connect": "^2.2.0",
17 | "gulp-imagemin": "^2.0.0",
18 | "gulp-minify-css": "^0.3.11",
19 | "gulp-notify": "^2.0.1",
20 | "gulp-rename": "^1.2.0",
21 | "gulp-ruby-sass": "^0.7.1",
22 | "gulp-webpack": "^1.2.0",
23 | "jsx-loader": "^0.12.2",
24 | "require-dir": "^0.1.0",
25 | "run-sequence": "^1.0.2"
26 | },
27 | "dependencies": {
28 | "alt": "^0.16.7",
29 | "node-libs-browser": "^0.5.2",
30 | "react": "^0.13.3",
31 | "react-router": "^0.13.3",
32 | "webpack": "^1.9.10"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/public/stylesheets/styles.min.css:
--------------------------------------------------------------------------------
1 | body{font-family:sans-serif;color:#091521;background-color:#fffefd}ul{list-style-type:none;padding:0}li.bean-list-item{display:block;float:left;font-size:3em;background-color:#F8FBFC;border:1px solid #cce7f3;margin-right:5px;margin-top:5px;border-radius:6px;padding:6px 13px}li.bean-list-item:hover{background-color:#fff;border-bottom:1px solid #b0b9d1;border-top:1px solid #bcc5dd;box-shadow:0 0 17px rgba(90,110,120,.2);-webkit-transition:box-shadow .3s;-moz-transition:box-shadow .3s;-o-transition:box-shadow .3s;transition:box-shadow .3s;cursor:pointer}span.power-name{font-style:italic;font-weight:700;margin-right:20px}.bean-item-page{text-align:center}.bean-item-page .error{color:red;margin:30px}.bean-item-page .loading-element{font-size:2em;margin:20px}.navigation{padding:10px}.navigation a{text-decoration:none;color:#fbfbfb}.navigation .navigation-item{font-weight:700;display:inline;font-size:1.5em;padding:5px;background-color:#9a9ea4;-webkit-transition:.3s linear;-moz-transition:.3s linear;-o-transition:.3s linear;transition:.3s linear}.navigation .navigation-item:hover{background-color:#afb3b9}
--------------------------------------------------------------------------------
/src/js/api/BeanWebAPI.js:
--------------------------------------------------------------------------------
1 | var fakeData = require('./EXAMPLE_DATA');
2 |
3 | // Emulate API requests
4 |
5 | class BeanWebApi {
6 |
7 | // API requests using the Promise interface
8 |
9 | // TODO: caching data that has already been received from the server
10 |
11 | static requestBeanList() {
12 | return new Promise(function(resolve, reject) {
13 |
14 | setTimeout(function() {
15 | resolve(fakeData.getList);
16 | }, Math.random() * 2000 + 1000);
17 |
18 | // Short timeout for testing
19 | /*setTimeout(function() {
20 | resolve(fakeData.getList);
21 | }, 1);*/
22 | });
23 | }
24 |
25 | static requestBeanItem(beanID) {
26 | return new Promise(function(resolve, reject) {
27 |
28 | setTimeout(function() {
29 | if (fakeData.getBean[beanID]) {
30 | resolve(fakeData.getBean[beanID]);
31 | } else {
32 | reject("Bean item does not exist");
33 | }
34 |
35 | }, Math.random() * 700 + 100);
36 | });
37 | }
38 | }
39 |
40 | module.exports = BeanWebApi;
--------------------------------------------------------------------------------
/src/js/react/components/BeanProfile.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var BeanPowerListItem = require('./BeanPowerListItem');
3 |
4 | var BeanProfile = React.createClass({
5 |
6 | render() {
7 | var beanColor = this.props.beanItem.bean_color;
8 |
9 | var imgStyle = {
10 | backgroundColor : beanColor
11 | };
12 |
13 | var spanStyle = {
14 | color: beanColor
15 | };
16 |
17 | if (this.props.beanItem.bean_powers) {
18 | var beanPowers = this.props.beanItem.bean_powers.map(function(power) {
19 | return (
20 |
21 | )
22 | });
23 | }
24 |
25 | return (
26 |
27 |

28 |
The {this.props.beanItem.bean_name} bean
29 |
{this.props.beanItem.bean_description}
30 |
34 |
35 | )
36 | }
37 | });
38 |
39 | module.exports = BeanProfile;
--------------------------------------------------------------------------------
/src/sass/_beanStyles.scss:
--------------------------------------------------------------------------------
1 | li.bean-list-item {
2 | display: block;
3 | float: left;
4 | font-size: 3em;
5 | background-color: #F8FBFC;
6 | border: 1px solid #cce7f3;
7 | // border-bottom: 2px solid white;
8 | margin-right: 5px;
9 | margin-top: 5px;
10 | border-radius: 6px;
11 | padding: 6px 13px;
12 | }
13 |
14 | li.bean-list-item:hover {
15 | background-color: white;
16 | border-bottom: 1px solid #b0b9d1;
17 | border-top: 1px solid #bcc5dd;
18 | box-shadow: 0px 0px 17px rgba(90, 110, 120, 0.2);
19 | transition: box-shadow 0.3s;
20 | // border-bottom: 2px solid #9098af;
21 | cursor: pointer;
22 | }
23 |
24 | span.power-name {
25 | font-style: italic;
26 | font-weight: bold;
27 | margin-right: 20px;
28 | /* min-width: 200px; */
29 | }
30 |
31 | .bean-item-page {
32 | text-align: center;
33 |
34 | .error {
35 | color : red;
36 | margin: 30px;
37 | }
38 |
39 | .loading-element {
40 | font-size: 2em;
41 | margin: 20px;
42 | }
43 | }
44 |
45 | .navigation {
46 | padding: 10px;
47 |
48 | a {
49 | text-decoration: none;
50 | color: #fbfbfb;
51 | }
52 |
53 | .navigation-item {
54 | font-weight: bold;
55 | display: inline;
56 | font-size: 1.5em;
57 | padding: 5px;
58 | background-color: #9a9ea4;
59 | transition: 0.3s linear;
60 | }
61 |
62 | .navigation-item:hover {
63 | background-color: #afb3b9;
64 |
65 | }
66 | }
--------------------------------------------------------------------------------
/public/stylesheets/styles.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: sans-serif;
3 | color: #091521;
4 | background-color: #fffefd;
5 | }
6 |
7 | ul {
8 | list-style-type: none;
9 | padding: 0px;
10 | }
11 |
12 | li.bean-list-item {
13 | display: block;
14 | float: left;
15 | font-size: 3em;
16 | background-color: #F8FBFC;
17 | border: 1px solid #cce7f3;
18 | margin-right: 5px;
19 | margin-top: 5px;
20 | border-radius: 6px;
21 | padding: 6px 13px;
22 | }
23 |
24 | li.bean-list-item:hover {
25 | background-color: white;
26 | border-bottom: 1px solid #b0b9d1;
27 | border-top: 1px solid #bcc5dd;
28 | box-shadow: 0px 0px 17px rgba(90, 110, 120, 0.2);
29 | -webkit-transition: box-shadow 0.3s;
30 | -moz-transition: box-shadow 0.3s;
31 | -o-transition: box-shadow 0.3s;
32 | transition: box-shadow 0.3s;
33 | cursor: pointer;
34 | }
35 |
36 | span.power-name {
37 | font-style: italic;
38 | font-weight: bold;
39 | margin-right: 20px;
40 | /* min-width: 200px; */
41 | }
42 |
43 | .bean-item-page {
44 | text-align: center;
45 | }
46 | .bean-item-page .error {
47 | color: red;
48 | margin: 30px;
49 | }
50 | .bean-item-page .loading-element {
51 | font-size: 2em;
52 | margin: 20px;
53 | }
54 |
55 | .navigation {
56 | padding: 10px;
57 | }
58 | .navigation a {
59 | text-decoration: none;
60 | color: #fbfbfb;
61 | }
62 | .navigation .navigation-item {
63 | font-weight: bold;
64 | display: inline;
65 | font-size: 1.5em;
66 | padding: 5px;
67 | background-color: #9a9ea4;
68 | -webkit-transition: 0.3s linear;
69 | -moz-transition: 0.3s linear;
70 | -o-transition: 0.3s linear;
71 | transition: 0.3s linear;
72 | }
73 | .navigation .navigation-item:hover {
74 | background-color: #afb3b9;
75 | }
76 |
--------------------------------------------------------------------------------
/src/js/react/pages/BeanListPage.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var BeanListActions = require('../../flux/actions/BeanListActions');
3 | var BeanListStore = require('../../flux/stores/BeanListStore');
4 | var ListenerMixin = require('alt/mixins/ListenerMixin');
5 |
6 | var BeanListItem = require('../components/BeanListItem');
7 |
8 | var BeanListPage = React.createClass({
9 | mixins: [ListenerMixin],
10 |
11 | getInitialState() {
12 | return BeanListStore.getState();
13 | },
14 |
15 | componentWillMount() {
16 | this.listenTo(BeanListStore, this._onChange);
17 | },
18 |
19 | componentDidMount() {
20 |
21 | // Simple way of implementing a caching of sorts...
22 | // Should probably be implemented properly in the
23 | // Web API though, not at the view level
24 |
25 | if (!this.state.beanList.length) {
26 | BeanListActions.requestBeanList();
27 | }
28 | },
29 |
30 | _onChange() {
31 | this.setState( BeanListStore.getState() );
32 | },
33 |
34 | render() {
35 | var beanList = null;
36 |
37 | if (this.state.loadingBeanList) {
38 | beanList = (
39 | LOADING...
40 | );
41 | } else {
42 | beanList = this.state.beanList.map(function(listItem) {
43 | return (
44 |
45 | );
46 | })
47 | }
48 |
49 | return (
50 |
51 |
Take your pick
52 |
55 |
56 | );
57 | }
58 | });
59 |
60 | module.exports = BeanListPage;
--------------------------------------------------------------------------------
/npm-debug.log:
--------------------------------------------------------------------------------
1 | 0 info it worked if it ends with ok
2 | 1 verbose cli [ 'node',
3 | 1 verbose cli 'C:\\Users\\Paul\\AppData\\Roaming\\npm\\node_modules\\npm\\bin\\npm-cli.js',
4 | 1 verbose cli 'start' ]
5 | 2 info using npm@2.3.0
6 | 3 info using node@v0.10.36
7 | 4 verbose run-script [ 'prestart', 'start', 'poststart' ]
8 | 5 info prestart alt-react-router-example@1.0.0
9 | 6 info start alt-react-router-example@1.0.0
10 | 7 verbose unsafe-perm in lifecycle true
11 | 8 info alt-react-router-example@1.0.0 Failed to exec start script
12 | 9 verbose stack Error: alt-react-router-example@1.0.0 start: `gulp liveserver`
13 | 9 verbose stack Exit status 8
14 | 9 verbose stack at EventEmitter. (C:\Users\Paul\AppData\Roaming\npm\node_modules\npm\lib\utils\lifecycle.js:213:16)
15 | 9 verbose stack at EventEmitter.emit (events.js:98:17)
16 | 9 verbose stack at ChildProcess. (C:\Users\Paul\AppData\Roaming\npm\node_modules\npm\lib\utils\spawn.js:14:12)
17 | 9 verbose stack at ChildProcess.emit (events.js:98:17)
18 | 9 verbose stack at maybeClose (child_process.js:766:16)
19 | 9 verbose stack at Process.ChildProcess._handle.onexit (child_process.js:833:5)
20 | 10 verbose pkgid alt-react-router-example@1.0.0
21 | 11 verbose cwd D:\Dev\Flux\simple-alt
22 | 12 error Windows_NT 6.2.9200
23 | 13 error argv "node" "C:\\Users\\Paul\\AppData\\Roaming\\npm\\node_modules\\npm\\bin\\npm-cli.js" "start"
24 | 14 error node v0.10.36
25 | 15 error npm v2.3.0
26 | 16 error code ELIFECYCLE
27 | 17 error alt-react-router-example@1.0.0 start: `gulp liveserver`
28 | 17 error Exit status 8
29 | 18 error Failed at the alt-react-router-example@1.0.0 start script 'gulp liveserver'.
30 | 18 error This is most likely a problem with the alt-react-router-example package,
31 | 18 error not with npm itself.
32 | 18 error Tell the author that this fails on your system:
33 | 18 error gulp liveserver
34 | 18 error You can get their info via:
35 | 18 error npm owner ls alt-react-router-example
36 | 18 error There is likely additional logging output above.
37 | 19 verbose exit [ 1, true ]
38 |
--------------------------------------------------------------------------------
/src/js/react/pages/BeanItemPage.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var BeanItemStore = require('../../flux/stores/BeanItemStore');
3 | var BeanItemActions = require('../../flux/actions/BeanItemActions');
4 | var ListenerMixin = require('alt/mixins/ListenerMixin');
5 |
6 | var BeanPowerListItem = require('../components/BeanPowerListItem');
7 | var BeanProfile = require('../components/BeanProfile');
8 |
9 | var BeanItemPage = React.createClass({
10 | mixins: [ListenerMixin],
11 |
12 | getInitialState() {
13 | return BeanItemStore.getState();
14 | },
15 |
16 | componentWillMount() {
17 | this.listenTo(BeanItemStore, this._onChange);
18 | },
19 |
20 | componentDidMount() {
21 | BeanItemActions.requestBeanItem(this.props.params.beanID);
22 | },
23 |
24 | _onChange() {
25 | this.setState(BeanItemStore.getState());
26 | },
27 |
28 | componentWillReceiveProps(nextProps) {
29 | if (this.props.params !== nextProps.params) {
30 | BeanItemActions.requestBeanItem(nextProps.params.beanID);
31 | }
32 | },
33 |
34 | render() {
35 |
36 | var elementToDisplay = null;
37 |
38 | // First check if it's loading
39 | // Then once loaded, check if there's an error
40 | // Show whatever element is required for each stage
41 |
42 | if (this.state.loadingBeanItem) {
43 | elementToDisplay = (
44 | LOADING BEAN...
45 | )
46 | } else {
47 | if (this.state.beanItemError) {
48 | elementToDisplay = (
49 | {this.state.beanItemError}
50 | )
51 | } else {
52 | elementToDisplay = (
53 |
54 | )
55 | }
56 | }
57 |
58 | return (
59 |
60 | {elementToDisplay}
61 |
62 | );
63 | }
64 | });
65 |
66 | module.exports = BeanItemPage;
--------------------------------------------------------------------------------
/src/js/api/EXAMPLE_DATA.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "getList" : [
3 | {
4 | "bean_id" : "wildwest0",
5 | "bean_name" : "Wild West",
6 | "bean_color" : "#D4B881"
7 | },
8 |
9 | {
10 | "bean_id" : "aquatic0",
11 | "bean_name" : "Aquatic",
12 | "bean_color" : "#77A8C3"
13 | },
14 |
15 | {
16 | "bean_id" : "zuluwarrior0",
17 | "bean_name" : "Zulu Warrior",
18 | "bean_color" : "#806744"
19 | },
20 |
21 | {
22 | "bean_id" : "godzilla0",
23 | "bean_name" : "Godzilla",
24 | "bean_color" : "#546B58"
25 | },
26 |
27 | {
28 | "bean_id" : "doesnotexist0",
29 | "bean_name" : "Erroneous",
30 | "bean_color" : "#D14B49"
31 | }
32 | ],
33 |
34 | "getBean" : {
35 | "wildwest0" : {
36 | "bean_id" : "wildwest0",
37 | "bean_name" : "Wild West",
38 | "bean_color" : "#D4B881",
39 | "bean_description" : "Gunslinging bean from the wild American frontier",
40 | "bean_powers" : [
41 | {
42 | "power_name" : "Whip",
43 | "power_description" : "Whip with a whip"
44 | },
45 | {
46 | "power_name" : "Shoot",
47 | "power_description" : "Quick-draw a gun and shoot from the hip"
48 | }
49 | ]
50 | },
51 | "aquatic0" : {
52 | "bean_id" : "aquatic0",
53 | "bean_name" : "Aquatic",
54 | "bean_color" : "#77A8C3",
55 | "bean_description" : "A bean at home in the ocean",
56 | "bean_powers" : [
57 | {
58 | "power_name" : "Squirt",
59 | "power_description" : "Sprays water at enemies"
60 | },
61 | {
62 | "power_name" : "Typhoon",
63 | "power_description" : "Creates a massive storm"
64 | },
65 | {
66 | "power_name" : "Splash",
67 | "power_description" : "Magikarp flashbacks.. Pretty much useless"
68 | }
69 | ]
70 | },
71 | "zuluwarrior0" : {
72 | "bean_id" : "zuluwarrior0",
73 | "bean_name" : "Zulu Warrior",
74 | "bean_color" : "#806744",
75 | "bean_description" : "Legendary African fighter bean",
76 | "bean_powers" : [
77 | {
78 | "power_name" : "Stab",
79 | "power_description" : "Thrusts with its spear"
80 | },
81 | {
82 | "power_name" : "Warcry",
83 | "power_description" : "Rallies allies and strikes fear in enemies with an intimidating warcry"
84 | }
85 | ]
86 | },
87 | "godzilla0" : {
88 | "bean_id" : "godzilla0",
89 | "bean_name" : "Godzilla",
90 | "bean_color" : "#546B58",
91 | "bean_description" : "The arrogance of men is thinking nature is in their control and not the other way around...",
92 | "bean_powers" : [
93 | {
94 | "power_name" : "Atomic Breath",
95 | "power_description" : "A concentrated blast of radiation"
96 | },
97 | {
98 | "power_name" : "Roar",
99 | "power_description" : "A low, groaning bellow"
100 | }
101 | ]
102 | }
103 | }
104 | };
--------------------------------------------------------------------------------