-
Notifications
You must be signed in to change notification settings - Fork 321
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
AltManager + WeatherTabs App Example
- Loading branch information
Alvin Sng
committed
Mar 24, 2015
1 parent
bffff73
commit a901e9c
Showing
17 changed files
with
652 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/js/bundle.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
## AltManager example: Weather Tabs App | ||
|
||
This is an example React/Flux/Alt app that shows the use of AltManager, a | ||
utility class for Alt.js. AltManager allows for multiple alt instances which is | ||
necessary to build apps that encapsulates a mini app inside of a large app. In | ||
this example we have a simple weather searcher. Each search you make will | ||
create a new tab which itself is a new Alt instance and has its own internal | ||
store & actions. Whatever you do in the alt instance is persisted even after | ||
you move to another tab. You can delete tabs which will delete that alt instance | ||
|
||
## Install | ||
1) run `npm run clean` | ||
2) open the index.html file | ||
|
||
## Docs | ||
See /utils/AltManager.js for details on how to use AltManager.js | ||
See /mixins/AltManagerMixin.js for details on mixin usage. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
body { | ||
font-family: 'Lato', sans-serif, "Arial"; | ||
font-size: 16px; | ||
background: #eee; | ||
margin: 0; | ||
} | ||
|
||
h1 { | ||
background: #333; | ||
margin: 0; | ||
padding: 20px 20px; | ||
color: #eee; | ||
border-bottom: solid 3px #aaa; | ||
} | ||
|
||
.search-box { | ||
width: 600px; | ||
margin: 40px auto 60px auto; | ||
} | ||
|
||
.search-location { | ||
padding: 6px; | ||
width: 380px; | ||
margin-right: 10px; | ||
font-size: 20px; | ||
border-radius: 3px; | ||
border: solid 1px #ccc; | ||
} | ||
|
||
button { | ||
font-size: 20px; | ||
padding: 6px 14px; | ||
background: #333; | ||
color: #eee; | ||
border: solid 1px #999; | ||
border-radius: 3px; | ||
} | ||
|
||
.content { | ||
padding: 0 20px; | ||
} | ||
|
||
.pull-right { | ||
float:right; | ||
} | ||
|
||
.weather-tab { | ||
padding: 20px; | ||
background: #ccc; | ||
border-radius: 3px; | ||
} | ||
|
||
.loading img { | ||
margin: 0 auto; | ||
display: block; | ||
padding: 50px 0; | ||
} | ||
|
||
.nav { | ||
list-style: none; | ||
padding: 0; | ||
margin: 0 20px; | ||
} | ||
|
||
.nav li { | ||
display: inline; | ||
margin: 0; | ||
font-size: 20px; | ||
padding: 10px 0; | ||
background: #333; | ||
position: relative; | ||
bottom: 10px; | ||
border-top-left-radius: 3px; | ||
border-top-right-radius: 3px; | ||
} | ||
|
||
.nav li a { | ||
color: white; | ||
padding: 0 1em; | ||
text-decoration: none; | ||
} | ||
|
||
.nav li.selected { | ||
background: #ccc; | ||
padding-top: 18px; | ||
} | ||
|
||
.nav li.selected a { | ||
color: #000; | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>AltManager - Weather Tabs App</title> | ||
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Lato" /> | ||
<link rel="stylesheet" type="text/css" href="css/app.css" /> | ||
</head> | ||
<body> | ||
<section id="weather-tabs"></section> | ||
<script src="js/bundle.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
var alt = require('../alt') | ||
|
||
module.exports = alt.createActions(class AppActions { | ||
constructor() { | ||
this.generateActions( | ||
'setManager', | ||
'addLocation', | ||
'setLocation', | ||
'deleteLocation' | ||
); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
var $ = require('jquery'); | ||
|
||
class WeatherActions { | ||
constructor() { | ||
this.generateActions( | ||
'setLoading', | ||
'setWeather', | ||
'showRaw' | ||
); | ||
} | ||
|
||
loadWeather(location) { | ||
this.dispatch(location); | ||
$.ajax('http://api.openweathermap.org/data/2.5/weather', { | ||
crossDomain: true, | ||
data: { q: location }, | ||
success: (data) => { | ||
// we put in a fake delay here to show the loading icon | ||
setTimeout(() => { | ||
if (data.weather) { | ||
this.actions.setWeather(data); | ||
} | ||
this.actions.setLoading(false); | ||
}, 500); | ||
}, | ||
error: () => { | ||
this.actions.setLoading(false); | ||
} | ||
}); | ||
} | ||
} | ||
|
||
module.exports = WeatherActions; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
var Alt = require('../../../'); | ||
module.exports = new Alt(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
var React = require('react'); | ||
var App = require('./components/App.jsx'); | ||
|
||
React.render( | ||
React.createElement(App), | ||
document.getElementById('weather-tabs') | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
var React = require('react'); | ||
var ReactStateMagicMixin = require('../../../../mixins/ReactStateMagicMixin'); | ||
var Alt = require('../../../../'); | ||
var AltManager = require('../../../../utils/AltManager'); | ||
var AppActions = require('../actions/AppActions'); | ||
var AppStore = require('../stores/AppStore'); | ||
var WeatherTab = require('./WeatherTab.jsx'); | ||
|
||
var manager = new AltManager(Alt); | ||
AppActions.setManager(manager); | ||
|
||
module.exports = React.createClass({ | ||
|
||
displayName: 'App', | ||
mixins: [ReactStateMagicMixin], | ||
statics: { registerStore: AppStore }, | ||
|
||
render: function() { | ||
var locationLinks = []; | ||
var weatherApp = null; | ||
|
||
if (this.state.location) { | ||
weatherApp = ( | ||
<WeatherTab | ||
alt={manager.getOrCreate(this.state.location)} | ||
location={this.state.location} /> | ||
); | ||
} | ||
|
||
for (var location in manager.all()) { | ||
locationLinks.push( | ||
<li | ||
key={location} | ||
className={location === this.state.location ? 'selected' : null}> | ||
<a href="javascript:void(0);" onClick={this._onClickLocation.bind(this, location)}> | ||
{location} | ||
</a> | ||
</li> | ||
); | ||
} | ||
|
||
return ( | ||
<div> | ||
<h1>AltManager - Weather Tabs App</h1> | ||
<div className="content"> | ||
<p> | ||
This is an example React/Flux/Alt app that shows the use of AltManager, a | ||
utility class for Alt.js. AltManager allows for multiple alt instances which is | ||
necessary to build apps that encapsulates a mini app inside of a large app. In | ||
this example we have a simple weather searcher. Each search you make will | ||
create a new tab which itself is a new Alt instance and has its own internal | ||
store & actions. Whatever you do in the alt instance is persisted even after | ||
you move to another tab. You can delete tabs which will delete that alt instance | ||
</p> | ||
<form className="search-box" onSubmit={this._onClickSubmit}> | ||
<input | ||
type="text" | ||
className="search-location" | ||
placeholder="Location eg. New York City, NY"/> | ||
<button>Search Weather</button> | ||
</form> | ||
<ul className="nav">{locationLinks}</ul> | ||
{weatherApp} | ||
</div> | ||
</div> | ||
); | ||
}, | ||
|
||
componentDidMount: function() { | ||
// we load San Francisco, CA on page load as an example | ||
AppActions.addLocation('San Francisco, CA'); | ||
}, | ||
|
||
_onClickSubmit: function(e) { | ||
e.preventDefault(); | ||
AppActions.addLocation(e.target.children[0].value.trim()); | ||
}, | ||
|
||
_onClickLocation: function(location) { | ||
AppActions.setLocation(location); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
var React = require('react'); | ||
var AltManagerMixin = require('../../../../mixins/AltManagerMixin'); | ||
var AppActions = require('../actions/AppActions'); | ||
var WeatherActions = require('../actions/WeatherActions'); | ||
var WeatherStore = require('../stores/WeatherStore'); | ||
|
||
module.exports = React.createClass({ | ||
|
||
displayName: 'WeatherTab', | ||
|
||
mixins: [AltManagerMixin], | ||
statics: { registerStore: WeatherStore, registerAction: WeatherActions }, | ||
|
||
onNewAlt: function(state, newProps) { | ||
// load weather if none exists | ||
if (!state.location && !state.loading) { | ||
this.action.loadWeather(newProps.location); | ||
} | ||
}, | ||
|
||
_onClickShowRaw: function() { | ||
this.action.showRaw(!this.state.showRaw); | ||
}, | ||
|
||
onClickDelete: function() { | ||
AppActions.deleteLocation(this.props.location); | ||
}, | ||
|
||
getWeatherContent: function() { | ||
if (this.state.loading) { | ||
return <div className="loading"><img src="images/loading.gif" /></div>; | ||
} | ||
|
||
if (!this.state.weather) { | ||
return <p>Error loading weather data, check location</p>; | ||
} | ||
|
||
var weather = this.state.weather; | ||
var rawData = null; | ||
var showText = 'Show Raw JSON'; | ||
if (this.state.showRaw) { | ||
rawData = <pre>{JSON.stringify(weather, null, 4)}</pre>; | ||
showText = 'Hide Raw JSON'; | ||
} | ||
|
||
return ( | ||
<div className="weather-data"> | ||
<h3>Current Temp: {weather.main.temp}K, {weather.weather[0].description}</h3> | ||
<button onClick={this._onClickShowRaw}> | ||
{showText} | ||
</button> | ||
{rawData} | ||
</div> | ||
); | ||
}, | ||
|
||
render: function() { | ||
return ( | ||
<div className="weather-tab"> | ||
<button className="pull-right" onClick={this.onClickDelete}> | ||
Close Tab | ||
</button> | ||
<h2>Weather For {this.state.location}</h2> | ||
{this.getWeatherContent()} | ||
</div> | ||
); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
var alt = require('../alt'); | ||
|
||
var AppActions = require('../actions/AppActions'); | ||
|
||
module.exports = alt.createStore(class AppStore { | ||
constructor() { | ||
this.bindActions(AppActions); | ||
this.location = null; | ||
this.manager = null; | ||
} | ||
|
||
setManager(manager) { | ||
this.manager = manager; | ||
} | ||
|
||
addLocation(location) { | ||
this.manager.getOrCreate(location); | ||
this.location = location; | ||
} | ||
|
||
setLocation(location) { | ||
this.location = location; | ||
} | ||
|
||
deleteLocation(location) { | ||
this.manager.delete(location); | ||
this.location = null; | ||
for (var i in this.manager.all()) { | ||
this.location = i; | ||
break; | ||
} | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
class WeatherStore { | ||
constructor(alt) { | ||
this.bindActions(alt.getActions('WeatherActions')); | ||
this.loading = false; | ||
this.weather = null; | ||
this.showRaw = false; | ||
this.location = null; | ||
} | ||
|
||
loadWeather(location) { | ||
this.location = location; | ||
this.loading = true; | ||
} | ||
|
||
setLoading(isLoading) { | ||
this.loading = isLoading | ||
} | ||
|
||
setWeather(weather) { | ||
this.weather = weather; | ||
} | ||
|
||
showRaw(showRaw) { | ||
this.showRaw = showRaw; | ||
} | ||
} | ||
|
||
module.exports = WeatherStore; |
Oops, something went wrong.