First design of second factor page.

This commit is contained in:
Clement Michaud 2018-11-11 22:27:43 -08:00
parent f5c653551a
commit 337f0df12a
10 changed files with 295 additions and 138 deletions

View File

@ -2,8 +2,8 @@ import React, { Component } from 'react';
import './App.css';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import { FirstFactor } from './first-factor';
import { SecondFactor } from './second-factor';
import { FirstFactor } from './pages/first-factor/first-factor';
import { SecondFactor } from './pages/second-factor/second-factor';
class App extends Component {
render() {

View File

@ -1,91 +0,0 @@
import React, { Component } from "react";
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Checkbox from '@material-ui/core/Checkbox';
import logo from '../logo.svg';
import styles from "./index.module.css"
interface State {
rememberMe: boolean;
}
export class FirstFactor extends Component<any, State> {
constructor(props: any) {
super(props)
this.state = {
rememberMe: false
}
}
toggleRememberMe = () => {
this.setState({
rememberMe: !(this.state.rememberMe)
})
}
render() {
return (
<div className={styles.mainContent}>
<div className={styles.header}>
<h1>Sign in</h1>
</div>
<div className={styles.frame}>
<div className={styles.innerFrame}>
<div className={styles.fields}>
<div className={styles.field}>
<TextField
className={styles.input}
id="username"
label="Username">
</TextField>
</div>
<div className={styles.field}>
<TextField
className={styles.input}
id="password"
label="Password"
type="password">
</TextField>
</div>
</div>
<div className={styles.controlArea}>
<div className={styles.controls}>
<div className={styles.rememberMe}>
<FormControlLabel
control={
<Checkbox
checked={this.state.rememberMe}
onChange={this.toggleRememberMe}
color="primary"
/>
}
label="Remember me"
/>
</div>
<div className={styles.resetPassword}>
<a href="/">Forgot password?</a>
</div>
</div>
<div className={styles.buttons}>
<Button
variant="contained"
color="primary"
className={styles.button}>
Login
</Button>
</div>
</div>
</div>
</div>
<div className={styles.footer}>
<img src={logo} alt="logo"></img>
<div>Powered by <a href="#">Authelia</a></div>
</div>
</div>
)
}
}

View File

@ -0,0 +1,39 @@
.main {
padding: 2em 3em 2em 3em;
}
.field {
width: 100%;
margin-bottom: 20px;
}
.field .input {
width: 100%;
}
.controls {
display: inline-block;
width: 100%;
font-size: 0.875rem;
}
.controls .rememberMe {
float: left;
}
.controls .resetPassword {
padding: 12px 0px;
float: right;
}
.controls .resetPassword a {
color: black;
}
.buttons {
margin-top: 20px;
}
.buttons button {
width: 100%;
}

View File

@ -0,0 +1,83 @@
import React, { Component } from "react";
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Checkbox from '@material-ui/core/Checkbox';
import FormTemplate from '../../templates/form-template';
import styles from "./first-factor.module.css"
interface State {
rememberMe: boolean;
}
export class FirstFactor extends Component<any, State> {
constructor(props: any) {
super(props)
this.state = {
rememberMe: false
}
}
toggleRememberMe = () => {
this.setState({
rememberMe: !(this.state.rememberMe)
})
}
render() {
return (
<FormTemplate title="Sign in">
<div className={styles.main}>
<div className={styles.fields}>
<div className={styles.field}>
<TextField
className={styles.input}
id="username"
label="Username">
</TextField>
</div>
<div className={styles.field}>
<TextField
className={styles.input}
id="password"
label="Password"
type="password">
</TextField>
</div>
</div>
<div className={styles.controlArea}>
<div className={styles.controls}>
<div className={styles.rememberMe}>
<FormControlLabel
control={
<Checkbox
checked={this.state.rememberMe}
onChange={this.toggleRememberMe}
color="primary"
/>
}
label="Remember me"
/>
</div>
<div className={styles.resetPassword}>
<a href="/">Forgot password?</a>
</div>
</div>
<div className={styles.buttons}>
<Button
variant="contained"
color="primary"
className={styles.button}>
Login
</Button>
</div>
</div>
</div>
</FormTemplate>
)
}
}

View File

@ -0,0 +1,37 @@
.main {
text-align: center;
padding: 2em 3em 2em 3em;
min-height: 350px;
}
.authenticate {
margin: 1em;
}
.authenticate hr {
width: 100%;
}
.authenticate .u2f img {
width: 128px;
margin-top: 1em;
}
.authenticate .totpField {
margin: 1em 0em;
}
.register {
margin: 1em;
}
.register .buttons {
margin: 2em 0em;
}
.register .buttons button {
margin: 0.8em 0em;
width: 100%;
}

View File

@ -0,0 +1,103 @@
import React, { Component } from "react";
import TextField from '@material-ui/core/TextField';
import BottomNavigation from '@material-ui/core/BottomNavigation';
import BottomNavigationAction from '@material-ui/core/BottomNavigationAction';
import RestoreIcon from '@material-ui/core/Icon';
import FavoriteIcon from '@material-ui/core/Icon';
import Button from '@material-ui/core/Button';
import FormTemplate from '../../templates/form-template';
import styles from './second-factor.module.css';
import pendrive from '../../pendrive.png'
interface State {
mode: number;
}
export class SecondFactor extends Component<any, State> {
constructor(props: any) {
super(props);
this.state = {
mode: 0
}
}
onMenuChanged(event: any, value: number) {
this.setState({mode: value});
}
renderInner() {
const registerDevice = (
<div className={styles.register}>
<div>Register a new device</div>
<div className={styles.buttons}>
<Button variant="contained" color="primary">
Security key
</Button>
<Button variant="contained" color="primary">
One-time password
</Button>
</div>
</div>
)
const authenticate = (
<div className={styles.authenticate}>
<div className={styles.u2f}>
Touch your security key
<div>
<img src={pendrive} alt="usb key"/>
</div>
</div>
<table style={{width: '60%', margin: '2em auto'}}>
<tbody>
<tr>
<td style={{width: '40%'}}><hr/></td>
<td style={{width: '20%'}}>or</td>
<td style={{width: '40%'}}><hr/></td>
</tr>
</tbody>
</table>
<div className={styles.totp}>
Provide a one-time password
<div className={styles.totpField}>
<TextField
id="otp"
variant="outlined"
label="Password">
</TextField>
</div>
</div>
</div>
)
if (this.state.mode == 0) {
return authenticate;
}
else if (this.state.mode == 1) {
return registerDevice;
}
}
render() {
return (
<FormTemplate title="2-Factor">
<div className={styles.main}>
{this.renderInner()}
</div>
<BottomNavigation
value={this.state.mode}
onChange={this.onMenuChanged.bind(this)}
showLabels
className={styles.menu}
>
<BottomNavigationAction label="Authenticate" icon={<RestoreIcon />} />
<BottomNavigationAction label="Register" icon={<FavoriteIcon />} />
</BottomNavigation>
</FormTemplate>
)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -1,7 +0,0 @@
import React, { Component } from "react";
export class SecondFactor extends Component {
render() {
return <div>second factor</div>
}
}

View File

@ -12,55 +12,18 @@
text-align: center;
}
/* MAIN */
/* FRAME */
.frame {
box-shadow: rgba(0,0,0,0.14902) 0px 1px 1px 0px,rgba(0,0,0,0.09804) 0px 1px 2px 0px;
background-color: white;
border-radius: 5px;
padding: 0.5em 3em 3em 3em;
}
.innerFrame {
width: 100%;
}
.field {
width: 100%;
margin: 20px 0px;
}
.field .input {
width: 100%;
}
.controls {
display: inline-block;
width: 100%;
font-size: 0.875rem;
}
.controls .rememberMe {
float: left;
}
.controls .resetPassword {
padding: 12px 0px;
float: right;
}
.controls .resetPassword a {
color: black;
}
.buttons {
margin-top: 20px;
}
.buttons button {
width: 100%;
}
/* FOOTER */
.footer {

View File

@ -0,0 +1,30 @@
import React, { Component } from "react";
import logo from '../logo.svg';
import styles from "./form-template.module.css"
interface Props {
title: string;
}
export default class FormTemplate extends Component<Props> {
render() {
const children = this.props.children;
return (
<div className={styles.mainContent}>
<div className={styles.header}>
<h1>{this.props.title}</h1>
</div>
<div className={styles.frame}>
<div className={styles.innerFrame}>
{children}
</div>
</div>
<div className={styles.footer}>
<img src={logo} alt="logo"></img>
<div>Powered by <a href="#">Authelia</a></div>
</div>
</div>
)
}
}