Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(feature) O3-3859 Ability to customize or add logos at the bottom of the LogIn page below the "Powered by" #1127

Merged
merged 6 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/apps/esm-login-app/__mocks__/config.mock.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ConfigSchema } from '../src/config-schema';
import { type ConfigSchema } from '../src/config-schema';

export const mockConfig: ConfigSchema = {
provider: {
Expand All @@ -19,5 +19,8 @@ export const mockConfig: ConfigSchema = {
links: {
loginSuccess: '${openmrsSpaBase}/home',
},
footer: {
additionalLogos: [],
},
showPasswordOnSeparateScreen: true,
};
29 changes: 29 additions & 0 deletions packages/apps/esm-login-app/src/config-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,29 @@ export const configSchema = {
_description: 'The alternative text for the logo image, displayed when the image cannot be loaded or on hover.',
},
},
footer: {
additionalLogos: {
_type: Type.Array,
_elements: {
_type: Type.Object,
_properties: {
brandones marked this conversation as resolved.
Show resolved Hide resolved
src: {
_type: Type.String,
_required: true,
_description: 'The source URL of the logo image',
_validations: [validators.isUrl]
},
alt: {
_type: Type.String,
_required: true,
_description: 'The alternative text for the logo image'
}
}
},
_default: [],
_description: 'An array of logos to be displayed in the footer next to the OpenMRS logo.',
}
},
showPasswordOnSeparateScreen: {
_type: Type.Boolean,
_default: true,
Expand Down Expand Up @@ -95,5 +118,11 @@ export interface ConfigSchema {
alt: string;
src: string;
};
footer: {
additionalLogos: Array<{
src: string;
alt: string;
}>;
};
showPasswordOnSeparateScreen: boolean;
}
32 changes: 32 additions & 0 deletions packages/apps/esm-login-app/src/footer.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import { interpolateUrl, useConfig } from '@openmrs/esm-framework';
import { useTranslation } from 'react-i18next';
import { type ConfigSchema } from './config-schema';
import styles from './login/login.scss';

const Footer: React.FC = () => {
const {t} = useTranslation();
const config = useConfig<ConfigSchema>();
const logos = config.footer.additionalLogos || [];

return (
<div className={styles.footer}>
<p className={styles.poweredByTxt}>{t('poweredBy', 'Powered by')}</p>
<div className={styles.logosContainer}>
<svg role="img" className={styles.poweredByLogo}>
<use href="#omrs-logo-partial-mono"></use>
</svg>
{logos.map((logo, index) => (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @suubi-joshua Basing on @ibacher suggestion, Does this fixes the issue. i thought this can be generic

<img
key={index}
alt={logo.alt ? t(logo.alt) : t('footerlogo', 'Footer Logo')}
className={styles.poweredByLogo}
src={logo.src}
/>
))}
</div>
</div>
);
};

export default Footer;
10 changes: 2 additions & 8 deletions packages/apps/esm-login-app/src/login/login.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from '@openmrs/esm-framework';
import { type ConfigSchema } from '../config-schema';
import Logo from '../logo.component';
import Footer from '../footer.component';
import styles from './login.scss';

export interface LoginReferrer {
Expand Down Expand Up @@ -265,14 +266,7 @@ const Login: React.FC = () => {
)}
</form>
</Tile>
<div className={styles.footer}>
<p className={styles.poweredByTxt}>{t('poweredBy', 'Powered by')}</p>
<div>
<svg role="img" className={styles.poweredByLogo}>
<use href="#omrs-logo-partial-mono"></use>
</svg>
</div>
</div>
<Footer/>
</div>
);
}
Expand Down
26 changes: 24 additions & 2 deletions packages/apps/esm-login-app/src/login/login.scss
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,31 @@
margin-left: 0.5rem;
}

.footer {
display: flex;
flex-direction: column;
align-items: center;
padding: 1.5rem;
}

.logosContainer {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.logosContainer {
.logosContainer::last-of-type {
margin-right: 0;
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard to tell without seeing the dev tools how the margins are working. If you want to clean it up after the merge, @vasharma05 , you are very welcome, I'll give a quick review. But this has been open a long time already, time to get it in.

margin-right: 0;
display: flex;
justify-content: center;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
gap: 2rem;
filter: grayscale(100%);
opacity: 1;
}

.poweredByLogo {
height: 2.5rem;
width: 6.5rem;
height: 3rem;
width: auto;
max-width: 8rem;
object-fit: contain;
display: block;
}

.loginCard {
Expand Down
4 changes: 2 additions & 2 deletions packages/apps/esm-login-app/src/login/login.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ describe('Login', () => {
renderWithRouter(
Login,
{},
{
{
route: '/login',
},
);

screen.getByRole('img', { name: /OpenMRS logo/i });
expect(screen.queryByAltText(/logo/i)).not.toBeInTheDocument();
expect(screen.queryByAltText(/^logo$/i)).not.toBeInTheDocument();
screen.getByRole('textbox', { name: /Username/i });
screen.getByRole('button', { name: /Continue/i });
});
Expand Down
2 changes: 1 addition & 1 deletion packages/apps/esm-login-app/src/logo.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const Logo: React.FC<{ t: TFunction }> = ({ t }) => {
<svg role="img" className={styles.logo}>
<title>{t('openmrsLogo', 'OpenMRS logo')}</title>
<use href="#omrs-logo-full-color"></use>
</svg>
</svg>
);
};

Expand Down
Loading