Commit 9e3addb7 authored by Jed Simson's avatar Jed Simson

Create React frontend

parent edb6db74
This diff is collapsed.
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var SubredditField = React.createClass({displayName: "SubredditField",
getInitialState: function() {
return {default: 'programming',
subreddit: 'programming'};
},
handleChange: function(event) {
var oldValue = this.state.subreddit;
this.setState({subreddit: event.target.value});
this.props.onChange(event, oldValue);
},
render: function() {
return (
React.createElement("fieldset", {className: "form-group"},
React.createElement("label", {htmlFor: "subreddit"}, React.createElement("strong", null, " Subreddit ")),
React.createElement("div", {className: "input-group"},
React.createElement("span", {className: "input-group-addon"}, "/r/"),
React.createElement("input", {
type: "text",
id: "subreddit",
className: "form-control",
placeholder: this.state.default,
onChange: this.handleChange})
)
)
);
}
});
var RangeField = React.createClass({displayName: "RangeField",
getInitialState: function() {
return {default: 'today',
range: 'today'};
},
handleChange: function(event) {
var oldValue = this.state.range;
var newValue = event.target.value;
newValue = newValue.split(' ').join('+');
this.setState({range: newValue});
this.props.onChange(event, oldValue);
},
render: function() {
return (
React.createElement("fieldset", {className: "form-group"},
React.createElement("label", {for: "range"}, React.createElement("strong", null, " Range ")),
React.createElement("input", {
type: "text",
id: "range",
className: "form-control",
placeholder: this.state.default,
onChange: this.handleChange})
)
);
}
});
var SortField = React.createClass({displayName: "SortField",
getInitialState: function() {
return {default: 'hot',
sort: 'hot'};
},
handleChange: function(event) {
var oldValue = this.state.sort;
this.setState({sort: event.target.value});
this.props.onChange(event, oldValue);
},
render: function() {
return (
React.createElement("fieldset", {className: "form-group"},
React.createElement("label", {for: "sort"}, React.createElement("strong", null, " Sort ")),
React.createElement("select", {className: "form-control", id: "sort", defaultValue: this.state.default, onChange: this.handleChange},
React.createElement("option", {value: "hot"}, "Hot"),
React.createElement("option", {value: "top"}, "Top"),
React.createElement("option", {value: "new"}, "New"),
React.createElement("option", {value: "controversial"}, "Controversial")
)
)
);
}
});
var LimitField = React.createClass({displayName: "LimitField",
getInitialState: function() {
return {default: '100',
limit: '100'};
},
handleChange: function(event) {
var oldValue = this.state.limit;
this.setState({limit: event.target.value});
this.props.onChange(event, oldValue);
},
render: function() {
return (
React.createElement("fieldset", {className: "form-group"},
React.createElement("label", {for: "limit"}, React.createElement("strong", null, " Limit ")),
React.createElement("input", {type: "number", min: "1", className: "form-control", id: "limit", onChange: this.handleChange, defaultValue: this.state.default})
)
);
}
});
module.exports = {
SubredditField: SubredditField,
RangeField: RangeField,
SortField: SortField,
LimitField: LimitField
};
},{}]},{},[1]);
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var Information = React.createClass({displayName: "Information",
render: function() {
return (
React.createElement("div", null,
React.createElement("br", null),
React.createElement("h1", null, "Reddit Slider"),
React.createElement("hr", null),
React.createElement("p", null, "Please enter your query using the options below..."),
React.createElement("p", null, "The range field accepts values like:"),
React.createElement("ul", null,
React.createElement("li", null, "\"Today\""),
React.createElement("li", null, "\"June 20 2016 to now\""),
React.createElement("li", null, "\"May 18 8:00am to May 18 2:00pm\""),
React.createElement("li", null, "\"1 year ago\"")
)
)
);
}
});
module.exports = Information;
},{}]},{},[1]);
var Information = require('./information.js')
var {SubredditField, RangeField, SortField, LimitField} = require('./fields.js')
var Container = React.createClass({
render: function() {
return (
<div className="container">
<div className="content" id="content">
<Information />
<SearchForm />
</div>
</div>
);
}
});
var SearchForm = React.createClass({
getInitialState: function() {
var queryParams = {subreddit: 'programming', range: 'today',
sort: 'hot', limit: '100'};
var query = this.serializeQuery(queryParams);
var urlBase = '/api/search/';
return {params: queryParams, query: query, url: urlBase};
},
serializeQuery: function(params) {
var query = params.subreddit + '/?range=' + params.range.split(' ').join('+') +
'&sort=' + params.sort + '&limit=' + params.limit;
return query;
},
fetchResults: function() {
console.log('Fetching results with query: ' + this.state.url + this.state.query);
if (this.state.params.subreddit === '') {
console.log('Empty subreddit');
}
this.refs.resultsPanel.isLoading();
$.ajax({
type: 'GET',
url: this.state.url + this.state.query,
dataType: 'json',
contentType: 'application/json'
}).fail(function(data) {
var error;
if (data.status == 404) {
// The subreddit field has been left empty
error = {msg: 'Please provide a subreddit to search.', code: 404};
}
else if (data.status == 500) {
error = {msg: data.responseJSON['error'], code: 500};
}
this.refs.resultsPanel.setState({
hasError: true,
error: error,
loading: false,
submissions: [],
info: ''
});
}.bind(this)).then(function(data) {
var resultsPanel = this.refs.resultsPanel;
var count = data['count'];
var time = data['time'];
var submissions = data['submissions'];
resultsPanel.setState({
submissions: submissions,
info: count + ' results fetched in ' + time + ' seconds...',
loading: false
});
}.bind(this));
},
handleSubmit: function(event) {
// Get the results and as a side-effect update the
// internal state
event.preventDefault();
this.fetchResults();
},
handleChange: function(event, oldValue) {
var newValue = event.target.value;
var newParams = this.state.params;
newParams[event.target.id] = newValue
this.setState({
params: newParams,
query: this.serializeQuery(newParams)
});
console.log('Updated ' + event.target.id + ' state: ' + oldValue + ' => ' + newValue);
},
render: function() {
return (
<div>
<form className="form-inline" onSubmit={this.handleSubmit}>
<SubredditField ref="subredditField" onChange={this.handleChange}/>
<RangeField ref="rangeField" onChange={this.handleChange}/>
<SortField ref="sortField" onChange={this.handleChange}/>
<LimitField ref="limitField" onChange={this.handleChange}/>
&nbsp;<button type="submit" id="search-btn" className="btn btn-primary-outline">Search</button>
</form>
<br/>
<ResultsPanel ref="resultsPanel" />
</div>
);
}
});
var ResultsPanel = React.createClass({
getInitialState: function() {
return {loading: false, submissions: [], info: '', showResults: false, hasError: false};
},
isLoading: function() {
this.setState({
hasError: false,
error: null,
loading: true,
submissions: [],
info: '',
showResults: true
});
},
render: function() {
var noSubmissions = this.state.submissions.length == 0;
if (!noSubmissions) {
var submissions = this.state.submissions.map(function(submission) {
return (
<a key={submission['timestamp']} target="_blank" href={submission['href']} className="list-group-item">
<h5 className="list-group-item-heading">{submission['info']}</h5>
<p className="list-group-item-text text-muted"><em>{submission['date']}</em></p>
</a>
);
});
}
if (this.state.showResults) {
return (
<div className="card" id="results-card">
<div className="card-block">
<h4 className="card-title">Results</h4>
{!noSubmissions ? <div id="info" className="alert alert-info">{this.state.info}</div> : null}
</div>
<div className="card-block">
<div className="list-group" id="results">
{this.state.hasError ? <div className="alert alert-danger">{this.state.error.msg}</div> : null}
{!noSubmissions ? submissions : null}
{this.state.loading ? <div id="loading"><strong>Loading...</strong></div> : null}
</div>
</div>
</div>
);
} else {
return null;
}
}
});
ReactDOM.render(
<Container />,
document.getElementById('react-mount-point')
);
var SubredditField = React.createClass({
getInitialState: function() {
return {default: 'programming',
subreddit: 'programming'};
},
handleChange: function(event) {
var oldValue = this.state.subreddit;
this.setState({subreddit: event.target.value});
this.props.onChange(event, oldValue);
},
render: function() {
return (
<fieldset className="form-group">
<label htmlFor="subreddit"><strong>&nbsp;Subreddit&nbsp;</strong></label>
<div className="input-group">
<span className="input-group-addon">/r/</span>
<input
type="text"
id="subreddit"
className="form-control"
placeholder={this.state.default}
onChange={this.handleChange}/>
</div>
</fieldset>
);
}
});
var RangeField = React.createClass({
getInitialState: function() {
return {default: 'today',
range: 'today'};
},
handleChange: function(event) {
var oldValue = this.state.range;
var newValue = event.target.value;
newValue = newValue.split(' ').join('+');
this.setState({range: newValue});
this.props.onChange(event, oldValue);
},
render: function() {
return (
<fieldset className="form-group">
<label for="range"><strong>&nbsp;Range&nbsp;</strong></label>
<input
type="text"
id="range"
className="form-control"
placeholder={this.state.default}
onChange={this.handleChange}/>
</fieldset>
);
}
});
var SortField = React.createClass({
getInitialState: function() {
return {default: 'hot',
sort: 'hot'};
},
handleChange: function(event) {
var oldValue = this.state.sort;
this.setState({sort: event.target.value});
this.props.onChange(event, oldValue);
},
render: function() {
return (
<fieldset className="form-group">
<label for="sort"><strong>&nbsp;Sort&nbsp;</strong></label>
<select className="form-control" id="sort" defaultValue={this.state.default} onChange={this.handleChange}>
<option value="hot">Hot</option>
<option value="top">Top</option>
<option value="new">New</option>
<option value="controversial">Controversial</option>
</select>
</fieldset>
);
}
});
var LimitField = React.createClass({
getInitialState: function() {
return {default: '100',
limit: '100'};
},
handleChange: function(event) {
var oldValue = this.state.limit;
this.setState({limit: event.target.value});
this.props.onChange(event, oldValue);
},
render: function() {
return (
<fieldset className="form-group">
<label for="limit"><strong>&nbsp;Limit&nbsp;</strong></label>
<input type="number" min="1" className="form-control" id="limit" onChange={this.handleChange} defaultValue={this.state.default}/>
</fieldset>
);
}
});
module.exports = {
SubredditField: SubredditField,
RangeField: RangeField,
SortField: SortField,
LimitField: LimitField
};
var Information = React.createClass({
render: function() {
return (
<div>
<br/>
<h1>Reddit Slider</h1>
<hr/>
<p>Please enter your query using the options below...</p>
<p>The range field accepts values like:</p>
<ul>
<li>"Today"</li>
<li>"June 20 2016 to now"</li>
<li>"May 18 8:00am to May 18 2:00pm"</li>
<li>"1 year ago"</li>
</ul>
</div>
);
}
});
module.exports = Information;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment