diff --git a/.gitignore b/.gitignore
index ab434eef3..c90ef2e4e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@
# testing
/coverage
+/cypress.env.json
/cypress/videos
/cypress/screenshots
/cypress/fixtures/login.json
diff --git a/cypress.env.json.example b/cypress.env.json.example
new file mode 100644
index 000000000..08fba94ca
--- /dev/null
+++ b/cypress.env.json.example
@@ -0,0 +1,6 @@
+{
+ "admin_username": "",
+ "admin_password": "",
+ "test_username": "",
+ "test_password": ""
+}
\ No newline at end of file
diff --git a/cypress/integration/IconLogo.spec.py.js b/cypress/integration/IconLogo.spec.py.js
new file mode 100644
index 000000000..16897783b
--- /dev/null
+++ b/cypress/integration/IconLogo.spec.py.js
@@ -0,0 +1,20 @@
+describe('Icon Logo', () => {
+ it('Displays the organization logo when the user belongs to an organization', () => {
+ cy.visit('http://localhost:3001/login');
+ cy.get('#userName').type(Cypress.env('test_username'));
+ cy.get('#password').type(Cypress.env('test_password'));
+ cy.contains(/log/i).click();
+ cy.contains(/earnings/i).click();
+ cy.wait(100);
+ cy.get('img').should('have.attr', 'alt', 'organization logo');
+ });
+ it('Displays the Greenstand logo when the user does not belongs to an organization', () => {
+ cy.visit('http://localhost:3001/login');
+ cy.get('#userName').type(Cypress.env('admin_username'));
+ cy.get('#password').type(Cypress.env('admin_password'));
+ cy.contains(/log/i).click();
+ cy.contains(/earnings/i).click();
+ cy.wait(100);
+ cy.get('img').should('have.attr', 'alt', 'greenstand logo');
+ });
+});
diff --git a/cypress/integration/messaging2.spec.py.js b/cypress/integration/messaging2.spec.py.js
index 02a5bd004..0e013c12b 100644
--- a/cypress/integration/messaging2.spec.py.js
+++ b/cypress/integration/messaging2.spec.py.js
@@ -459,8 +459,8 @@ describe('Messaging', () => {
);
cy.visit('http://localhost:3001/login');
- cy.get('#userName').type('admin');
- cy.get('#password').type('8pzPdcZAG6&Q');
+ cy.get('#userName').type(Cypress.env('admin_username'));
+ cy.get('#password').type(Cypress.env('admin_password'));
cy.contains(/log/i).click();
cy.contains(/inbox/i).click();
cy.contains(
@@ -470,8 +470,8 @@ describe('Messaging', () => {
});
it('Returns an error message if the user is not registered for messaging', () => {
cy.visit('http://localhost:3001/login');
- cy.get('#userName').type('test1');
- cy.get('#password').type('EoCAyCPpW0');
+ cy.get('#userName').type(Cypress.env('test_username'));
+ cy.get('#password').type(Cypress.env('test_password'));
cy.contains(/log/i).click();
cy.contains(/inbox/i).click();
cy.contains(
diff --git a/src/api/stakeholders.js b/src/api/stakeholders.js
index ea146706f..28e6d765c 100644
--- a/src/api/stakeholders.js
+++ b/src/api/stakeholders.js
@@ -54,6 +54,24 @@ export default {
}
},
+ // Returns a single stakeholder data
+ getStakeholder(id) {
+ try {
+ const query = `${STAKEHOLDER_API}/stakeholders/${id}`;
+
+ const options = {
+ method: 'GET',
+ headers: {
+ 'content-type': 'application/json',
+ },
+ };
+
+ return fetchJSON(query, options);
+ } catch (e) {
+ log.error('getStakeholder', e);
+ }
+ },
+
deleteStakeholder(id, stakeholderData) {
try {
const orgId = id || getOrganizationId();
diff --git a/src/components/IconLogo.js b/src/components/IconLogo.js
index f0280e1b9..27f1f4962 100644
--- a/src/components/IconLogo.js
+++ b/src/components/IconLogo.js
@@ -1,22 +1,47 @@
import { Link } from 'react-router-dom';
import logo from './images/logo.svg';
+import { AppContext } from '../context/AppContext';
+import { React, useContext } from 'react';
/*
* Just a logo icon
*/
-import React from 'react';
export default function IconLogo() {
+ const appContext = useContext(AppContext);
+ const { logoPath, user } = appContext;
+
+ // Hide logo if the logo URL hasn't been loaded or if the Greenstand logo is loaded
+ // and the user has an organization
+ function isVisible() {
+ if (!user) {
+ return 'visible';
+ }
+ if (logoPath === '') {
+ return 'hidden';
+ } else return 'visible';
+ }
+
+ // Logo styling objects for both org and Greenstand logos to be applied to img
+ const greenstandLogoStyle = {
+ maxWidth: 149,
+ maxHeight: 32,
+ marginBottom: '-6px',
+ visibility: isVisible(),
+ };
+
+ const orgLogoStyle = {
+ maxHeight: 50,
+ marginBottom: '-15px',
+ visibility: isVisible(),
+ };
+
return (
);
diff --git a/src/components/Login.js b/src/components/Login.js
index 21ac609f4..05a80c34e 100644
--- a/src/components/Login.js
+++ b/src/components/Login.js
@@ -11,10 +11,11 @@ import {
Container,
CircularProgress,
} from '@material-ui/core';
-import IconLogo from './IconLogo';
+import logo from './images/logo.svg';
import { withStyles } from '@material-ui/core/styles';
import { AppContext } from '../context/AppContext';
import classNames from 'classnames';
+import api from '../api/stakeholders';
import { useHistory, useLocation } from 'react-router-dom';
import axios from 'axios';
// import Copyright from 'components/Copyright'
@@ -142,7 +143,21 @@ const Login = (props) => {
if (res.status === 200) {
const token = res.data.token;
const user = res.data.user;
- appContext.login(user, token, isRemember);
+ // GET logo URL from API if user belongs to an organization
+ // and apply it to logoPath state before completing login
+ if (user.policy.organization) {
+ const orgID = user.policy.organization.id;
+ try {
+ await api.getStakeholder(orgID).then((response) => {
+ const orgLogo = response.stakeholders[0].logo_url;
+ orgLogo && appContext.setLogoPath(orgLogo);
+ });
+ } catch (e) {
+ console.error('Undefined User error:', e);
+ } finally {
+ appContext.login(user, token, isRemember);
+ }
+ } else appContext.login(user, token, isRemember);
} else {
setErrorMessage('Invalid username or password');
setLoading(false);
@@ -167,7 +182,15 @@ const Login = (props) => {
-
+
Admin Panel