Skip to content

Commit

Permalink
fix(client): address nav UX issues (freeCodeCamp#40823)
Browse files Browse the repository at this point in the history
Co-authored-by: nhcarrigan <[email protected]>
  • Loading branch information
2 people authored and raisedadead committed Jan 31, 2021
1 parent 1875984 commit c56a9c9
Show file tree
Hide file tree
Showing 15 changed files with 484 additions and 277 deletions.
3 changes: 2 additions & 1 deletion client/i18n/locales/chinese/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,8 @@
"update-email-1": "更新你的邮件地址",
"update-email-2": "在这里更新你的邮件地址:",
"email": "邮箱",
"and": ""
"and": "",
"change-theme": "Sign in to change theme."
},
"icons": {
"gold-cup": "金奖杯",
Expand Down
3 changes: 2 additions & 1 deletion client/i18n/locales/english/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,8 @@
"update-email-1": "Update your email address",
"update-email-2": "Update your email address here:",
"email": "Email",
"and": "and"
"and": "and",
"change-theme": "Sign in to change theme."
},
"icons": {
"gold-cup": "Gold Cup",
Expand Down
3 changes: 2 additions & 1 deletion client/i18n/locales/espanol/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,8 @@
"update-email-1": "Actualiza tu correo electrónico",
"update-email-2": "Actualiza tu correo electrónico aquí:",
"email": "Correo electrónico",
"and": "y"
"and": "y",
"change-theme": "Sign in to change theme."
},
"icons": {
"gold-cup": "Copa de Oro",
Expand Down
3 changes: 2 additions & 1 deletion client/i18n/translations-schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,8 @@ const translationsSchema = {
'update-email-1': 'Update your email address',
'update-email-2': 'Update your email address here:',
email: 'Email',
and: 'and'
and: 'and',
'change-theme': 'Sign in to change theme.'
},
icons: {
'gold-cup': 'Gold Cup',
Expand Down
50 changes: 0 additions & 50 deletions client/src/components/Footer/LanguageMenu.js

This file was deleted.

26 changes: 0 additions & 26 deletions client/src/components/Footer/__snapshots__/Footer.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,6 @@ exports[`<Footer /> matches snapshot 1`] = `
<div
className="footer-desc-col"
>
<div
className="language-menu"
>
<label>
footer.language
<select
onChange={[Function]}
>
<option
value="english"
>
English
</option>
<option
value="espanol"
>
Español
</option>
<option
value="chinese"
>
中文
</option>
</select>
</label>
</div>
<p>
footer.tax-exempt-status
</p>
Expand Down
15 changes: 0 additions & 15 deletions client/src/components/Footer/footer.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,6 @@
overflow-x: hidden;
}

.footer-container .language-menu {
display: flex;
margin-bottom: 10px;
}

.footer-container .language-menu label {
font-weight: normal;
}

.footer-container .language-menu select {
padding: 0 5px;
margin-left: 10px;
font-weight: normal;
}

.footer-container p {
margin: 0 0 1.45rem;
line-height: 30px;
Expand Down
4 changes: 0 additions & 4 deletions client/src/components/Footer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@ import React from 'react';
import PropTypes from 'prop-types';
import { useTranslation } from 'react-i18next';
import Link from '../helpers/Link';
import LanguageMenu from './LanguageMenu';
import './footer.css';

const { showLocaleDropdownMenu = false } = require('../../../config/env');

const propTypes = {
children: PropTypes.any
};
Expand All @@ -26,7 +23,6 @@ function Footer() {
<div className='footer-container'>
<div className='footer-top'>
<div className='footer-desc-col'>
{showLocaleDropdownMenu ? <LanguageMenu /> : null}
<p>{t('footer.tax-exempt-status')}</p>
<p>{t('footer.mission-statement')}</p>
<p>{t('footer.donation-initiatives')}</p>
Expand Down
139 changes: 118 additions & 21 deletions client/src/components/Header/Header.test.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
/* global expect */
import React from 'react';
import ShallowRenderer from 'react-test-renderer/shallow';
/* import { useTranslation } from 'react-i18next';
import { I18nextProvider } from 'react-i18next';

import i18n from '../../../i18n/configForTests';*/
import { UniversalNav } from './components/UniversalNav';
import { NavLinks } from './components/NavLinks';
import AuthOrProfile from './components/AuthOrProfile';

import { apiLocation } from '../../../../config/env.json';

describe('<UniversalNav />', () => {
const UniversalNavProps = {
displayMenu: false,
menuButtonRef: {},
searchBarRef: {},
toggleDisplayMenu: function() {},
pathName: '/'
pathName: '/',
fetchState: {
pending: false
}
};
it('renders to the DOM', () => {
const shallow = new ShallowRenderer();
Expand All @@ -26,14 +28,14 @@ describe('<UniversalNav />', () => {
});

describe('<NavLinks />', () => {
it('has expected navigation links', () => {
it('has expected navigation links when not signed in', () => {
const landingPageProps = {
fetchState: {
pending: false
},
user: {
isUserDonating: false,
username: '',
isDonating: false,
username: null,
theme: 'default'
},
i18n: {
Expand All @@ -45,11 +47,70 @@ describe('<NavLinks />', () => {
shallow.render(<NavLinks {...landingPageProps} />);
const result = shallow.getRenderOutput();
expect(
hasRadioNavItem(result) &&
hasDonateNavItem(result) &&
hasSignInNavItem(result) &&
hasCurriculumNavItem(result) &&
hasForumNavItem(result) &&
hasNewsNavItem(result) &&
hasRadioNavItem(result)
).toBeTruthy();
});

it('has expected navigation links when signed in', () => {
const landingPageProps = {
fetchState: {
pending: false
},
user: {
isDonating: false,
username: 'nhcarrigan',
theme: 'default'
},
i18n: {
language: 'en'
},
toggleNightMode: theme => theme
};
const shallow = new ShallowRenderer();
shallow.render(<NavLinks {...landingPageProps} />);
const result = shallow.getRenderOutput();
expect(
hasDonateNavItem(result) &&
hasCurriculumNavItem(result) &&
hasProfileAndSettingsNavItems(result, landingPageProps.user.username) &&
hasForumNavItem(result) &&
hasNewsNavItem(result) &&
hasDonateNavItem(result)
hasRadioNavItem(result) &&
hasSignOutNavItem(result)
).toBeTruthy();
});

it('has expected navigation links when signed in and donating', () => {
const landingPageProps = {
fetchState: {
pending: false
},
user: {
isDonating: true,
username: 'moT01',
theme: 'default'
},
i18n: {
language: 'en'
},
toggleNightMode: theme => theme
};
const shallow = new ShallowRenderer();
shallow.render(<NavLinks {...landingPageProps} />);
const result = shallow.getRenderOutput();
expect(
hasThanksForDonating(result) &&
hasCurriculumNavItem(result) &&
hasProfileAndSettingsNavItems(result, landingPageProps.user.username) &&
hasForumNavItem(result) &&
hasNewsNavItem(result) &&
hasRadioNavItem(result) &&
hasSignOutNavItem(result)
).toBeTruthy();
});
});
Expand All @@ -68,7 +129,6 @@ describe('<AuthOrProfile />', () => {
const shallow = new ShallowRenderer();
shallow.render(<AuthOrProfile {...defaultUserProps} />);
const componentTree = shallow.getRenderOutput();

expect(avatarHasClass(componentTree, 'default-border')).toBeTruthy();
});

Expand Down Expand Up @@ -125,7 +185,7 @@ describe('<AuthOrProfile />', () => {
});

const navigationLinks = (component, navItem) => {
return component.props.children.props.children[navItem].props.children.props;
return component.props.children[navItem].props;
};

const profileNavItem = component => component.props.children;
Expand All @@ -135,29 +195,66 @@ const hasDonateNavItem = component => {
return children === 'buttons.donate' && to === '/donate';
};

const hasThanksForDonating = component => {
const { children } = navigationLinks(component, 0);
return children[0].props.children === 'donate.thanks';
};

const hasSignInNavItem = component => {
const { children } = navigationLinks(component, 1);
return children === 'buttons.sign-in';
};

const hasCurriculumNavItem = component => {
const { children, to } = navigationLinks(component, 2);
return children === 'buttons.curriculum' && to === '/learn';
};

const hasProfileAndSettingsNavItems = (component, username) => {
const fragment = navigationLinks(component, 3);

const profile = fragment.children[0].props;
const settings = fragment.children[1].props;

const hasProfile =
profile.children === 'buttons.profile' && profile.to === `/${username}`;
const hasSettings =
settings.children === 'buttons.settings' && settings.to === '/settings';

return hasProfile && hasSettings;
};

const hasForumNavItem = component => {
const { children, to } = navigationLinks(component, 1);
const { children, to } = navigationLinks(component, 5);
return (
children === 'buttons.forum' && to === 'https://forum.freecodecamp.org'
children[0].props.children === 'buttons.forum' &&
to === 'https://forum.freecodecamp.org/'
);
};

const hasNewsNavItem = component => {
const { children, to } = navigationLinks(component, 2);
const { children, to } = navigationLinks(component, 6);
return (
children === 'buttons.news' && to === 'https://www.freecodecamp.org/news'
children[0].props.children === 'buttons.news' &&
to === 'https://www.freecodecamp.org/news'
);
};

const hasCurriculumNavItem = component => {
const { children, to } = navigationLinks(component, 3);
return children === 'buttons.curriculum' && to === '/learn';
const hasRadioNavItem = component => {
const { children, to } = navigationLinks(component, 7);
return (
children[0].props.children === 'buttons.radio' &&
to === 'https://coderadio.freecodecamp.org'
);
};

const hasRadioNavItem = component => {
const { children, to } = navigationLinks(component, 5);
const hasSignOutNavItem = component => {
const { children } = navigationLinks(component, 10);
const signOutProps = children[1].props;

return (
children === 'buttons.radio' && to === 'https://coderadio.freecodecamp.org'
signOutProps.children === 'buttons.sign-out' &&
signOutProps.href === `${apiLocation}/signout`
);
};

Expand Down
Loading

0 comments on commit c56a9c9

Please sign in to comment.