scratch-www/src/views/search/search.jsx

151 lines
6 KiB
React
Raw Normal View History

2016-04-18 16:51:45 -04:00
var injectIntl = require('react-intl').injectIntl;
var FormattedMessage = require('react-intl').FormattedMessage;
var React = require('react');
2016-10-31 10:19:35 -04:00
var connect = require('react-redux').connect;
2016-04-18 16:51:45 -04:00
var render = require('../../lib/render.jsx');
var api = require('../../lib/api');
2016-04-18 16:51:45 -04:00
var Page = require('../../components/page/www/page.jsx');
2016-08-12 16:31:09 -04:00
var TitleBanner = require('../../components/title-banner/title-banner.jsx');
var Form = require('../../components/forms/form.jsx');
var Input = require('../../components/forms/input.jsx');
var Button = require('../../components/forms/button.jsx');
var Tabs = require('../../components/tabs/tabs.jsx');
var Grid = require('../../components/grid/grid.jsx');
var navigationActions = require('../../redux/navigation.js');
2016-04-18 16:51:45 -04:00
require('./search.scss');
// @todo migrate to React-Router once available
2016-04-18 16:51:45 -04:00
var Search = injectIntl(React.createClass({
type: 'Search',
getDefaultProps: function () {
2016-06-09 07:32:25 -04:00
var pathname = window.location.pathname.toLowerCase();
if (pathname[pathname.length - 1] === '/') {
pathname = pathname.substring(0, pathname.length - 1);
}
var start = pathname.lastIndexOf('/');
2016-06-09 07:32:25 -04:00
var type = pathname.substring(start + 1, pathname.length);
return {
tab: type,
loadNumber: 16
};
2016-04-18 16:51:45 -04:00
},
getInitialState: function () {
return {
loaded: [],
offset: 0
};
},
componentDidMount: function () {
var query = window.location.search;
var q = query.lastIndexOf('q=');
var term = '';
if (q !== -1) {
term = query.substring(q + 2, query.length).toLowerCase();
}
while (term.indexOf('/') > -1) {
term = term.substring(0, term.indexOf('/'));
}
while (term.indexOf('&') > -1) {
term = term.substring(0, term.indexOf('&'));
}
term = term.split('+').join(' ');
this.getSearchMore();
this.props.dispatch(navigationActions.setSearchTerm(decodeURI(term)));
2016-04-18 16:51:45 -04:00
},
getSearchMore: function () {
var termText = '';
2016-06-09 07:32:25 -04:00
if (this.props.searchTerm !== '') {
termText = '&q=' + this.props.searchTerm;
}
api({
2016-06-09 07:32:25 -04:00
uri: '/search/' + this.props.tab +
'?limit=' + this.props.loadNumber +
'&offset=' + this.state.offset +
'&language=' + this.props.intl.locale +
2016-08-12 16:31:09 -04:00
'&mode=popular' +
2016-06-09 07:32:25 -04:00
termText
2016-04-18 16:51:45 -04:00
}, function (err, body) {
var loadedSoFar = this.state.loaded;
2016-06-09 07:32:25 -04:00
Array.prototype.push.apply(loadedSoFar, body);
this.setState({loaded: loadedSoFar});
var currentOffset = this.state.offset + this.props.loadNumber;
this.setState({offset: currentOffset});
2016-04-18 16:51:45 -04:00
}.bind(this));
},
2016-08-12 16:31:09 -04:00
onSearchSubmit: function (formData) {
window.location.href = '/search/projects?q=' + encodeURIComponent(formData.q);
2016-08-12 16:31:09 -04:00
},
getTab: function (type) {
var term = this.props.searchTerm.split(' ').join('+');
2016-06-09 07:32:25 -04:00
var allTab = <a href={'/search/' + type + '?q=' + term + '/'}>
2016-08-22 13:30:44 -04:00
<li>
2016-08-12 16:31:09 -04:00
<img src={'/svgs/tabs/' + type + '-inactive.svg'} className={'tab-icon ' + type} />
2016-06-09 07:32:25 -04:00
<FormattedMessage id={'general.' + type} />
2016-04-18 16:51:45 -04:00
</li>
</a>;
if (this.props.tab == type) {
2016-06-09 07:32:25 -04:00
allTab = <a href={'/search/' + type + '?q=' + term + '/'}>
<li className='active'>
2016-08-12 16:31:09 -04:00
<img src={'/svgs/tabs/' + type + '-active.svg'} className={'tab-icon ' + type} />
2016-06-09 07:32:25 -04:00
<FormattedMessage id={'general.' + type} />
2016-04-18 16:51:45 -04:00
</li>
</a>;
}
return allTab;
},
render: function () {
var formatMessage = this.props.intl.formatMessage;
2016-08-12 16:31:09 -04:00
2016-04-18 16:51:45 -04:00
return (
<div>
<div className='outer'>
2016-08-12 16:31:09 -04:00
<TitleBanner className="masthead">
<div className="inner">
<h1 className="title-banner-h1"><FormattedMessage id="general.search" /></h1>
2016-08-12 16:31:09 -04:00
<div className="search">
<Form onSubmit={this.onSearchSubmit}>
<Button type="submit" className="btn-search" />
<Input type="text"
aria-label={formatMessage({id: 'general.search'})}
placeholder={formatMessage({id: 'general.search'})}
value={this.props.searchTerm}
2016-08-12 16:31:09 -04:00
name="q" />
</Form>
</div>
</div>
</TitleBanner>
<Tabs>
{this.getTab('projects')}
{this.getTab('studios')}
</Tabs>
<div id='projectBox' key='projectBox'>
2016-08-12 16:31:09 -04:00
<Grid items={this.state.loaded}
itemType={this.props.tab}
cards={true}
showAvatar={true}
showLoves={false}
showFavorites={false}
showViews={false} />
<Button onClick={this.getSearchMore} className="white">
<FormattedMessage id='general.loadMore' />
</Button>
2016-04-18 16:51:45 -04:00
</div>
</div>
</div>
);
}
}));
2016-10-31 10:05:08 -04:00
var mapStateToProps = function (state) {
return {
searchTerm: state.navigation
2016-10-31 10:05:08 -04:00
};
};
var ConnectedSearch = connect(mapStateToProps)(Search);
2016-10-31 10:05:08 -04:00
render(<Page><ConnectedSearch /></Page>, document.getElementById('app'));