Skip to content

Commit

Permalink
Merge pull request #269 from uclaacm/loginpage
Browse files Browse the repository at this point in the history
New Login Page Design & Unifying Login/CreateUser
  • Loading branch information
krashanoff authored May 30, 2020
2 parents 0dfd919 + d3a985d commit dfbb280
Show file tree
Hide file tree
Showing 17 changed files with 366 additions and 199 deletions.
28 changes: 0 additions & 28 deletions src/components/CreateUser.js

This file was deleted.

16 changes: 0 additions & 16 deletions src/components/CreateUser.test.js

This file was deleted.

142 changes: 134 additions & 8 deletions src/components/Login.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,146 @@
import React from "react";
import Footer from "./common/Footer";
import "styles/Login.scss";
import LoginForm from "./Login/LoginForm";
import LoginGuy from "img/blueguy.png";
import CreateUserForm from "./Login/CreateUserForm.js";

import { faCode, faHeart, faPaintBrush, faRedo, faRocket } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

import LoginImg1 from "img/login1.svg";
import LoginImg2 from "img/login2.svg";
import LoginImg3 from "img/login3.svg";
import LoginImg4 from "img/login4.svg";
import LoginImg5 from "img/login5.svg";

const loginArt = [LoginImg1, LoginImg2, LoginImg3, LoginImg4, LoginImg5];
const loginArtAlts = [
"girl on tablet",
"boy using VR headset",
"girl controlling drone",
"boy developing an app",
"girl coding for robot",
];

const gradientColors = {
0: ["#FFB5B5", "#FFF7F3"],
1: ["#54C9FE", "#D8F6FF"],
2: ["#ACF53F", "#DAFFA4"],
3: ["#FFF065", "#FFF7F3"],
4: ["#FF94DB", "#FFE4EE"],
};

const themeColors = {
0: ["#FF5F54", "white"],
1: ["#36C5FC", "white"],
2: ["#ACF53F", "white"],
3: ["#FFF065", "black"],
4: ["#FF94DB", "white"],
};

class Login extends React.Component {
render() {
state = {
dummy: false,
index: Math.floor(Math.random() * 5),
};
// basically, when the window resizes, we should recalculate get SVG - the window parameters change!
componentDidMount = () => {
window.addEventListener("resize", () => this.setState({ dummy: !this.state.dummy }));
};
componentWillUnmount = () => {
window.removeEventListener("resize", () => this.setState({ dummy: !this.state.dummy }));
};
getSVG = () => {
return (
<div className="login-page">
<div className="login-page-content" style={{ backgroundImage: `url(${LoginGuy})` }}>
<LoginForm provider={this.props.provider} />
<svg
className="background-svg"
viewBox={`0 0 1084 ${window.innerHeight}`}
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d={`
M204.407 691.847
C51.4294 796.853 0.666362 951.817 0 ${window.innerHeight}
H1094
V-14
L53.4756 -6.443
C178.418 14.2132 602.225 418.778 204.407 691.847Z
`}
fill="url(#paint0_linear)"
/>
<defs>
<linearGradient
id="paint0_linear"
x1="547"
y1="0"
x2="547"
y2={`${window.innerHeight}`}
gradientUnits="userSpaceOnUse"
>
<stop stopColor={gradientColors[this.state.index][0]} />
<stop offset="1" stopColor={gradientColors[this.state.index][1]} stopOpacity="0.47" />
</linearGradient>
</defs>
</svg>
);
};

render = () => {
const textHighlightStyle = {
background: `linear-gradient(180deg, rgba(255,255,255,0) 80%, ${
gradientColors[this.state.index][0]
} 50%)`,
};
return (
<div className="login-page-content">
<div className="login-page-content-container">
<div
className="bottom-right-toggle"
onClick={() => this.setState({ index: Math.floor(Math.random() * 5) })}
>
<FontAwesomeIcon icon={faRedo} />
</div>
<div className="login-page-content-main">
<div>
<h1 className="font-weight-bold">
The ACM <span className="teachla-green">Teach LA</span>{" "}
<span style={textHighlightStyle}>Online Editor</span>
</h1>
<p>a web IDE that lets you write and run Python &amp; Processing code, anywhere.</p>
{this.props.create ? (
<CreateUserForm
initialState={this.props.initialState}
themeColor={themeColors[this.state.index][0]}
textColor={themeColors[this.state.index][2]}
/>
) : (
<LoginForm
themeColor={themeColors[this.state.index][0]}
textColor={themeColors[this.state.index][1]}
/>
)}
</div>
</div>
<div className="login-page-content-footer">
<FontAwesomeIcon icon={faPaintBrush} /> <FontAwesomeIcon icon={faCode} />{" "}
<FontAwesomeIcon icon={faRocket} /> by{" "}
<a href="https://teachla.uclaacm.com" target="_blank" rel="noopener noreferrer">
<span className="teachla-green">ACM Teach LA</span>
</a>{" "}
with <FontAwesomeIcon className="beating-heart" icon={faHeart} />
</div>
</div>
<div className="login-page-images">
<img
className="login-page-art"
src={loginArt[this.state.index]}
alt={`decorative login page art: ${loginArtAlts[this.state.index]}`}
/>
{this.getSVG()}
</div>
<Footer />
</div>
);
}
};
}

export default Login;
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Link } from "react-router-dom";
import * as firebase from "firebase/app";
import "firebase/auth";
import SHA256 from "crypto-js/sha256";
import LoginInput from "../Login/LoginInput.js";
import LoginInput from "./LoginInput.js";
import {
MINIMUM_USERNAME_LENGTH,
MINIMUM_PASSWORD_LENGTH,
Expand Down Expand Up @@ -100,7 +100,7 @@ export default class CreateUserForm extends React.Component {
* @return {void} submit returns early if the inputs passed by a prospective user
* are bad.
*/
submit = e => {
submit = (e) => {
e.preventDefault();

this.setState({
Expand Down Expand Up @@ -129,7 +129,7 @@ export default class CreateUserForm extends React.Component {
.auth()
.createUserWithEmailAndPassword(email, passHash)
.then(({ user }) => {})
.catch(err => {
.catch((err) => {
console.error(err);
let newMsg = err.message;
switch (err.code) {
Expand Down Expand Up @@ -185,9 +185,9 @@ export default class CreateUserForm extends React.Component {
return addBreak ? <br /> : null;
};

updateUsername = username => this.setState({ username });
updatePassword = password => this.setState({ password });
updateConfirmPassword = confirmPassword => this.setState({ confirmPassword });
updateUsername = (username) => this.setState({ username });
updatePassword = (password) => this.setState({ password });
updateConfirmPassword = (confirmPassword) => this.setState({ confirmPassword });

renderInputs = () => (
<div className="login-form-input-list">
Expand Down Expand Up @@ -221,37 +221,50 @@ export default class CreateUserForm extends React.Component {
if (this.state.waiting) {
return (
<div className="login-form-loader">
<RingLoader color={"#857e8f"} size={50} loading={true} />
<RingLoader color={this.props.themeColor} size={80} loading={true} />
</div>
);
} else {
const unclickedStyle = {
backgroundColor: "white",
borderColor: this.props.themeColor,
borderWidth: "medium",
borderRadius: "4px",
color: "black",
};

const clickedStyle = {
backgroundColor: this.props.themeColor,
borderColor: this.props.themeColor,
borderWidth: "medium",
borderRadius: "4px",
color: this.props.textColor,
};
return (
<Button className="login-form-button" size="lg" type="submit">
Create Account
</Button>
<div>
<Button
size="lg"
type="submit"
style={this.state.hoverButton ? clickedStyle : unclickedStyle}
onMouseEnter={() => this.setState({ hoverButton: !this.state.hoverButton })}
onMouseLeave={() => this.setState({ hoverButton: !this.state.hoverButton })}
>
Create Account
</Button>
<Link to="/login" className="login-form-link ml-4">
or, login with an existing account
</Link>
</div>
);
}
};

renderLink = () => (
<Link to="/login" className="login-form-link">
Already have an account? Click here to login.
</Link>
);

render() {
return (
<div className="login-form-container">
<form className="login-form" onSubmit={this.submit}>
<h1>Create a new account</h1>
<br />
{this.renderInputs()}
{this.renderAction()}
<br />
<br />
{this.renderLink()}
</form>
</div>
<form className="login-form" onSubmit={this.submit}>
{this.renderInputs()}
{this.renderAction()}
</form>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,7 @@ describe("CreateUserForm", () => {
expect(component.state().usernameMessage).toBe(
`Username must only use upper case and lower case letters, numbers, and/or the special characters !@#$%`,
);
expect(
component
.find(".login-form-input-error")
.at(0)
.text(),
).toBe(
expect(component.find(".login-form-input-error").at(0).text()).toBe(
`Username must only use upper case and lower case letters, numbers, and/or the special characters !@#$%`,
);

Expand All @@ -60,12 +55,7 @@ describe("CreateUserForm", () => {
expect(component.state().passwordMessage).toBe(
`Password must only use upper case and lower case letters, numbers, and/or the special characters !@#$%`,
);
expect(
component
.find(".login-form-input-error")
.at(0)
.text(),
).toBe(
expect(component.find(".login-form-input-error").at(0).text()).toBe(
`Password must only use upper case and lower case letters, numbers, and/or the special characters !@#$%`,
);

Expand Down
Loading

0 comments on commit dfbb280

Please sign in to comment.