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} <a href={href} title={title}
className={"btn social-link-button p-0 d-inline-flex align-items-stretch " + backgroundClass}> className={"btn social-link-button p-0 d-inline-flex align-items-stretch " + backgroundClass}>
<span className="icon-part d-flex align-items-center"> <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>
<span className="text-part d-flex align-items-center"> <span className="text-part d-flex align-items-center mx-auto">
{children} {children}
</span> </span>
</a> </a>

View file

@ -1,6 +1,6 @@
import {Trans, useTranslation} from "react-i18next"; import {Trans, useTranslation} from "react-i18next";
import {Alert, Button, Form} from "react-bootstrap"; import {Alert, Button, Card, Form} from "react-bootstrap";
import React, {Fragment, useState} from "react"; import React, {useState} from "react";
import {postEmailLogin} from "../../../../../api/user"; import {postEmailLogin} from "../../../../../api/user";
import {getAndSetUser} from "../../../../../utils/apiUtils"; import {getAndSetUser} from "../../../../../utils/apiUtils";
@ -27,10 +27,12 @@ export const ViaEMail: React.FC = () => {
}; };
return ( return (
<Fragment> <Card className="bg-dark mb-4">
<h5 className="center"> <Card.Body>
<Card.Title>
<Trans i18nKey="signInVia" values={{service: "E-Mail"}}/> <Trans i18nKey="signInVia" values={{service: "E-Mail"}}/>
</h5> </Card.Title>
<Form onSubmit={onFormSubmit}> <Form onSubmit={onFormSubmit}>
<Form.Group controlId="email"> <Form.Group controlId="email">
<Form.Control <Form.Control
@ -39,6 +41,7 @@ export const ViaEMail: React.FC = () => {
size="sm" size="sm"
placeholder={t("email")} placeholder={t("email")}
onChange={(event) => setEmail(event.currentTarget.value)} onChange={(event) => setEmail(event.currentTarget.value)}
className="bg-dark text-white"
/> />
</Form.Group> </Form.Group>
@ -49,6 +52,7 @@ export const ViaEMail: React.FC = () => {
size="sm" size="sm"
placeholder={t("password")} placeholder={t("password")}
onChange={(event) => setPassword(event.currentTarget.value)} onChange={(event) => setPassword(event.currentTarget.value)}
className="bg-dark text-white"
/> />
</Form.Group> </Form.Group>
@ -58,11 +62,11 @@ export const ViaEMail: React.FC = () => {
<Button <Button
type="submit" type="submit"
size="sm"
variant="primary"> variant="primary">
<Trans i18nKey="signIn"/> <Trans i18nKey="signIn"/>
</Button> </Button>
</Form> </Form>
</Fragment> </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 {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 {postLdapLogin} from "../../../../../api/user";
import {getAndSetUser} from "../../../../../utils/apiUtils"; import {getAndSetUser} from "../../../../../utils/apiUtils";
import {useSelector} from "react-redux"; import {useSelector} from "react-redux";
@ -33,10 +33,12 @@ const ViaLdap: React.FC = () => {
} }
return ( return (
<Fragment> <Card className="bg-dark mb-4">
<h5 className="center"> <Card.Body>
<Card.Title>
<Trans i18nKey="signInVia" values={{service: name}}/> <Trans i18nKey="signInVia" values={{service: name}}/>
</h5> </Card.Title>
<Form onSubmit={onFormSubmit}> <Form onSubmit={onFormSubmit}>
<Form.Group controlId="username"> <Form.Group controlId="username">
<Form.Control <Form.Control
@ -45,6 +47,7 @@ const ViaLdap: React.FC = () => {
size="sm" size="sm"
placeholder={t("username")} placeholder={t("username")}
onChange={(event) => setUsername(event.currentTarget.value)} onChange={(event) => setUsername(event.currentTarget.value)}
className="bg-dark text-white"
/> />
</Form.Group> </Form.Group>
@ -55,6 +58,7 @@ const ViaLdap: React.FC = () => {
size="sm" size="sm"
placeholder={t("password")} placeholder={t("password")}
onChange={(event) => setPassword(event.currentTarget.value)} onChange={(event) => setPassword(event.currentTarget.value)}
className="bg-dark text-white"
/> />
</Form.Group> </Form.Group>
@ -64,12 +68,12 @@ const ViaLdap: React.FC = () => {
<Button <Button
type="submit" type="submit"
size="sm"
variant="primary"> variant="primary">
<Trans i18nKey="signIn"/> <Trans i18nKey="signIn"/>
</Button> </Button>
</Form> </Form>
</Fragment> </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 React from "react"
import {Col, Jumbotron, Row} from "react-bootstrap" import {Card, Col, Row} from "react-bootstrap"
import {Trans, useTranslation} from "react-i18next"; import {Trans, useTranslation} from "react-i18next";
import {ViaEMail} from "./auth/via-email"; import {ViaEMail} from "./auth/via-email";
import {OneClickType, ViaOneClick} from "./auth/via-one-click"; import {OneClickType, ViaOneClick} from "./auth/via-one-click";
import {ViaLdap} from "./auth/via-ldap"; import {ViaLdap} from "./auth/via-ldap";
import {useSelector} from "react-redux"; import {useSelector} from "react-redux";
import {ApplicationState} from "../../../../redux"; import {ApplicationState} from "../../../../redux";
import {ViaOpenId} from "./auth/via-open id"; import {ViaOpenId} from "./auth/via-openid";
import "./login.scss";
import {ElementSeparator} from "../../../element-separator/element-separator";
import {Redirect} from "react-router"; import {Redirect} from "react-router";
import {LoginStatus} from "../../../../redux/user/types"; import {LoginStatus} from "../../../../redux/user/types";
@ -40,26 +38,23 @@ const Login: React.FC = () => {
} }
return ( return (
<Jumbotron className="bg-dark">
<div className="my-3"> <div className="my-3">
<Row className="h-100 flex justify-content-center"> <Row className="h-100 flex justify-content-center">
{ {
authProviders.email || authProviders.ldap || authProviders.openid ? authProviders.email || authProviders.ldap || authProviders.openid ?
<Col xs={12} sm={10} lg={3}> <Col xs={12} sm={10} lg={4}>
<ElementSeparator separator={<hr className="w-100 bg-white"/>}>
{emailForm} {emailForm}
{ldapForm} {ldapForm}
{openIdForm} {openIdForm}
</ElementSeparator>
<hr className="w-100 d-lg-none d-block bg-white"/>
</Col> </Col>
: null : null
} }
<Col xs={12} sm={10} lg={5}> <Col xs={12} sm={10} lg={4}>
<h5> <Card className="bg-dark mb-4">
<Card.Body>
<Card.Title>
<Trans i18nKey="signInVia" values={{service: ""}}/> <Trans i18nKey="signInVia" values={{service: ""}}/>
</h5> </Card.Title>
<div className={"d-flex flex-wrap one-click-login justify-content-center"}>
{ {
Object.values(OneClickType) Object.values(OneClickType)
.filter((value) => authProviders[value]) .filter((value) => authProviders[value])
@ -77,11 +72,11 @@ const Login: React.FC = () => {
) )
}) })
} }
</div> </Card.Body>
</Card>
</Col> </Col>
</Row> </Row>
</div> </div>
</Jumbotron>
) )
} }