Skip to content

Commit

Permalink
Milestone 54 / Convert Navbar to React (#2306)
Browse files Browse the repository at this point in the history
* Navbar dropdowns conversion to React (#2230)

* Implement currencies using Dropdown Menu Component

* Add active prop on list item in Dropdown menu

* Resolve reactivity for currency drop down

* Add language dropdown implementation

* Add select on current selected language

* Remove extra code

* Have language icon div be larger

* Fix pop over arrangement

* Fix spacing, add caret on language dropdown

* Deal with display when switches are pff

* Fix overflow issues on dropdown-menu

* Fix linting

* Close dropdown on menu item click

* Add import for Match

* Convert login views to React (#2250)

* Initial component/container setup for sign in page

* Replicate look of sign in form

* Replicate look of sign up form

* Use composeWithTracker in signInContainer

* Replicate look of forgot password form

* Create parent login container to hold general login for views

* Add switching between views logic

* Set up sign in form submission

* Set up sign up form submission

* Set up forgot password form submission

* Handle sign in action and error message display

* Remove template methods

* Remove template methods and alert message template

* Rewrite renderPasswordErrors method

* Render social buttons on login

* Add social login functionality

* Remove unnecessary blaze templates

* Move functions to React

* Implement sign up functionality

* Merge signin and signup containers

* Put back helper methods needed by other templates

* Abstract loginFormMessaged into react container

* Add forgot password functionality (part1)

* Remove unnecessary component in helper

* Remove forgot password template

* Clean up folder structure

* Solve invariant violation browser error

* updatepasswordOverlay react component/container

* completed updayePasswordOverlay functionality

* Remove stopPropagation function

* Capitalize social login name

* Show loading spinner while processing button clicks

* Solve onClick not working by removing 'event.stopPropagation()' on parent template

* Remove JQuery and use lodash

* Using 'event' instead of 'e' to reference event handlers

* Add validation for no email input on forgot password

* Add error message on social login

* Move capitalize function to helper file

* Move capitalize function to helper file

* [WIP]Main navbar container conversion to React (#2277)

Main navbar container conversion to React

* Convert to react: Tag navigation (#2251)

* Test tagnav component

* Use existing tag component

* Update component setup

* Use existing tagsList container

* Remove debugging

* Edit button

* Use tagItem loop to match styles instead of existing

* Base tagTree init

* Fix structure

* Fix dropdown mouseover event

* Edit conditional

* Base tag editatble

* Button switch fix

* On edit fix

* Selectable button icon

* Enable drop of tagtree by icon

* Init edit mode for tagTree

* Tagtree second level new tag

* Typo fix

* Fix top level width and classes

* Show Base tagList

* Lint clean up

* Remove commented code

* Style fix and show new tag on edit

* i18n

* Init saving top level tags

* Saving tags - cont

* New tag save fix

* Switching to Taglist custom

* Saving top level

* Enable new tag option

* Move class names to base comp

* Style on create new tag item

* Fix Hover back

* Move file

* Tag select prop

* Rename files

* Fix save and delete

* Reorder element wrapper

* Init passing the functions down

* Init editing new tag item on tree

* Separate the two new tagItems

* Adding new tags on tree + refactor 🎉

* Fix delete on subtags

* Reset form after save and prevent saving empty tags

* Prevent close of tree after save

* Restructure tree state to fix input

* Init refactor on tagTree

* Props setup after refactor

* Reposition button

* Autocompletion fixing

* Add componentWillReceiveProps to fix re-render and reset

* Refactor into container comp

* Remove debugs

* Use composewithTracker

* Remove props with spread

* Update props list

* Fix logic breaking new tag style

* Tag sort order after drag

* Clean un-used vars

* Add react tagNav to main navbar container

* Fix lint issue

* Init toggle visibility

* Close tags with overlay

* Remove JQuery references(part 1)

* Add router.go for tag click

* Mobile fixes and remove blaze files

* Fix click on mobile

* Remove jquery

* Remove jquery .closest

* UI tagnav classes update

* Fixes

* Fix undefined refs after merge with development

* Remove unused vars

* Editing should turn off on toggle

* Use Translation component over data-i18n

* Fix Brand name glitch

* Prefer standalone PropTypes import over React.PropTypes

* Inport i18next and Reaction in same line

* Space at end of self-closing tag

* One-lining imports

* Place '&nbsp' inside span for less random-looking code

* Add comment about style

* Use Divider component as separator
  • Loading branch information
brent-hoover authored Jun 8, 2017
1 parent f3ca0d4 commit 1e4d7fc
Show file tree
Hide file tree
Showing 83 changed files with 3,777 additions and 1,693 deletions.
3 changes: 3 additions & 0 deletions client/modules/accounts/components/auth/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export LoginButtons from "./loginButtons";
export SignIn from "./signIn";
export SignUp from "./signUp";
76 changes: 76 additions & 0 deletions client/modules/accounts/components/auth/loginButtons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import { Button, Divider, Translation } from "/imports/plugins/core/ui/client/components";

class LoginButtons extends Component {
static propTypes = {
capitalizeName: PropTypes.func,
currentView: PropTypes.string,
loginServices: PropTypes.func,
onSeparator: PropTypes.func,
onSocialClick: PropTypes.func
}

renderLoginButtons() {
const enabledServices = this.props.loginServices().filter((service) =>{
return service.enabled;
});

return (
<div>
{this.props.loginServices &&
enabledServices.map((service) => (
<Button
key={service._id}
className={`btn-block provider-${service.name}`}
primary={true}
bezelStyle="solid"
type="button"
data-provider={`${service.name}`}
onClick={() => this.props.onSocialClick(service.name)}
>
<i className={`fa fa-${service.name}`} />

{this.props.currentView === "loginFormSignInView" &&
<span>
<Translation defaultValue="Sign in with" i18nKey="accountsUI.signInWith" />
</span>
}
{this.props.currentView === "loginFormSignUpView" &&
<span>
<Translation defaultValue="Sign up with" i18nKey="accountsUI.signUpWith" />
</span>
}

<span>
&nbsp;
<Translation defaultValue={this.props.capitalizeName(service.name)} i18nKey={`social.${service.name}`} />
</span>
</Button>
))
}
</div>
);
}

renderSeparator() {
if (this.props.onSeparator()) {
return (
<div className="loginForm-seperator">
<Divider id="auth-divider" label="or" i18nKeyLabel="accountsUI.or" />
</div>
);
}
}

render() {
return (
<div>
{this.renderLoginButtons()}
{this.renderSeparator()}
</div>
);
}
}

export default LoginButtons;
182 changes: 182 additions & 0 deletions client/modules/accounts/components/auth/signIn.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import classnames from "classnames";
import { Button, TextField, Translation } from "/imports/plugins/core/ui/client/components";

class SignIn extends Component {
static propTypes = {
credentials: PropTypes.object,
isLoading: PropTypes.bool,
loginFormMessages: PropTypes.func,
messages: PropTypes.object,
onError: PropTypes.func,
onForgotPasswordClick: PropTypes.func,
onFormSubmit: PropTypes.func,
onSignUpClick: PropTypes.func,
uniqueId: PropTypes.string
}

constructor(props) {
super(props);

this.state = {
email: props.credentials.email,
password: props.credentials.password
};

this.handleFieldChange = this.handleFieldChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}

handleFieldChange = (event, value, field) => {
this.setState({
[field]: value
});
}

handleSubmit = (event) => {
if (this.props.onFormSubmit) {
this.props.onFormSubmit(event, this.state.email, this.state.password);
}
}

renderEmailErrors() {
if (this.props.onError(this.props.messages.errors && this.props.messages.errors.email)) {
return (
<span className="help-block">
<Translation
defaultValue={this.props.messages.errors.email.reason}
i18nKey={this.props.messages.errors.email.i18nKeyReason}
/>
</span>
);
}
}

renderPasswordErrors() {
return (
<span className="help-block">
{this.props.onError(this.props.messages.errors && this.props.messages.errors.password) &&
this.props.messages.errors.password.map((error, i) => (
<Translation
key={i}
defaultValue={error.reason}
i18nKey={error.i18nKeyReason}
/>
))
}
</span>
);
}

renderFormMessages() {
if (this.props.loginFormMessages) {
return (
<div>
{this.props.loginFormMessages()}
</div>
);
}
}

renderSpinnerOnWait() {
if (this.props.isLoading === true) {
return (
<div style={{ textAlign: "center" }}>
<i className="fa fa-spinner fa-spin" />
</div>
);
}
return (
<Button
className="btn-block"
primary={true}
bezelStyle="solid"
i18nKeyLabel="accountsUI.signIn"
label="Sign In"
type="submit"
tabIndex="3"
eventAction="submitSignInForm"
/>
);
}

render() {
const emailClasses = classnames({
"form-group": true,
"form-group-email": true,
"has-error has-feedback": this.props.onError(this.props.messages.errors && this.props.messages.errors.email)
});

const passwordClasses = classnames({
"form-group": true,
"has-error has-feedback": this.props.onError(this.props.messages.errors && this.props.messages.errors.password)
});
return (
<div>
<div className="loginForm-title">
<h2>
<Translation defaultValue="Sign In" i18nKey="accountsUI.signIn" />
</h2>
</div>

<form className="login-form" onSubmit={this.handleSubmit} noValidate>

{this.renderFormMessages()}

<div className={emailClasses}>
<TextField
i18nKeyLabel="accountsUI.emailAddress"
label="Email"
name="email"
type="email"
tabIndex="1"
id={`email-${this.props.uniqueId}`}
value={this.state.email}
onChange={this.handleFieldChange}
/>
{this.renderEmailErrors()}
</div>

<div className={passwordClasses}>
<TextField
i18nKeyLabel="accountsUI.password"
label="Password"
name="password"
type="password"
tabIndex="2"
id={`password-${this.props.uniqueId}`}
value={this.state.password}
onChange={this.handleFieldChange}
/>
{this.renderPasswordErrors()}
</div>

<div className="form-group">
{this.renderSpinnerOnWait()}
</div>

<div className="form-group flex flex-justify-spaceBetween">
<a
href="#"
tabIndex="4"
onClick={this.props.onForgotPasswordClick}
>
<Translation defaultValue="Reset Password" i18nKey="accountsUI.forgotPassword" />
</a>
<a
href="#"
tabIndex="5"
onClick={this.props.onSignUpClick}
>
<Translation defaultValue="Register" i18nKey="accountsUI.signUp" />
</a>
</div>

</form>
</div>
);
}
}

export default SignIn;
Loading

0 comments on commit 1e4d7fc

Please sign in to comment.