diff options
-rw-r--r-- | Timeline/ClientApp/.editorconfig | 1 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/views/common/LoadingButton.tsx | 28 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/views/login/index.tsx | 24 |
3 files changed, 42 insertions, 11 deletions
diff --git a/Timeline/ClientApp/.editorconfig b/Timeline/ClientApp/.editorconfig index 54d8316a..779719e0 100644 --- a/Timeline/ClientApp/.editorconfig +++ b/Timeline/ClientApp/.editorconfig @@ -1,4 +1,5 @@ root = true
+end_of_line = lf
[*.ts]
tab_width = 2
diff --git a/Timeline/ClientApp/src/app/views/common/LoadingButton.tsx b/Timeline/ClientApp/src/app/views/common/LoadingButton.tsx new file mode 100644 index 00000000..fa721afe --- /dev/null +++ b/Timeline/ClientApp/src/app/views/common/LoadingButton.tsx @@ -0,0 +1,28 @@ +import React from "react"; +import { Button, ButtonProps, Spinner } from "react-bootstrap"; + +const LoadingButton: React.FC<{ loading?: boolean } & ButtonProps> = ({ + loading, + variant, + ...otherProps +}) => { + return ( + <Button + variant={variant != null ? `outline-${variant}` : "outline-primary"} + disabled={loading} + {...otherProps} + > + {otherProps.children} + {loading ? ( + <Spinner + className="ml-1" + variant={variant} + animation="grow" + size="sm" + /> + ) : null} + </Button> + ); +}; + +export default LoadingButton; diff --git a/Timeline/ClientApp/src/app/views/login/index.tsx b/Timeline/ClientApp/src/app/views/login/index.tsx index 5d1e8f06..545fc05a 100644 --- a/Timeline/ClientApp/src/app/views/login/index.tsx +++ b/Timeline/ClientApp/src/app/views/login/index.tsx @@ -6,6 +6,7 @@ import { Form, Spinner, Button } from "react-bootstrap"; import { useUser, userService } from "@/services/user"; import AppBar from "../common/AppBar"; +import LoadingButton from "../common/LoadingButton"; const LoginPage: React.FC = (_) => { const { t } = useTranslation(); @@ -89,7 +90,7 @@ const LoginPage: React.FC = (_) => { isInvalid={usernameDirty && username === ""} /> {usernameDirty && username === "" && ( - <Form.Control.Feedback> + <Form.Control.Feedback type="invalid"> {t("login.emptyUsername")} </Form.Control.Feedback> )} @@ -108,7 +109,7 @@ const LoginPage: React.FC = (_) => { isInvalid={passwordDirty && password === ""} /> {passwordDirty && password === "" && ( - <Form.Control.Feedback> + <Form.Control.Feedback type="invalid"> {t("login.emptyPassword")} </Form.Control.Feedback> )} @@ -124,15 +125,16 @@ const LoginPage: React.FC = (_) => { label={t("user.rememberMe")} /> </Form.Group> - {error ? <p className="text-error">{t(error)}</p> : null} - <div> - {process ? ( - <Spinner animation="border" /> - ) : ( - <Button variant="primary" onClick={onSubmit}> - {t("user.login")} - </Button> - )} + {error ? <p className="text-danger">{t(error)}</p> : null} + <div className="text-right"> + <LoadingButton + loading={process} + variant="primary" + onClick={onSubmit} + disabled={username === "" || password === "" ? true : undefined} + > + {t("user.login")} + </LoadingButton> </div> </Form> </div> |