Card-ify login components (#53)

* Card-ify login components

* Fix lint warnings

* Replace HTML with react-bootstrap components

* Remove now obsolete flex div

* Apply fixed width to fa-icons

* Reset sign-in buttons to normal size
This commit is contained in:
Henrik Hüttemann 2020-05-25 20:48:27 +02:00 committed by GitHub
parent 8636391a73
commit 7a33177014
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 167 additions and 165 deletions

View file

@ -15,9 +15,9 @@ export const SocialLinkButton: React.FC<SocialButtonProps> = ({title, background
<a href={href} title={title}
className={"btn social-link-button p-0 d-inline-flex align-items-stretch " + backgroundClass}>
<span className="icon-part d-flex align-items-center">
<FontAwesomeIcon icon={icon} className={"social-icon"}/>
<FontAwesomeIcon icon={icon} className={"social-icon"} fixedWidth={true}/>
</span>
<span className="text-part d-flex align-items-center">
<span className="text-part d-flex align-items-center mx-auto">
{children}
</span>
</a>

View file

@ -1,6 +1,6 @@
import {Trans, useTranslation} from "react-i18next";
import {Alert, Button, Form} from "react-bootstrap";
import React, {Fragment, useState} from "react";
import {Alert, Button, Card, Form} from "react-bootstrap";
import React, {useState} from "react";
import {postEmailLogin} from "../../../../../api/user";
import {getAndSetUser} from "../../../../../utils/apiUtils";
@ -27,42 +27,46 @@ export const ViaEMail: React.FC = () => {
};
return (
<Fragment>
<h5 className="center">
<Trans i18nKey="signInVia" values={{service: "E-Mail"}}/>
</h5>
<Form onSubmit={onFormSubmit}>
<Form.Group controlId="email">
<Form.Control
isInvalid={error}
type="email"
size="sm"
placeholder={t("email")}
onChange={(event) => setEmail(event.currentTarget.value)}
/>
</Form.Group>
<Card className="bg-dark mb-4">
<Card.Body>
<Card.Title>
<Trans i18nKey="signInVia" values={{service: "E-Mail"}}/>
</Card.Title>
<Form.Group controlId="password">
<Form.Control
isInvalid={error}
type="password"
size="sm"
placeholder={t("password")}
onChange={(event) => setPassword(event.currentTarget.value)}
/>
</Form.Group>
<Form onSubmit={onFormSubmit}>
<Form.Group controlId="email">
<Form.Control
isInvalid={error}
type="email"
size="sm"
placeholder={t("email")}
onChange={(event) => setEmail(event.currentTarget.value)}
className="bg-dark text-white"
/>
</Form.Group>
<Alert className="small" show={error} variant="danger">
<Trans i18nKey="errorEmailLogin"/>
</Alert>
<Form.Group controlId="password">
<Form.Control
isInvalid={error}
type="password"
size="sm"
placeholder={t("password")}
onChange={(event) => setPassword(event.currentTarget.value)}
className="bg-dark text-white"
/>
</Form.Group>
<Button
type="submit"
size="sm"
variant="primary">
<Trans i18nKey="signIn"/>
</Button>
</Form>
</Fragment>
<Alert className="small" show={error} variant="danger">
<Trans i18nKey="errorEmailLogin"/>
</Alert>
<Button
type="submit"
variant="primary">
<Trans i18nKey="signIn"/>
</Button>
</Form>
</Card.Body>
</Card>
);
}

View file

@ -1,6 +1,6 @@
import React, {Fragment, useState} from "react";
import React, {useState} from "react";
import {Trans, useTranslation} from "react-i18next";
import {Alert, Button, Form} from "react-bootstrap";
import {Alert, Button, Card, Form} from "react-bootstrap";
import {postLdapLogin} from "../../../../../api/user";
import {getAndSetUser} from "../../../../../utils/apiUtils";
import {useSelector} from "react-redux";
@ -33,43 +33,47 @@ const ViaLdap: React.FC = () => {
}
return (
<Fragment>
<h5 className="center">
<Trans i18nKey="signInVia" values={{service: name}}/>
</h5>
<Form onSubmit={onFormSubmit}>
<Form.Group controlId="username">
<Form.Control
isInvalid={error}
type="text"
size="sm"
placeholder={t("username")}
onChange={(event) => setUsername(event.currentTarget.value)}
/>
</Form.Group>
<Card className="bg-dark mb-4">
<Card.Body>
<Card.Title>
<Trans i18nKey="signInVia" values={{service: name}}/>
</Card.Title>
<Form.Group controlId="password">
<Form.Control
isInvalid={error}
type="password"
size="sm"
placeholder={t("password")}
onChange={(event) => setPassword(event.currentTarget.value)}
/>
</Form.Group>
<Form onSubmit={onFormSubmit}>
<Form.Group controlId="username">
<Form.Control
isInvalid={error}
type="text"
size="sm"
placeholder={t("username")}
onChange={(event) => setUsername(event.currentTarget.value)}
className="bg-dark text-white"
/>
</Form.Group>
<Alert className="small" show={error} variant="danger">
<Trans i18nKey="errorLdapLogin"/>
</Alert>
<Form.Group controlId="password">
<Form.Control
isInvalid={error}
type="password"
size="sm"
placeholder={t("password")}
onChange={(event) => setPassword(event.currentTarget.value)}
className="bg-dark text-white"
/>
</Form.Group>
<Button
type="submit"
size="sm"
variant="primary">
<Trans i18nKey="signIn"/>
</Button>
</Form>
</Fragment>
<Alert className="small" show={error} variant="danger">
<Trans i18nKey="errorLdapLogin"/>
</Alert>
<Button
type="submit"
variant="primary">
<Trans i18nKey="signIn"/>
</Button>
</Form>
</Card.Body>
</Card>
);
};

View file

@ -1,59 +0,0 @@
import React, {Fragment, useState} from "react";
import {Trans, useTranslation} from "react-i18next";
import {Alert, Button, Form} from "react-bootstrap";
import {postOpenIdLogin} from "../../../../../api/user";
import {getAndSetUser} from "../../../../../utils/apiUtils";
const ViaOpenId: React.FC = () => {
useTranslation();
const [openId, setOpenId] = useState("");
const [error, setError] = useState(false);
const doAsyncLogin = () => {
(async () => {
try {
await postOpenIdLogin(openId);
await getAndSetUser();
} catch {
setError(true);
}
})();
}
const onFormSubmit = (event: any) => {
doAsyncLogin();
event.preventDefault();
}
return (
<Fragment>
<h5 className="center">
<Trans i18nKey="signInVia" values={{service: "OpenID"}}/>
</h5>
<Form onSubmit={onFormSubmit}>
<Form.Group controlId="openid">
<Form.Control
isInvalid={error}
type="text"
size="sm"
placeholder={"OpenID"}
onChange={(event) => setOpenId(event.currentTarget.value)}
/>
</Form.Group>
<Alert className="small" show={error} variant="danger">
<Trans i18nKey="errorOpenIdLogin"/>
</Alert>
<Button
type="submit"
size="sm"
variant="primary">
<Trans i18nKey="signIn"/>
</Button>
</Form>
</Fragment>
);
};
export { ViaOpenId }

View file

@ -0,0 +1,61 @@
import React, {useState} from "react";
import {Trans, useTranslation} from "react-i18next";
import {Alert, Button, Card, Form} from "react-bootstrap";
import {postOpenIdLogin} from "../../../../../api/user";
import {getAndSetUser} from "../../../../../utils/apiUtils";
const ViaOpenId: React.FC = () => {
useTranslation();
const [openId, setOpenId] = useState("");
const [error, setError] = useState(false);
const doAsyncLogin = () => {
(async () => {
try {
await postOpenIdLogin(openId);
await getAndSetUser();
} catch {
setError(true);
}
})();
}
const onFormSubmit = (event: any) => {
doAsyncLogin();
event.preventDefault();
}
return (
<Card className="bg-dark mb-4">
<Card.Body>
<Card.Title>
<Trans i18nKey="signInVia" values={{service: "OpenID"}}/>
</Card.Title>
<Form onSubmit={onFormSubmit}>
<Form.Group controlId="openid">
<Form.Control
isInvalid={error}
type="text"
size="sm"
placeholder={"OpenID"}
onChange={(event) => setOpenId(event.currentTarget.value)}
className="bg-dark text-white"
/>
</Form.Group>
<Alert className="small" show={error} variant="danger">
<Trans i18nKey="errorOpenIdLogin"/>
</Alert>
<Button
type="submit"
variant="primary">
<Trans i18nKey="signIn"/>
</Button>
</Form>
</Card.Body>
</Card>
);
};
export { ViaOpenId }

View file

@ -1,3 +0,0 @@
.social-button-container {
min-width: 30%;
}

View file

@ -1,14 +1,12 @@
import React from "react"
import {Col, Jumbotron, Row} from "react-bootstrap"
import {Card, Col, Row} from "react-bootstrap"
import {Trans, useTranslation} from "react-i18next";
import {ViaEMail} from "./auth/via-email";
import {OneClickType, ViaOneClick} from "./auth/via-one-click";
import {ViaLdap} from "./auth/via-ldap";
import {useSelector} from "react-redux";
import {ApplicationState} from "../../../../redux";
import {ViaOpenId} from "./auth/via-open id";
import "./login.scss";
import {ElementSeparator} from "../../../element-separator/element-separator";
import {ViaOpenId} from "./auth/via-openid";
import {Redirect} from "react-router";
import {LoginStatus} from "../../../../redux/user/types";
@ -40,26 +38,23 @@ const Login: React.FC = () => {
}
return (
<Jumbotron className="bg-dark">
<div className="my-3">
<Row className="h-100 flex justify-content-center">
{
authProviders.email || authProviders.ldap || authProviders.openid ?
<Col xs={12} sm={10} lg={3}>
<ElementSeparator separator={<hr className="w-100 bg-white"/>}>
{emailForm}
{ldapForm}
{openIdForm}
</ElementSeparator>
<hr className="w-100 d-lg-none d-block bg-white"/>
</Col>
: null
}
<Col xs={12} sm={10} lg={5}>
<h5>
<Trans i18nKey="signInVia" values={{service: ""}}/>
</h5>
<div className={"d-flex flex-wrap one-click-login justify-content-center"}>
<div className="my-3">
<Row className="h-100 flex justify-content-center">
{
authProviders.email || authProviders.ldap || authProviders.openid ?
<Col xs={12} sm={10} lg={4}>
{emailForm}
{ldapForm}
{openIdForm}
</Col>
: null
}
<Col xs={12} sm={10} lg={4}>
<Card className="bg-dark mb-4">
<Card.Body>
<Card.Title>
<Trans i18nKey="signInVia" values={{service: ""}}/>
</Card.Title>
{
Object.values(OneClickType)
.filter((value) => authProviders[value])
@ -77,11 +72,11 @@ const Login: React.FC = () => {
)
})
}
</div>
</Col>
</Row>
</div>
</Jumbotron>
</Card.Body>
</Card>
</Col>
</Row>
</div>
)
}