diff --git a/src/config-schema.ts b/src/config-schema.ts index 818fc68..9d59e74 100644 --- a/src/config-schema.ts +++ b/src/config-schema.ts @@ -1,3 +1,4 @@ +import _default from "@carbon/react/lib/components/Button/Button"; import { validators, Type } from "@openmrs/esm-framework"; export const configSchema = { @@ -49,4 +50,32 @@ export const configSchema = { _description: "Alt text, shown on hover", }, }, + loginBackgroundImage: { + src: { + _type: Type.String, + _default: "/openmrs/spa/background.png", + _description: + "A path or URL to an image. If null, will use the OpenMRS SVG sprite.", + _validators: [validators.isUrl], + }, + alt: { + _type: Type.String, + _default: "Background", + _description: "Alt text, shown on hover", + }, + }, + loginLogoImage: { + src: { + _type: Type.String, + _default: "/openmrs/spa/updf-logo.jpg", + _description: + "A path or URL to an image. If null, will use the OpenMRS SVG sprite.", + _validators: [validators.isUrl], + }, + alt: { + _type: Type.String, + _default: "OpenMRS Logo", + _description: "Alt text, shown on hover", + }, + }, }; diff --git a/src/index.ts b/src/index.ts index 94b82de..872c061 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import { getAsyncLifecycle, defineConfigSchema } from "@openmrs/esm-framework"; -import { configSchema } from "./config-schema"; +import { configSchema } from "./config-schema"; const moduleName = "@ugandaemr/esm-login-app"; diff --git a/src/login/background.wrapper.component.tsx b/src/login/background.wrapper.component.tsx new file mode 100644 index 0000000..824e072 --- /dev/null +++ b/src/login/background.wrapper.component.tsx @@ -0,0 +1,32 @@ +import React from "react"; +import styles from "./login.scss"; +import { useConfig } from "@openmrs/esm-framework"; +const BackgroundWrapper = ({ children }) => { + const config = useConfig(); + + return config?.loginBackgroundImage ? ( + <> + {config?.loginBackgroundImage?.alt +
+
{children}
+
+ + ) : ( + <> + Fallback Background +
+
{children}
+
+ + ); +}; + +export default BackgroundWrapper; diff --git a/src/login/login.component.tsx b/src/login/login.component.tsx index 27c381f..7063ccf 100644 --- a/src/login/login.component.tsx +++ b/src/login/login.component.tsx @@ -23,6 +23,7 @@ import { import { getProvider, performLogin, useFacilityName } from "./login.resource"; import Logo from "./logo.component"; import styles from "./login.scss"; +import BackgroundWrapper from "./background.wrapper.component"; export interface LoginReferrer { referrer?: string; @@ -157,7 +158,7 @@ const Login: React.FC = () => { if (config.provider.type === "basic") { return ( -
+
@@ -260,10 +261,9 @@ const Login: React.FC = () => {
- + ); } - return null; }; diff --git a/src/login/login.scss b/src/login/login.scss index fddac81..0ecef07 100644 --- a/src/login/login.scss +++ b/src/login/login.scss @@ -1,14 +1,45 @@ @use "@carbon/colors"; @use "@carbon/styles/scss/type"; @import "../root.scss"; -.container { + +.backgroundContainer { display: flex; align-items: center; - background-image: url("../assets/background.png"); - background-repeat: no-repeat; + justify-content: center; height: 100vh; - background-size: cover; + width: 100%; + position: relative; + overflow: hidden; +} + +.backgroundImage { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + object-fit: cover; + opacity: 1; +} + +.contentOverlay { + position: relative; + z-index: 1; + display: flex; justify-content: center; + align-items: center; +} + +@media screen and (min-width: 1150px) { + .backgroundContainer { + max-width: 80%; + justify-content: right; + } + + .backgroundImage { + object-fit: fit; + /* Fit image for larger screens */ + } } .logoContainer { @@ -20,6 +51,7 @@ @include type.type-style('label-02'); text-align: center; margin-top: 1rem; + >*+* { margin-left: 0.5rem; } @@ -33,6 +65,7 @@ a { color: colors.$gray-70; text-decoration: none; + &:hover { text-decoration: underline; } @@ -45,6 +78,7 @@ flex-flow: row wrap; justify-content: center; align-items: center; + svg { height: 2rem; width: 7rem; @@ -57,9 +91,11 @@ background-size: contain; justify-content: right; } + .login-card { border: none; } + .footer { display: flex; flex-direction: column; @@ -73,8 +109,8 @@ .logo { margin-bottom: 2rem; - height: 7rem; - width: 18.75rem; + max-height: 10rem; + max-width: 20rem; } .logo-img { @@ -130,11 +166,13 @@ flex-direction: column; align-items: center; width: 18rem; - :global(.cds--text-input) { + + :global(.cds--text-input) { height: 3rem; @extend .label01; } - :global(.cds--text-input__field-outer-wrapper) { + + :global(.cds--text-input__field-outer-wrapper) { width: 18rem; } } @@ -154,10 +192,12 @@ .back-button { height: 3rem; padding-left: 0rem; + svg { margin-right: 0.5rem; order: 1; } + span { order: 2; } diff --git a/src/login/login.test.tsx b/src/login/login.test.tsx index 1cdc3ff..09a21e1 100644 --- a/src/login/login.test.tsx +++ b/src/login/login.test.tsx @@ -34,11 +34,6 @@ jest.mock("./login.resource", () => ({ performLogin: jest.fn(), })); -const loginLocations = [ - { uuid: "111", display: "Earth" }, - { uuid: "222", display: "Mars" }, -]; - mockedUseSession.mockReturnValue({ authenticated: false }); mockedUseConfig.mockReturnValue(mockConfig); diff --git a/src/login/logo.component.tsx b/src/login/logo.component.tsx index 470490f..7bbad51 100644 --- a/src/login/logo.component.tsx +++ b/src/login/logo.component.tsx @@ -1,50 +1,62 @@ import React from "react"; +import { useConfig } from "@openmrs/esm-framework"; -const Logo = (props) => ( - - - - - - - - - +const Logo = (props) => { + const { loginLogoImage } = useConfig(); + return loginLogoImage.src ? ( + {loginLogoImage.alt} + ) : ( + + + + + + + + + + + + + + + - - - - - - - -); + + ); +}; + export default Logo;