Skip to content

Commit

Permalink
Merge branch 'develop' into fix/a11y-search-typeahead
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristiaanScheermeijer authored Apr 16, 2024
2 parents 32f200e + d6c7202 commit 94bc6cb
Show file tree
Hide file tree
Showing 21 changed files with 282 additions and 54 deletions.
2 changes: 2 additions & 0 deletions packages/common/src/controllers/CheckoutController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ export default class CheckoutController {
useCheckoutStore.getState().setOrder(null);
} else if (error.message === 'Invalid coupon code') {
throw new FormValidationError({ couponCode: [i18next.t('account:checkout.coupon_not_valid')] });
} else if (error.message === 'Invalid coupon code for this offer') {
throw new FormValidationError({ couponCode: [i18next.t('account:checkout.coupon_not_valid_for_offer')] });
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ export default class CleengCheckoutService extends CheckoutService {
if (response.errors[0].includes(`Coupon ${payload.couponCode} not found`)) {
throw new Error('Invalid coupon code');
}

if (response.errors[0].includes(`Coupon ${payload.couponCode} cannot be applied on this offer`)) {
throw new Error('Invalid coupon code for this offer');
}
}

return response;
Expand Down
30 changes: 29 additions & 1 deletion packages/ui-react/src/components/Header/Header.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,17 @@
flex: 1;
align-items: center;

> a {
> ul {
margin: 0;
padding: 0;
list-style-type: none;

li {
display: inline-block;
}
}

a {
height: 36px;
min-height: 36px;
margin: 0 6px;
Expand Down Expand Up @@ -177,6 +187,24 @@
}
}

.navButton {
overflow: visible;

&::after {
position: absolute;
bottom: calc(((variables.$header-height - 36px) / 2) * -1);
left: 0;
width: 100%;
height: 2px;
background-color: variables.$white;
content: '';
}

body:global(.is-tabbing) &:focus::after {
display: none;
}
}

//
// mediaQueries
// --------------------------------
Expand Down
41 changes: 39 additions & 2 deletions packages/ui-react/src/components/Header/Header.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('<Header />', () => {
});

test('renders header', () => {
const playlistMenuItems = [<Button key="key" label="Home" to="/" />];
const homeButton = [<Button key="key" label="Home" to="/" />];
const { container } = render(
<Header
onMenuButtonClick={vi.fn()}
Expand All @@ -46,10 +46,47 @@ describe('<Header />', () => {
currentLanguage={undefined}
onLanguageClick={vi.fn()}
>
{playlistMenuItems}
{homeButton}
</Header>,
);

expect(container).toMatchSnapshot();
});

test('renders header with nav buttons', () => {
const navItems = [
{ label: 'Home', to: '/' },
{ label: 'Button test', to: '/test' },
];
const { container } = render(
<Header
onMenuButtonClick={vi.fn()}
searchBarProps={{
query: '',
onQueryChange: vi.fn(),
}}
searchEnabled
searchActive={false}
onSearchButtonClick={vi.fn()}
onCloseSearchButtonClick={vi.fn()}
onLoginButtonClick={vi.fn()}
userMenuOpen={false}
sideBarOpen={false}
openUserPanel={vi.fn()}
closeUserPanel={vi.fn()}
openLanguageMenu={vi.fn()}
closeLanguageMenu={vi.fn()}
isLoggedIn={false}
canLogin={true}
showPaymentsMenuItem={true}
supportedLanguages={[]}
languageMenuOpen={false}
currentLanguage={undefined}
onLanguageClick={vi.fn()}
navItems={navItems}
/>,
);

expect(container).toMatchSnapshot();
});
});
28 changes: 26 additions & 2 deletions packages/ui-react/src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ import styles from './Header.module.scss';

type TypeHeader = 'static' | 'fixed';

type NavItem = {
label: string;
to: string;
};

type Props = {
headerType?: TypeHeader;
onMenuButtonClick: () => void;
Expand All @@ -51,6 +56,8 @@ type Props = {
currentLanguage: LanguageDefinition | undefined;
onLanguageClick: (code: string) => void;
favoritesEnabled?: boolean;
siteName?: string;
navItems?: NavItem[];

profilesData?: {
currentProfile: Profile | null;
Expand Down Expand Up @@ -87,7 +94,9 @@ const Header: React.FC<Props> = ({
currentLanguage,
onLanguageClick,
favoritesEnabled,
siteName,
profilesData: { currentProfile, profiles, profilesEnabled, selectProfile, isSelectingProfile } = {},
navItems = [],
}) => {
const { t } = useTranslation('menu');
const [logoLoaded, setLogoLoaded] = useState(false);
Expand Down Expand Up @@ -195,6 +204,21 @@ const Header: React.FC<Props> = ({
);
};

const renderNav = () => {
if (navItems.length === 0) {
return children;
}
return (
<ul>
{navItems.map((item, index) => (
<li key={index}>
<Button activeClassname={styles.navButton} label={item.label} to={item.to} variant="text" />
</li>
))}
</ul>
);
};

return (
<header className={headerClassName}>
<div className={styles.container}>
Expand All @@ -215,10 +239,10 @@ const Header: React.FC<Props> = ({
</div>
{logoSrc && (
<div className={styles.brand}>
<Logo src={logoSrc} onLoad={() => setLogoLoaded(true)} />
<Logo alt={t('logo_alt', { siteName })} src={logoSrc} onLoad={() => setLogoLoaded(true)} />
</div>
)}
<nav className={styles.nav}>{logoLoaded || !logoSrc ? children : null}</nav>
<nav className={styles.nav}>{logoLoaded || !logoSrc ? renderNav() : null}</nav>
<div className={styles.actions}>
{renderSearch()}
{renderLanguageDropdown()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,105 @@ exports[`<Header /> > renders header 1`] = `
</header>
</div>
`;

exports[`<Header /> > renders header with nav buttons 1`] = `
<div>
<header
class="_header_f4f7a7 _static_f4f7a7"
>
<div
class="_container_f4f7a7"
>
<a
class="_skipToContent_f4f7a7"
href="#content"
>
skip_to_content
</a>
<div
class="_menu_f4f7a7"
>
<div
aria-controls="sidebar"
aria-expanded="false"
aria-haspopup="true"
aria-label="open_menu"
class="_iconButton_0fef65 _iconButton_f4f7a7"
role="button"
tabindex="0"
>
<svg
aria-hidden="true"
class="_icon_585b29"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 0h24v24H0V0z"
fill="none"
/>
<path
d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"
/>
</svg>
</div>
</div>
<nav
class="_nav_f4f7a7"
>
<ul>
<li>
a
</li>
<li>
a
</li>
</ul>
</nav>
<div
class="_actions_f4f7a7"
>
<div
aria-label="Open search"
class="_iconButton_0fef65 _iconButton_f4f7a7 _actionButton_f4f7a7"
role="button"
tabindex="0"
>
<svg
aria-hidden="true"
class="_icon_585b29"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"
/>
</svg>
</div>
<div
class="_buttonContainer_f4f7a7"
>
<button
aria-haspopup="dialog"
class="_button_f8f296 _default_f8f296 _outlined_f8f296"
type="button"
>
<span>
sign_in
</span>
</button>
<button
aria-haspopup="dialog"
class="_button_f8f296 _primary_f8f296"
type="button"
>
<span>
sign_up
</span>
</button>
</div>
</div>
</div>
</header>
</div>
`;
5 changes: 3 additions & 2 deletions packages/ui-react/src/components/Logo/Logo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import styles from './Logo.module.scss';

type Props = {
src: string;
alt?: string;
onLoad: () => void;
};

Expand All @@ -13,7 +14,7 @@ type ImgRef = {
width?: number;
};

const Logo: React.FC<Props> = ({ src, onLoad }: Props) => {
const Logo: React.FC<Props> = ({ src, alt = 'logo', onLoad }: Props) => {
const [imgDimensions, updateImgDimensions] = useState<ImgRef>({ height: undefined, width: undefined });

const onLoadHandler = (event: React.SyntheticEvent<HTMLImageElement, Event>) => {
Expand All @@ -24,7 +25,7 @@ const Logo: React.FC<Props> = ({ src, onLoad }: Props) => {

return (
<Link to="/">
<img className={styles.logo} alt="logo" src={src} height={imgDimensions.height} width={imgDimensions.width} onLoad={onLoadHandler} onError={onLoad} />
<img className={styles.logo} alt={alt} src={src} height={imgDimensions.height} width={imgDimensions.width} onLoad={onLoadHandler} onError={onLoad} />
</Link>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
import React from 'react';

import { renderWithRouter } from '../../../test/utils';
import { renderWithRouter, waitForWithFakeTimers } from '../../../test/utils';

import RegistrationForm from './RegistrationForm';

// The SocialButton component contains an SVG import that results in an absolute path on the current machine
// This results in snapshot inconsistencies per machine
vi.mock('../SocialButton/SocialButton.tsx', () => ({
default: (props: { href: string }) => {
return <a href={props.href}>Social Button</a>;
},
}));

const socialLoginURLs = {
twitter: 'https://staging-v2.inplayer.com/',
facebook: 'https://www.facebook.com/',
google: 'https://accounts.google.com/',
};

describe('<RegistrationForm>', () => {
test('renders and matches snapshot', () => {
test('renders and matches snapshot', async () => {
const { container } = renderWithRouter(
<RegistrationForm
publisherConsents={null}
Expand All @@ -19,9 +33,12 @@ describe('<RegistrationForm>', () => {
consentValues={{}}
loading={false}
onConsentChange={vi.fn()}
socialLoginURLs={socialLoginURLs}
/>,
);

await waitForWithFakeTimers();

expect(container).toMatchSnapshot();
});
});
Loading

0 comments on commit 94bc6cb

Please sign in to comment.