Commit 5f18472b authored by Florent Chehab's avatar Florent Chehab

Search ok and some tweaks

parent ebac59c4
......@@ -34,6 +34,7 @@ import {
import PageMap from './pages/PageMap';
import PageHome from './pages/PageHome';
import PageFilter from './pages/PageFilter';
import PageSearch from './pages/PageSearch';
const drawerWidth = 240;
......@@ -158,6 +159,7 @@ class App extends MyComponent {
<main className={classes.content}>
<Route path="/app/" exact={true} component={PageHome} />
<Route path="/app/search" component={PageSearch} />
<Route path="/app/map" component={PageMap} />
<Route path="/app/filter" component={PageFilter} />
......
......@@ -18,6 +18,15 @@ class MyComponent extends Component {
return out;
}
joinCampus(campus) {
const { universities, countries, cities } = this.getAllFetchedData();
let res = Object.assign({}, campus); //copy for safety
res.university = universities[campus.university];
res.city = cities[campus.city]
res.country = countries[res.city.country]
return res;
}
checkProps(val) {
for (let el in this.props) {
let prop = this.props[el];
......
......@@ -2,7 +2,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import deburr from 'lodash/deburr';
import keycode from 'keycode';
import Downshift from 'downshift';
import { withStyles } from '@material-ui/core/styles';
......
......@@ -15,15 +15,6 @@ import {
class Filter extends MyComponent {
joinCampus(campus) {
const { universities, countries, cities } = this.getAllFetchedData();
let res = Object.assign({}, campus); //copy for safety
res.university = universities[campus.university];
res.city = cities[campus.city]
res.country = countries[res.city.country]
return res;
}
saveContriesFilterConfig(state) {
this.props.saveConfig({ contriesFilter: state })
}
......@@ -73,12 +64,12 @@ class Filter extends MyComponent {
(c) => { return { id: c.iso_alpha2_code, label: c.name } })
return (
<DownshiftMultiple
options={options}
onChange={(selection) => this.updateSelectedUniversities(selection)}
onComponentUnmount={(state) => this.saveContriesFilterConfig(state)}
config={this.props.contriesFilterConfig}
/>
<DownshiftMultiple
options={options}
onChange={(selection) => this.updateSelectedUniversities(selection)}
onComponentUnmount={(state) => this.saveContriesFilterConfig(state)}
config={this.props.contriesFilterConfig}
/>
);
}
}
......
......@@ -12,7 +12,7 @@ const styles = theme => ({
}
});
class PageMap extends React.Component {
class PageFilter extends React.Component {
render() {
const { classes } = this.props;
return (
......@@ -33,8 +33,8 @@ class PageMap extends React.Component {
}
}
PageMap.propTypes = {
PageFilter.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(PageMap);
export default withStyles(styles)(PageFilter);
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Grid from '@material-ui/core/Grid';
import Typography from '@material-ui/core/Typography';
import Search from '../search/Search';
import Paper from '@material-ui/core/Paper';
const styles = theme => ({
myPaper: {
padding: 16
}
});
class PageSearch extends React.Component {
render() {
const { classes } = this.props;
return (
<Paper className={classes.myPaper}>
<Grid container spacing={24}>
<Grid item xs={11}>
<Typography variant="display1" gutterBottom>
Recherche d'une université
</Typography>
</Grid>
{/* <Grid item xs={1}>
<UnivMapReloadButton />
</Grid> */}
</Grid>
<Search />
</Paper>
);
}
}
PageSearch.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(PageSearch);
import React from 'react';
import TextField from '@material-ui/core/TextField';
import Paper from '@material-ui/core/Paper';
import MyComponent from '../MyComponent'
import { connect } from "react-redux";
import fuzzysort from 'fuzzysort';
import UnivList from './UnivList';
import _ from 'underscore';
// import { saveSelectedUniversities, saveSearchConfig } from '../../actions/filter';
import { withStyles } from '@material-ui/core/styles';
import {
universitiesFetchData,
mainCampusesFetchData,
citiesFetchData,
countriesFetchData
} from '../../generated/actions';
const styles = theme => ({
inputCentered: {
textAlign: 'center'
},
});
class Search extends MyComponent {
state = {
suggestions: []
}
getSuggestions(value) {
console.log(value)
const { universities } = this.getAllFetchedData();
const filter = fuzzysort.go(value, _.map(universities, (univ) => univ), { keys: ['name', 'acronym'] });
let out;
if (filter.length > 0) {
out = _.map(filter, (item) => item.obj)
} else {
out = universities
}
this.setState({ suggestions: out })
}
// saveContriesSearchConfig(state) {
// this.props.saveConfig({ contriesSearch: state })
// }
// getCountriesWhereThereAreUniversities() {
// const { mainCampuses } = this.getAllFetchedData();
// let res = [];
// _.each(mainCampuses, (campus) => {
// const campusFull = this.joinCampus(campus)
// res.push(campusFull.country)
// });
// return _.uniq(res, false, (c) => { return c.iso_alpha2_code });
// }
// updateSelectedUniversities(selection) {
// const { mainCampuses } = this.getAllFetchedData();
// const listOfCountries = _.map(selection, (s) => s.id);
// let selected_universities = []
// _.each(mainCampuses, (campus) => {
// const campusFull = this.joinCampus(campus)
// if (_.indexOf(listOfCountries, campusFull.country.iso_alpha2_code) > -1) {
// selected_universities.push(campusFull.university.id);
// }
// })
// this.props.saveSelection(selected_universities);
// }
myRender() {
const { classes } = this.props;
// const options = _.map(this.getCountriesWhereThereAreUniversities(),
// (c) => { return { id: c.iso_alpha2_code, label: c.name } })
return (
// <DownshiftMultiple
// options={options}
// onChange={(selection) => this.updateSelectedUniversities(selection)}
// onComponentUnmount={(state) => this.saveContriesSearchConfig(state)}
// config={this.props.contriesSearchConfig}
// />
<div>
<TextField
id="full-width"
label=""
InputLabelProps={{
shrink: true,
}}
placeholder="Rechercher..."
// helperText=""
fullWidth
margin="normal"
InputProps={{ classes: { input: classes.inputCentered } }}
onChange={(e) => this.getSuggestions(e.target.value)}
/>
{/* <Paper>{JSON.stringify(this.state.suggestions)}</Paper> */}
{
<UnivList universitiesToList={this.state.suggestions} />
}
</div>
);
}
}
const mapStateToProps = (state) => {
return {
universities: state.universities,
mainCampuses: state.mainCampuses,
cities: state.cities,
countries: state.countries,
// contriesSearchConfig: state.app.filter.contriesSearch
};
};
const mapDispatchToProps = (dispatch) => {
return {
fetchData: {
universities: () => dispatch(universitiesFetchData()),
mainCampuses: () => dispatch(mainCampusesFetchData()),
cities: () => dispatch(citiesFetchData()),
countries: () => dispatch(countriesFetchData())
},
// saveSelection: (selectedUniversities) => dispatch(saveSelectedUniversities(selectedUniversities)),
// saveConfig: (config) => dispatch(saveSearchConfig(config))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(Search));
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import MobileStepper from '@material-ui/core/MobileStepper';
import Paper from '@material-ui/core/Paper';
import Typography from '@material-ui/core/Typography';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import _ from 'underscore';
import ListItemText from '@material-ui/core/ListItemText';
import Divider from '@material-ui/core/Divider';
import Button from '@material-ui/core/Button';
import KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft';
import KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight';
import SwipeableViews from 'react-swipeable-views';
const styles = theme => ({
root: {
maxWidth: 650,
marginLeft: "auto",
marginRight: "auto",
flexGrow: 1,
},
header: {
display: 'flex',
alignItems: 'center',
height: 50,
paddingLeft: theme.spacing.unit * 4,
marginBottom: 20,
backgroundColor: theme.palette.background.default,
},
});
class UnivList extends React.Component {
state = {
activeStep: 0,
};
componentDidUpdate(prevProps, prevState, snapshot) {
if (prevProps.universitiesToList != this.props.universitiesToList) {
this.handleStepChange(0);
}
}
handleNext = () => {
console.log("next")
this.setState(prevState => ({
activeStep: prevState.activeStep + 1,
}));
};
handleBack = () => {
console.log("back")
this.setState(prevState => ({
activeStep: prevState.activeStep - 1,
}));
};
handleStepChange = activeStep => {
console.log("step change")
this.setState({ activeStep });
};
render() {
const { classes, theme, itemsPerPage, universitiesToList } = this.props;
const { activeStep } = this.state;
const numberOfItems = universitiesToList.length;
// Prevent bug
if (!numberOfItems) {
return <div></div>;
}
const maxSteps = Math.ceil(numberOfItems / itemsPerPage);
console.log("maxSteps", maxSteps, "numberOfItems", numberOfItems, "itemsPerPage");
return (
<div className={classes.root}>
<SwipeableViews
axis={theme.direction === 'rtl' ? 'x-reverse' : 'x'}
index={this.state.activeStep}
onChangeIndex={this.handleStepChange}
enableMouseEvents
>
{_.map(_.range(maxSteps), page => (
<div key={page}>
<List component="nav">
<Divider />
{_.map(_.range((page) * itemsPerPage, Math.min((page + 1) * itemsPerPage, numberOfItems)),
univ_ind => (
<ListItem button divider={true} key={univ_ind}>
<ListItemText primary={universitiesToList[univ_ind].name} />
</ListItem>
))
}
</List>
</div>
))}
</SwipeableViews>
<MobileStepper
steps={maxSteps}
position="static"
activeStep={activeStep}
className={classes.mobileStepper}
nextButton={
<Button color="secondary" size="small" onClick={this.handleNext} disabled={activeStep >= maxSteps - 1}>
Suivant
{theme.direction === 'rtl' ? <KeyboardArrowLeft /> : <KeyboardArrowRight />}
</Button>
}
backButton={
<Button color="secondary" size="small" onClick={this.handleBack} disabled={activeStep === 0}>
{theme.direction === 'rtl' ? <KeyboardArrowRight /> : <KeyboardArrowLeft />}
Précédent
</Button>
}
/>
</div>
);
}
}
UnivList.propTypes = {
classes: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
};
UnivList.defaultProps = {
itemsPerPage: 10
};
export default withStyles(styles, { withTheme: true })(UnivList);
\ No newline at end of file
......@@ -5513,6 +5513,86 @@
"react-transition-group": "^2.2.1"
}
},
"react-swipeable-views": {
"version": "0.12.17",
"resolved": "https://registry.npmjs.org/react-swipeable-views/-/react-swipeable-views-0.12.17.tgz",
"integrity": "sha512-+egPdA4vqe1h4a9OIFWHKZER9aMPVrggiZ7PtXRyovsuLCDsoiIgGjNujuEOKVEskNjN1LHtQjQsPWinT7UD6A==",
"requires": {
"@babel/runtime": "7.0.0",
"dom-helpers": "^3.2.1",
"prop-types": "^15.5.4",
"react-swipeable-views-core": "^0.12.17",
"react-swipeable-views-utils": "^0.12.17",
"warning": "^4.0.1"
},
"dependencies": {
"@babel/runtime": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0.tgz",
"integrity": "sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA==",
"requires": {
"regenerator-runtime": "^0.12.0"
}
},
"regenerator-runtime": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz",
"integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg=="
}
}
},
"react-swipeable-views-core": {
"version": "0.12.17",
"resolved": "https://registry.npmjs.org/react-swipeable-views-core/-/react-swipeable-views-core-0.12.17.tgz",
"integrity": "sha512-KfQ+BPfLVBe7kxb+0zbVJp3eGQfZlt1gn5J+GYAgnYoZ29GrqkTfiQFKmrG4tmVnhxvRiXFA7Q0q9EBMYTc/FA==",
"requires": {
"@babel/runtime": "7.0.0",
"warning": "^4.0.1"
},
"dependencies": {
"@babel/runtime": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0.tgz",
"integrity": "sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA==",
"requires": {
"regenerator-runtime": "^0.12.0"
}
},
"regenerator-runtime": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz",
"integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg=="
}
}
},
"react-swipeable-views-utils": {
"version": "0.12.17",
"resolved": "https://registry.npmjs.org/react-swipeable-views-utils/-/react-swipeable-views-utils-0.12.17.tgz",
"integrity": "sha512-S0ERcHcTdOPz7LC/z+fDpJW1Z03b71V+MpG0RcY2mtEfsK7BJHqyIuht4KIJKApVrngxV9xWLBOYqeP7R86gWA==",
"requires": {
"@babel/runtime": "7.0.0",
"fbjs": "^0.8.4",
"keycode": "^2.1.7",
"prop-types": "^15.6.0",
"react-event-listener": "^0.6.0",
"react-swipeable-views-core": "^0.12.17"
},
"dependencies": {
"@babel/runtime": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0.tgz",
"integrity": "sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA==",
"requires": {
"regenerator-runtime": "^0.12.0"
}
},
"regenerator-runtime": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz",
"integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg=="
}
}
},
"react-transition-group": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.4.0.tgz",
......
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