Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 149 additions & 0 deletions components/PopMenu.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import React from 'react';
import Popup from 'reactjs-popup';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';
import Draggable from 'react-draggable';

/**
* Required Props:
* array: array of JSON objects, should have string children of: name, title, instructor etc
* filter: filtering function of your choice, should act on above mentioned array
*/


//style declaration
const lStyle = {
overflow: 'auto',
maxHeight: '400px',
width: '300px',
};

const pStyle = {
fontSize: '14px',
textAlign: 'left',

};

const inStyle = {
width: '300px',
fontSize: '14px',
};


class PopMenu extends React.Component {
constructor(props) {
super(props);

this.handleClick = this.handleClick.bind(this);
this.handleOutsideClick = this.handleOutsideClick.bind(this);

this.state = {
visibleElements: 15,
popupVisible: false,
};

}

onListScroll = (event) => {
const el = document.getElementById('listDiv');
const max = el.scrollHeight;
const scrolled = el.scrollTop;
let newVisibleElements = this.state.visibleElements + 15;

if ( (max - scrolled) < 410 ) {
this.setState({
visibleElements: newVisibleElements});
}

//console.log(`max scroll height % : ${max}`);
//console.log(`amount scrolled? : ${scrolled}`);
};

handleFilterCall = (event) => {
this.props.filter(event);
this.setState({visibleElements: 15});
};

handleClick() {
if (!this.state.popupVisible) {
document.addEventListener('click', this.handleOutsideClick, false);
} else {
document.removeEventListener('click', this.handleOutsideClick, false);
}

this.setState(prevState => ({
popupVisible: !prevState.popupVisible,
}));
}

handleOutsideClick(e) {
if (this.node.contains(e.target)) {
return;
}
this.handleClick();
}

render() {
const data = this.props.array.slice(0, this.state.visibleElements);
let n = 0;
//console.log(`in Render, filtered: ${this.state.filtered}`);

return (
<Draggable enableUserSelectHack={false}>
<div>
<Popup
trigger={<input style={inStyle} onChange={this.handleFilterCall} type="text" placeholder="YAY!"/>}
position="bottom left"
onOpen={this.handleClick}
//on="click"
//closeOnDocumentClick
mouseLeaveDelay={300}
mouseEnterDelay={0}
contentStyle={{padding: '0px', border: 'none'}}
arrow={false}
>
{this.state.popupVisible && (
<div ref={node => { this.node = node; }} style={lStyle} id="listDiv" onScroll={this.onListScroll}>
<List >{data.map(({name, title, instructor, terms, description, geCategories, division}) => (
<div ref={this.setWrapperRef}>
<Popup trigger={
<ListItem
style={pStyle}
key={name + `${n++}`}
dense
divider
button
>
<ListItemText primary={name + ' ' + title} secondary={`Instr: ${instructor}`}/>
</ListItem>
} modal>
{close => (
<div className="modal">
<a className="close" onClick={close}>&times;</a>
<div className="header">
{`${name} ${title}`}
</div>
<div className={'content'}>
<p>{`Instructor: ${instructor}`}</p>
<p>{`Terms: ${terms}`}</p>
<p>{`GE: ${geCategories}`}</p>
<p>{`Division: ${division}`}</p>
<p>{`Description: ${description}`}</p>
</div>
</div>
)}
</Popup>
</div>
))}
</List>
</div>
)}
</Popup>
</div>
</Draggable>
);
}
}

export default PopMenu;
59 changes: 59 additions & 0 deletions components/Popups.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from 'react';
import Popup from 'reactjs-popup';


class Popups extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = {
tags: [] || props.tags,
}
}

static defaultProps = {
myLists: ({
course_title: 'Software Engineering',
course_number: '123',
instructor: 'Richard',
time: 'MW 9:00-12:30AM',
location: 'LEC Annex 101',
}),
};

handleClick(e) {
if (e === 'N/A') {
this.state.tags = 'N/A';
}
if (e === 'In Progress') {
this.state.tags = 'In Progress';
}
if (e === 'Finished') {
this.state.tags = 'Finished';
}
console.log(`get tags: ${this.state.tags}`);
}

render() {
return <div>
<Popup trigger={<a className="button">{this.props.myLists.course_title}</a>} modal>
{close => (
<div className="modal">
<a className="close" onClick={close}>&times;</a>
<button onClick={() => this.handleClick('N/A')}>N/A</button>
<button onClick={() => this.handleClick('In Progress')}>In Progress</button>
<button onClick={() => this.handleClick('Finished')}>Finished</button>
<div className="header">{this.props.myLists.course_number}</div>
<div className={'content'}>
<p>{'Instructor: '}{this.props.myLists.instructor}</p>
<p>{'Time: '}{this.props.myLists.time}</p>
<p>{'Location: '}{this.props.myLists.location}</p>
</div>
</div>
)}
</Popup>
</div>;
}
}

export default Popups;
23 changes: 23 additions & 0 deletions components/SearchBar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';

import PopMenu from './PopMenu';

class SearchBar extends React.Component {






render() {
return (
<div>
<PopMenu/>
</div>
)
}


}

export default SearchBar;
8 changes: 8 additions & 0 deletions pages/popups.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';
import Popups from '../components/Popups';

export default () => (
<div>
<Popups/>
</div>
);
81 changes: 81 additions & 0 deletions pages/searchbar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React from 'react';
import PropTypes from 'prop-types';
import fetch from 'isomorphic-unfetch';

import { withStyles } from '@material-ui/core/styles';
import PopMenu from '../components/PopMenu';

const styles = theme => ({
root: {
width: '100%',
maxWidth: 360,
backgroundColor: theme.palette.background.paper,
},
});

let indices = [];

class Index extends React.Component {
constructor(props) {
super(props);
this.state = {
filtered: this.props.courses.slice(0, 15),
};
}

static propTypes = {
courses: PropTypes.arrayOf(PropTypes.shape({
title: PropTypes.string.isRequired,
})),
};


static async getInitialProps() {
const res = await fetch('https://coursegraph.org/api/courses');
const data = await res.json();

console.log(`Show data fetched. Count: ${data.length}`);

return {
courses: data,
};
}

filter = (event) => {
console.log(`running page version of filter`);
let stringArray = new Array(this.props.courses.length);
for (let i = 0; i < this.props.courses.length; i++) {
stringArray[i] =
//JSON.stringify(this.state.unfiltered[i].name.toUpperCase()) +
//JSON.stringify(this.state.unfiltered[i].title.toUpperCase()) +
JSON.stringify(this.props.courses[i].instructor.toUpperCase());
}
let indexz = [];
let newArray = [];
for (let i = 0; i < this.props.courses.length; i++) {
if (stringArray[i].indexOf(event.target.value.toUpperCase() ) > -1 ) {
indexz.push(i);
}
}
for (let i = 0; i < indexz.length; i++) {
newArray.push(this.props.courses[indexz[i]]);
}
indices = indexz.slice();
this.setState({
filtered: newArray,
visibleElements: 15,
});
};


render() {
console.log(`indices: ${indices}`);
return (
<div>
<PopMenu array={this.state.filtered} filter={event => this.filter(event)}/>
</div>
);
}
}

export default withStyles(styles)(Index);