├── .gitignore
├── README.md
├── ajax-loader.gif
├── build
└── README.md
├── index.html
├── package.json
└── src
├── App.jsx
├── actions
└── LocationActions.js
├── alt.js
├── components
└── Locations.jsx
├── sources
└── LocationSource.js
└── stores
├── FavoritesStore.js
└── LocationStore.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | build/app.js
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Alt Tutorial
2 |
3 | ## Getting Started
4 |
5 | ```bash
6 | git clone https://github.com/goatslacker/alt-tutorial.git
7 | cd alt-tutorial
8 | npm install
9 | npm start
10 | ```
11 |
12 | ## License
13 |
14 | MIT
15 |
--------------------------------------------------------------------------------
/ajax-loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goatslacker/alt-tutorial/f1ca04d3ee374f2c31b8510779a3ed834efab569/ajax-loader.gif
--------------------------------------------------------------------------------
/build/README.md:
--------------------------------------------------------------------------------
1 | Build files go here
2 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "alt-tutorial",
3 | "version": "1.0.0",
4 | "description": "A simple flux tutorial built with alt and react",
5 | "main": "server.js",
6 | "dependencies": {
7 | "alt": "^0.16.0",
8 | "react": "^0.12.2"
9 | },
10 | "devDependencies": {
11 | "browserify": "^8.0.3",
12 | "reactify": "^0.17.1"
13 | },
14 | "scripts": {
15 | "build": "browserify -t [reactify --es6] src/App.jsx > build/app.js",
16 | "start": "npm run build && open 'index.html' "
17 | },
18 | "author": "Josh Perez ",
19 | "license": "MIT"
20 | }
21 |
--------------------------------------------------------------------------------
/src/App.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var Locations = require('./components/Locations.jsx');
3 |
4 | React.render(
5 | ,
6 | document.getElementById('ReactApp')
7 | );
8 |
--------------------------------------------------------------------------------
/src/actions/LocationActions.js:
--------------------------------------------------------------------------------
1 | var alt = require('../alt');
2 |
3 | class LocationActions {
4 | updateLocations(locations) {
5 | this.dispatch(locations);
6 | }
7 |
8 | fetchLocations() {
9 | this.dispatch();
10 | }
11 |
12 | locationsFailed(errorMessage) {
13 | this.dispatch(errorMessage);
14 | }
15 |
16 | favoriteLocation(location) {
17 | this.dispatch(location);
18 | }
19 | }
20 |
21 | module.exports = alt.createActions(LocationActions);
22 |
--------------------------------------------------------------------------------
/src/alt.js:
--------------------------------------------------------------------------------
1 | var Alt = require('alt');
2 | var alt = new Alt();
3 | var chromeDebug = require('alt/utils/chromeDebug')
4 |
5 | chromeDebug(alt);
6 |
7 | module.exports = alt;
8 |
--------------------------------------------------------------------------------
/src/components/Locations.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var AltContainer = require('alt/AltContainer');
3 | var LocationStore = require('../stores/LocationStore');
4 | var FavoritesStore = require('../stores/FavoritesStore');
5 | var LocationActions = require('../actions/LocationActions');
6 |
7 | var Favorites = React.createClass({
8 | render() {
9 | return (
10 |
11 | {this.props.locations.map((location, i) => {
12 | return (
13 | - {location.name}
14 | );
15 | })}
16 |
17 | );
18 | }
19 | });
20 |
21 | var AllLocations = React.createClass({
22 | addFave(ev) {
23 | var location = LocationStore.getLocation(
24 | Number(ev.target.getAttribute('data-id'))
25 | );
26 | LocationActions.favoriteLocation(location);
27 | },
28 |
29 | render() {
30 | if (this.props.errorMessage) {
31 | return (
32 | {this.props.errorMessage}
33 | );
34 | }
35 |
36 | if (LocationStore.isLoading()) {
37 | return (
38 |
39 |

40 |
41 | )
42 | }
43 |
44 | return (
45 |
46 | {this.props.locations.map((location, i) => {
47 | var faveButton = (
48 |
51 | );
52 |
53 | return (
54 | -
55 | {location.name} {location.has_favorite ? '<3' : faveButton}
56 |
57 | );
58 | })}
59 |
60 | );
61 | }
62 | });
63 |
64 | var Locations = React.createClass({
65 | componentDidMount() {
66 | LocationStore.fetchLocations();
67 | },
68 |
69 | render() {
70 | return (
71 |
72 |
Locations
73 |
74 |
75 |
76 |
77 |
Favorites
78 |
79 |
80 |
81 |
82 | );
83 | }
84 | });
85 |
86 | module.exports = Locations;
87 |
--------------------------------------------------------------------------------
/src/sources/LocationSource.js:
--------------------------------------------------------------------------------
1 | var LocationActions = require('../actions/LocationActions');
2 |
3 | var mockData = [
4 | { id: 0, name: 'Abu Dhabi' },
5 | { id: 1, name: 'Berlin' },
6 | { id: 2, name: 'Bogota' },
7 | { id: 3, name: 'Buenos Aires' },
8 | { id: 4, name: 'Cairo' },
9 | { id: 5, name: 'Chicago' },
10 | { id: 6, name: 'Lima' },
11 | { id: 7, name: 'London' },
12 | { id: 8, name: 'Miami' },
13 | { id: 9, name: 'Moscow' },
14 | { id: 10, name: 'Mumbai' },
15 | { id: 11, name: 'Paris' },
16 | { id: 12, name: 'San Francisco' }
17 | ];
18 |
19 | var LocationSource = {
20 | fetchLocations() {
21 | return {
22 | remote() {
23 | return new Promise(function (resolve, reject) {
24 | // simulate an asynchronous flow where data is fetched on
25 | // a remote server somewhere.
26 | setTimeout(function () {
27 |
28 | // change this to `false` to see the error action being handled.
29 | if (true) {
30 | // resolve with some mock data
31 | resolve(mockData);
32 | } else {
33 | reject('Things have broken');
34 | }
35 | }, 250);
36 | });
37 | },
38 |
39 | local() {
40 | // Never check locally, always fetch remotely.
41 | return null;
42 | },
43 |
44 | success: LocationActions.updateLocations,
45 | error: LocationActions.locationsFailed,
46 | loading: LocationActions.fetchLocations
47 | }
48 | }
49 | };
50 |
51 | module.exports = LocationSource;
52 |
--------------------------------------------------------------------------------
/src/stores/FavoritesStore.js:
--------------------------------------------------------------------------------
1 | var alt = require('../alt');
2 | var LocationActions = require('../actions/LocationActions');
3 |
4 | class FavoritesStore {
5 | constructor() {
6 | this.locations = [];
7 |
8 | this.bindListeners({
9 | addFavoriteLocation: LocationActions.FAVORITE_LOCATION
10 | });
11 | }
12 |
13 | addFavoriteLocation(location) {
14 | this.locations.push(location);
15 | }
16 | }
17 |
18 | module.exports = alt.createStore(FavoritesStore, 'FavoritesStore');
19 |
--------------------------------------------------------------------------------
/src/stores/LocationStore.js:
--------------------------------------------------------------------------------
1 | var alt = require('../alt');
2 | var LocationActions = require('../actions/LocationActions');
3 | var LocationSource = require('../sources/LocationSource');
4 | var FavoritesStore = require('./FavoritesStore');
5 |
6 | class LocationStore {
7 | constructor() {
8 | this.locations = [];
9 | this.errorMessage = null;
10 |
11 | this.bindListeners({
12 | handleUpdateLocations: LocationActions.UPDATE_LOCATIONS,
13 | handleFetchLocations: LocationActions.FETCH_LOCATIONS,
14 | handleLocationsFailed: LocationActions.LOCATIONS_FAILED,
15 | setFavorites: LocationActions.FAVORITE_LOCATION
16 | });
17 |
18 | this.exportPublicMethods({
19 | getLocation: this.getLocation
20 | });
21 |
22 | this.exportAsync(LocationSource);
23 | }
24 |
25 | handleUpdateLocations(locations) {
26 | this.locations = locations;
27 | this.errorMessage = null;
28 | }
29 |
30 | handleFetchLocations() {
31 | this.locations = [];
32 | }
33 |
34 | handleLocationsFailed(errorMessage) {
35 | this.errorMessage = errorMessage;
36 | }
37 |
38 | resetAllFavorites() {
39 | this.locations = this.locations.map((location) => {
40 | return {
41 | id: location.id,
42 | name: location.name,
43 | has_favorite: false
44 | };
45 | });
46 | }
47 |
48 | setFavorites(location) {
49 | this.waitFor(FavoritesStore);
50 |
51 | var favoritedLocations = FavoritesStore.getState().locations;
52 |
53 | this.resetAllFavorites();
54 |
55 | favoritedLocations.forEach((location) => {
56 | // find each location in the array
57 | for (var i = 0; i < this.locations.length; i += 1) {
58 |
59 | // set has_favorite to true
60 | if (this.locations[i].id === location.id) {
61 | this.locations[i].has_favorite = true;
62 | break;
63 | }
64 | }
65 | });
66 | }
67 |
68 | getLocation(id) {
69 | var { locations } = this.getState();
70 | for (var i = 0; i < locations.length; i += 1) {
71 | if (locations[i].id === id) {
72 | return locations[i];
73 | }
74 | }
75 |
76 | return null;
77 | }
78 | }
79 |
80 | module.exports = alt.createStore(LocationStore, 'LocationStore');
81 |
--------------------------------------------------------------------------------