Live updating gas stations and markets

This commit is contained in:
Dana Woodman 2017-10-10 13:12:13 -07:00
parent e8f0a0b505
commit 5207b0feeb
7 changed files with 2461 additions and 120 deletions

View File

@ -1,6 +1,7 @@
{
"presets": [
"react",
"stage-0",
[
"env",
{

125
app.js
View File

@ -4,62 +4,121 @@ require('./styles.scss')
const React = require('react')
const ReactDOM = require('react-dom')
class ResourceList extends React.Component {
constructor(props) {
super(props)
this.state = {
loading: false,
items: [],
}
}
componentWillMount() {
this.setState(Object.assign({}, this.state, { loading: true }))
fetch('http://app.tubbsfireinfo.com/recent_news.json')
function fetchResources(url) {
return new Promise((resolve, reject) => {
fetch(url)
.then(response => {
return response.json()
})
.then(json => {
console.log('RESPONSE:', json)
this.setState(
Object.assign({}, this.state, { items: json, loading: false })
)
resolve(json)
})
.catch(ex => {
console.log('parsing failed', ex)
this.setState(Object.assign({}, this.state, { loading: false }))
.catch(error => {
reject(error)
console.log('ERROR:', error)
})
})
}
class SmartTable extends React.Component {
constructor(props) {
super(props)
this.state = {
error: null,
loading: false,
items: [],
}
}
async componentWillMount() {
this.setState({ ...this.state, error: null, loading: true })
try {
const news = await fetchResources(this.props.url)
this.setState({ ...this.state, items: news, error: null, loading: false })
} catch (error) {
this.setState({ ...this.state, error: error })
console.error('ERROR:', error)
}
}
render() {
return <List items={this.state.items} loading={this.state.loading} />
return (
<Table
error={this.state.error}
items={this.state.items}
loading={this.state.loading}
/>
)
}
}
function List({ loading, items }) {
if (loading) {
function Table({ error, loading, items }) {
if (error) {
return (
<p className="lead text-center">
<i className="fa fa-spinner fa-spin mr-3" /> Loading news...
<p className="lead text-center text-danger">
<i className="fa fa-warning fa-spin mr-3" /> Sorry, we had an issue
loading results, please try again in a few moments.
</p>
)
}
if (loading) {
return (
<p className="lead text-center">
<i className="fa fa-spinner fa-spin mr-3" /> Loading...
</p>
)
}
const columns = Object.values(items[0].column_mappings)
return (
<ul className="list-group">
{items.map((item, key) => <Item item={item} key={key} />)}
</ul>
<table className="table table-hover">
<thead>
<tr>{columns.map((col, key) => <th key={key}>{col}</th>)}</tr>
</thead>
<tbody>
{items.map((item, key) => (
<Row item={item} columns={columns} key={key} />
))}
</tbody>
</table>
)
}
function Item({ item }) {
function formatCell(col, value) {
// Date
if (col.toLowerCase() === 'last updated') {
const date = new Date(value)
return `${date.getMonth() +
1}/${date.getDate()} at ${date.getHours()}:${date.getMinutes()}`
}
return value
}
function Row({ columns, item }) {
return (
<li className="list-group-item">
<i className="fa fa-warning mr-3" />
{item.fields.Description}
</li>
<tr>
{columns.map((col, key) => {
const cell = formatCell(col, item.fields[col])
return <td key={key}>{cell}</td>
})}
</tr>
)
}
ReactDOM.render(<ResourceList />, document.getElementById('resource-list'))
ReactDOM.render(
<SmartTable url="http://app.tubbsfireinfo.com/recent_news.json" />,
document.getElementById('resource-list')
)
ReactDOM.render(
<SmartTable url="http://app.tubbsfireinfo.com/gas_stations.json" />,
document.getElementById('gas-stations')
)
ReactDOM.render(
<SmartTable url="http://app.tubbsfireinfo.com/markets.json" />,
document.getElementById('markets')
)

2202
build.js

File diff suppressed because one or more lines are too long

View File

@ -60,20 +60,38 @@
<div class="container">
<h2 class="text-center mb-3">Updates</h2>
<p class="lead my-4 text-center">
<a href="https://airtable.com/shrS4LGsCBTMULwBk" class="btn btn-primary">
<a href="https://airtable.com/shrS4LGsCBTMULwBk" class="btn btn-primary" target="_blank">
<i class="fa fa-envelope-o mr-2"></i>
Send in new leads
</a>
</p>
<div class="row">
<div class="col-sm-10 mx-auto">
<div id="resource-list"></div>
</div>
</div>
<div id="resource-list"></div>
</div>
</div>
<div id="find-help" class="bg-light section">
<div id="" class="bg-light section">
<div class="container">
<h2 class="mb-3 text-center">
<i class="fa fa-car mr-3"></i>
Gas Stations
</h2>
<p class="lead mb-5 text-center">A list of gas stations known to be open.</p>
<div id="gas-stations"></div>
<hr class="my-5">
<h2 class="mb-3 text-center">
<i class="fa fa-cutlery mr-3"></i>
Markets
</h2>
<p class="lead mb-5 text-center">A list of markets known to be open.</p>
<div id="markets"></div>
</div>
</div>
<div id="find-help" class="section">
<div class="container">
<h2 class="text-center mb-5">Find Help</h2>
<div class="row">
@ -100,7 +118,7 @@
</div>
</div>
<div id="resources" class="section">
<div id="resources" class="bg-light section">
<div class="container">
<h2 class="text-center mb-5">Resources</h2>
<div class="row">

211
package-lock.json generated
View File

@ -355,6 +355,17 @@
}
}
},
"babel-helper-bindify-decorators": {
"version": "6.24.1",
"resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz",
"integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=",
"dev": true,
"requires": {
"babel-runtime": "6.26.0",
"babel-traverse": "6.26.0",
"babel-types": "6.26.0"
}
},
"babel-helper-builder-binary-assignment-operator-visitor": {
"version": "6.24.1",
"resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
@ -411,6 +422,18 @@
"babel-types": "6.26.0"
}
},
"babel-helper-explode-class": {
"version": "6.24.1",
"resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz",
"integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=",
"dev": true,
"requires": {
"babel-helper-bindify-decorators": "6.24.1",
"babel-runtime": "6.26.0",
"babel-traverse": "6.26.0",
"babel-types": "6.26.0"
}
},
"babel-helper-function-name": {
"version": "6.24.1",
"resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
@ -537,28 +560,93 @@
"integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
"dev": true
},
"babel-plugin-syntax-async-generators": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz",
"integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=",
"dev": true
},
"babel-plugin-syntax-class-constructor-call": {
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz",
"integrity": "sha1-nLnTn+Q8hgC+yBRkVt3L1OGnZBY=",
"dev": true
},
"babel-plugin-syntax-class-properties": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz",
"integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=",
"dev": true
},
"babel-plugin-syntax-decorators": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz",
"integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=",
"dev": true
},
"babel-plugin-syntax-do-expressions": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz",
"integrity": "sha1-V0d1YTmqJtOQ0JQQsDdEugfkeW0=",
"dev": true
},
"babel-plugin-syntax-dynamic-import": {
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz",
"integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=",
"dev": true
},
"babel-plugin-syntax-exponentiation-operator": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
"integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
"dev": true
},
"babel-plugin-syntax-export-extensions": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz",
"integrity": "sha1-cKFITw+QiaToStRLrDU8lbmxJyE=",
"dev": true
},
"babel-plugin-syntax-flow": {
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz",
"integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0="
},
"babel-plugin-syntax-function-bind": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz",
"integrity": "sha1-SMSV8Xe98xqYHnMvVa3AvdJgH0Y=",
"dev": true
},
"babel-plugin-syntax-jsx": {
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
"integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY="
},
"babel-plugin-syntax-object-rest-spread": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
"integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
"dev": true
},
"babel-plugin-syntax-trailing-function-commas": {
"version": "6.22.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
"integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=",
"dev": true
},
"babel-plugin-transform-async-generator-functions": {
"version": "6.24.1",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz",
"integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=",
"dev": true,
"requires": {
"babel-helper-remap-async-to-generator": "6.24.1",
"babel-plugin-syntax-async-generators": "6.13.0",
"babel-runtime": "6.26.0"
}
},
"babel-plugin-transform-async-to-generator": {
"version": "6.24.1",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
@ -570,6 +658,52 @@
"babel-runtime": "6.26.0"
}
},
"babel-plugin-transform-class-constructor-call": {
"version": "6.24.1",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz",
"integrity": "sha1-gNwoVQWsBn3LjWxl4vbxGrd2Xvk=",
"dev": true,
"requires": {
"babel-plugin-syntax-class-constructor-call": "6.18.0",
"babel-runtime": "6.26.0",
"babel-template": "6.26.0"
}
},
"babel-plugin-transform-class-properties": {
"version": "6.24.1",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz",
"integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=",
"dev": true,
"requires": {
"babel-helper-function-name": "6.24.1",
"babel-plugin-syntax-class-properties": "6.13.0",
"babel-runtime": "6.26.0",
"babel-template": "6.26.0"
}
},
"babel-plugin-transform-decorators": {
"version": "6.24.1",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz",
"integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=",
"dev": true,
"requires": {
"babel-helper-explode-class": "6.24.1",
"babel-plugin-syntax-decorators": "6.13.0",
"babel-runtime": "6.26.0",
"babel-template": "6.26.0",
"babel-types": "6.26.0"
}
},
"babel-plugin-transform-do-expressions": {
"version": "6.22.0",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz",
"integrity": "sha1-KMyvkoEtlJws0SgfaQyP3EaK6bs=",
"dev": true,
"requires": {
"babel-plugin-syntax-do-expressions": "6.13.0",
"babel-runtime": "6.26.0"
}
},
"babel-plugin-transform-es2015-arrow-functions": {
"version": "6.22.0",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
@ -828,6 +962,16 @@
"babel-runtime": "6.26.0"
}
},
"babel-plugin-transform-export-extensions": {
"version": "6.22.0",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz",
"integrity": "sha1-U3OLR+deghhYnuqUbLvTkQm75lM=",
"dev": true,
"requires": {
"babel-plugin-syntax-export-extensions": "6.13.0",
"babel-runtime": "6.26.0"
}
},
"babel-plugin-transform-flow-strip-types": {
"version": "6.22.0",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz",
@ -837,6 +981,26 @@
"babel-runtime": "6.26.0"
}
},
"babel-plugin-transform-function-bind": {
"version": "6.22.0",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz",
"integrity": "sha1-xvuOlqwpajELjPjqQBRiQH3fapc=",
"dev": true,
"requires": {
"babel-plugin-syntax-function-bind": "6.13.0",
"babel-runtime": "6.26.0"
}
},
"babel-plugin-transform-object-rest-spread": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz",
"integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=",
"dev": true,
"requires": {
"babel-plugin-syntax-object-rest-spread": "6.13.0",
"babel-runtime": "6.26.0"
}
},
"babel-plugin-transform-react-display-name": {
"version": "6.25.0",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz",
@ -988,6 +1152,53 @@
"babel-preset-flow": "6.23.0"
}
},
"babel-preset-stage-0": {
"version": "6.24.1",
"resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz",
"integrity": "sha1-VkLRUEL5E4TX5a+LyIsduVsDnmo=",
"dev": true,
"requires": {
"babel-plugin-transform-do-expressions": "6.22.0",
"babel-plugin-transform-function-bind": "6.22.0",
"babel-preset-stage-1": "6.24.1"
}
},
"babel-preset-stage-1": {
"version": "6.24.1",
"resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz",
"integrity": "sha1-dpLNfc1oSZB+auSgqFWJz7niv7A=",
"dev": true,
"requires": {
"babel-plugin-transform-class-constructor-call": "6.24.1",
"babel-plugin-transform-export-extensions": "6.22.0",
"babel-preset-stage-2": "6.24.1"
}
},
"babel-preset-stage-2": {
"version": "6.24.1",
"resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz",
"integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=",
"dev": true,
"requires": {
"babel-plugin-syntax-dynamic-import": "6.18.0",
"babel-plugin-transform-class-properties": "6.24.1",
"babel-plugin-transform-decorators": "6.24.1",
"babel-preset-stage-3": "6.24.1"
}
},
"babel-preset-stage-3": {
"version": "6.24.1",
"resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz",
"integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=",
"dev": true,
"requires": {
"babel-plugin-syntax-trailing-function-commas": "6.22.0",
"babel-plugin-transform-async-generator-functions": "6.24.1",
"babel-plugin-transform-async-to-generator": "6.24.1",
"babel-plugin-transform-exponentiation-operator": "6.24.1",
"babel-plugin-transform-object-rest-spread": "6.26.0"
}
},
"babel-register": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",

View File

@ -29,6 +29,7 @@
"babel-loader": "7.1.2",
"babel-polyfill": "6.26.0",
"babel-preset-env": "1.6.0",
"babel-preset-stage-0": "6.24.1",
"css-loader": "0.28.7",
"extract-text-webpack-plugin": "3.0.1",
"node-sass": "4.5.3",

View File

@ -2,7 +2,7 @@ const webpack = require('webpack')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const config = {
entry: ['./app.js'],
entry: ['babel-polyfill', './app.js'],
output: {
path: __dirname,
filename: 'build.js',
@ -23,7 +23,10 @@ const config = {
},
],
},
plugins: [new ExtractTextPlugin('output.css')],
plugins: [
new ExtractTextPlugin('output.css'),
new webpack.IgnorePlugin(/\.\/locale$/),
],
devtool: 'eval',
}