Skip to content

Commit

Permalink
Fix several frontend bugs (#55)
Browse files Browse the repository at this point in the history
  • Loading branch information
itaisteinherz authored Feb 7, 2019
1 parent d963110 commit 56af25b
Show file tree
Hide file tree
Showing 22 changed files with 190 additions and 145 deletions.
68 changes: 25 additions & 43 deletions client/components/Header.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import React from "react";
import PropTypes from "prop-types";
import Router from "next/router";
import Link from "next/link";
import {Layout, Menu, Icon, Drawer} from "antd";
import {Layout, Menu} from "antd";

import HeaderMenu from "./HeaderMenu";

import "antd/dist/antd.css";
import "../static/Header.css";

const {Header} = Layout;

export default class MainHeader extends React.Component {
state = {
drawerIsVisible: false,
currentItem: "0"
};
}

componentDidMount() {
let currentItem = "0";
Expand All @@ -31,59 +35,37 @@ export default class MainHeader extends React.Component {
this.setState({currentItem});
}

openDrawer = () => {
this.setState({
drawerIsVisible: true,
currentItem: "0"
});
};

closeDrawer = () => {
this.setState({
drawerIsVisible: false
});
};
navigateHome = () => {
if (window.location.pathname === "/") {
window.location.reload();
} else {
Router.push("/");
}
}

render() {
const {drawerIsVisible, currentItem} = this.state;
const {currentItem} = this.state;
const {authState} = this.props;

return (
<Header className="header">
<nav className="header__nav">
<div className="header__nav--brand">
<Link href="/">
<a>Knowledge</a>
</Link>
<a onClick={this.navigateHome}>Knowledge</a>
</div>
<HeaderMenu authState={authState} currentItem={currentItem}/>
<Menu
mode="horizontal"
className="header__menu"
theme="light"
selectedKeys={[currentItem]}
onClick={this.handleClick}
mode="horizontal"
selectedKeys={[currentItem === "1" || currentItem === "2" ? "1" : "0"]}
className="header__join"
>
{authState !== "unchecked" ? // eslint-disable-line no-negated-condition
<Menu.Item key="1">
<Link href={`/${authState === "logged in" ? "logout" : "login"}`}>
<a>{authState === "logged in" ? "Logout" : "Login"}</a>
</Link>
</Menu.Item> :
null}
{authState === "logged out" ?
<Menu.Item key="2">
<Link href="/register">
<a>Register</a>
</Link>
</Menu.Item> :
null}
<Menu.Item key="1">
<Link href="/register">
<a>Join</a>
</Link>
</Menu.Item>
</Menu>
<div className="header__drawer--toggle" onClick={this.openDrawer}>
<Icon type="bars" onClick={this.openDrawer}/>
</div>
<Drawer visible={drawerIsVisible} onClose={this.closeDrawer}>
<Menu mode="vertical" className="mobile__menu"/>
</Drawer>
</nav>
</Header>
);
Expand Down
48 changes: 48 additions & 0 deletions client/components/HeaderMenu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from "react";
import PropTypes from "prop-types";
import Link from "next/link";
import {Menu} from "antd";

const HeaderMenu = ({currentItem = "0", handleClick, authState = "unchecked", className = "header__menu", mode = "horizontal"}) => {
return (
<Menu
mode={mode}
className={className}
theme="light"
selectedKeys={[currentItem]}
onClick={handleClick}
>
{authState !== "unchecked" ? // eslint-disable-line no-negated-condition
<Menu.Item key="1">
<Link href={`/${authState === "logged in" ? "logout" : "login"}`}>
<a>{authState === "logged in" ? "Logout" : "Login"}</a>
</Link>
</Menu.Item> :
null}
{authState === "logged out" ?
<Menu.Item key="2">
<Link href="/register">
<a>Register</a>
</Link>
</Menu.Item> :
null}
</Menu>
);
};

HeaderMenu.propTypes = {
mode: PropTypes.string,
className: PropTypes.string,
authState: PropTypes.string,
handleClick: PropTypes.func,
currentItem: PropTypes.string
};
HeaderMenu.defaultProps = {
mode: "horizontal",
className: "header__menu",
authState: "unchecked",
handleClick: () => {},
currentItem: "0"
};

export default HeaderMenu;
4 changes: 2 additions & 2 deletions client/components/LoginForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import "../static/LoginForm.css";
class LoginForm extends React.Component {
state = {
error: null
};
}

handleSubmit = e => {
e.preventDefault();
Expand All @@ -33,7 +33,7 @@ class LoginForm extends React.Component {
error: validationError && validationError.message ? validationError : null
});
});
};
}

render() {
const {error} = this.state;
Expand Down
6 changes: 3 additions & 3 deletions client/components/QuestionForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const {TextArea} = Input;
class QuestionForm extends React.Component {
state = {
tags: []
};
}

handleSubmit = e => {
e.preventDefault();
Expand All @@ -28,15 +28,15 @@ class QuestionForm extends React.Component {
});
}
});
};
}

cancel() {
Router.push("/");
}

updateQuestionTags = tags => {
this.setState({tags});
};
}

render() {
const {getFieldDecorator} = this.props.form;
Expand Down
8 changes: 4 additions & 4 deletions client/components/RegisterForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import "../static/RegisterForm.css";
class RegisterForm extends React.Component {
state = {
confirmDirty: false // TODO: Figure out what this is used for and if we even need it.
};
}

handleSubmit = e => {
e.preventDefault();
Expand All @@ -20,7 +20,7 @@ class RegisterForm extends React.Component {
this.props.signup(values);
}
});
};
}

compareToFirstPassword = (rule, value, callback) => {
const {form} = this.props;
Expand All @@ -29,7 +29,7 @@ class RegisterForm extends React.Component {
} else {
callback();
}
};
}

validateToNextPassword = (rule, value, callback) => {
const {form} = this.props;
Expand All @@ -38,7 +38,7 @@ class RegisterForm extends React.Component {
}

callback();
};
}

render() {
const {getFieldDecorator} = this.props.form;
Expand Down
30 changes: 23 additions & 7 deletions client/components/SearchForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,32 @@ class SearchForm extends React.Component {
isNewQuery: true // TODO: Make sure this always recognizes new queries correctly, even if we remove all query text except for one character.
}

handleChange = e => {
if (e.target.value.length === 1) {
componentDidUpdate() {
const {isNewQuery} = this.state;

if (this.searchInput instanceof HTMLElement) {
const inputField = this.searchInput.querySelector(".ant-input");
if (inputField === document.activeElement && !isNewQuery) {
inputField.blur();
}
}
}

handleChange = event => {
if (event.target.value.length === 1) {
this.setState({
isNewQuery: true
});
}
}

onSearch = async value => {
if (this.state.isNewQuery) {
this.setState({isNewQuery: false});
}

try {
await this.props.search(value);

if (this.state.isNewQuery) {
this.setState({isNewQuery: false});
}
} catch (error) {
console.error("error", error);
}
Expand All @@ -36,7 +47,12 @@ class SearchForm extends React.Component {
const {ranSearch = false, stemmedWords = [], updateTags} = this.props;

return (
<div className="search_input">
<div
ref={input => {
this.searchInput = input;
}}
className="search_input"
>
<h1 className="search_input--title">Search</h1>
<Input.Search
enterButton
Expand Down
48 changes: 28 additions & 20 deletions client/components/SearchTag.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class SearchTag extends React.Component {
state = {
tags: [],
activeTags: []
};
}

updateTags = async e => {
try {
Expand All @@ -24,16 +24,18 @@ class SearchTag extends React.Component {
console.log(error);
return [];
}
};
}

componentDidMount() {
this.updateTags();
}

componentDidUpdate(prevProps) { // TODO: Only update the tags if a new query has been searched for (i.e. the user has removed all contents from the search input and then typed a new query).
const tagSearchField = document.querySelector(".ant-select-search__field");
if (tagSearchField) {
tagSearchField.addEventListener("input", this.updateTags); // TODO: Make sure that we always have at least 5 tags in the autocomplete list.
if (this.tagSelect instanceof HTMLElement) {
const tagInputField = this.tagSelect.querySelector(".ant-select-search__field");
if (tagInputField) {
tagInputField.addEventListener("input", this.updateTags); // TODO: Make sure that we always have at least 5 tags in the autocomplete list.
}
}

const {tags} = this.state;
Expand Down Expand Up @@ -64,15 +66,15 @@ class SearchTag extends React.Component {
}

return clonedArr;
};
}

handleChange = tag => {
this.setState(prevState => ({
activeTags: this.toggleElementIntoArray(tag, prevState.activeTags)
}), () => {
this.props.updateTags(this.state.activeTags);
});
};
}

render() {
const {ranSearch = false} = this.props;
Expand All @@ -85,20 +87,26 @@ class SearchTag extends React.Component {

return (
// TODO: Figure out how to stop the options popup from jumping around, and make it stay under the tag field.
<Select
mode="multiple"
style={{width: "100%"}}
placeholder="Tags to search for..."
notFoundContent="No matching tags found"
value={activeTags}
onSelect={this.handleChange}
onDeselect={this.handleChange}
<div
ref={element => {
this.tagSelect = element;
}}
>
{tags
.map(tag => <Option key={tag.name}>{tag.name}</Option>)
.filter(option => !activeTags.includes(option.key))
}
</Select>
<Select
mode="multiple"
style={{width: "100%"}}
placeholder="Tags to search for..."
notFoundContent="No matching tags found"
value={activeTags}
onSelect={this.handleChange}
onDeselect={this.handleChange}
>
{tags
.map(tag => <Option key={tag.name}>{tag.name}</Option>)
.filter(option => !activeTags.includes(option.key))
}
</Select>
</div>
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion client/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
"storageBucket": "react-firebase-85039.appspot.com",
"messagingSenderId": "55358337129"
},
"apiUrl": "http://knowl-knowl-ciw3basidwqs-321112760.eu-central-1.elb.amazonaws.com/"
"apiUrl": "http://knowl-knowl-ciw3basidwqs-321112760.eu-central-1.elb.amazonaws.com"
}
8 changes: 4 additions & 4 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
"node": ">=8"
},
"scripts": {
"dev": "next",
"dev": "next dev",
"start": "next start",
"heroku:start": "next start --port $PORT",
"build": "next build",
"container:build": "docker build -t knowledge-client .",
"container:run": "docker run -d --name knowledge-client -p 3000:3000 knowledge-client",
"heroku:start": "next start --port $PORT",
"docker:build": "docker build -t knowledge-client .",
"docker:run": "docker run -d --name knowledge-client -p 3000:3000 knowledge-client",
"test": "xo"
},
"dependencies": {
Expand Down
Loading

0 comments on commit 56af25b

Please sign in to comment.