diff --git a/.github/workflows/release-build-tag-release.yml b/.github/workflows/release-build-tag-release.yml index 26aa6ac42..43a172b47 100644 --- a/.github/workflows/release-build-tag-release.yml +++ b/.github/workflows/release-build-tag-release.yml @@ -8,6 +8,11 @@ on: jobs: create-new-release-version: runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [18.x] + steps: - name: Checkout code uses: actions/checkout@v3 @@ -52,7 +57,7 @@ jobs: if: ${{ steps.package-version.outputs.current-version }} with: commit: 'release' - artifacts: 'web/build/ott-web-app-build-*.tar.gz, web/build/ott-web-app-build-*.zip' + artifacts: 'platforms/web/build/ott-web-app-build-*.tar.gz, platforms/web/build/ott-web-app-build-*.zip' tag: v${{ steps.package-version.outputs.current-version }} bodyFile: '.github/RELEASE_BODY_TEMPLATE.md' token: ${{ secrets.github_token }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 230792e18..9aa3cd486 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,28 @@ +## [6.1.1](https://github.com/jwplayer/ott-web-app/compare/v6.1.0...v6.1.1) (2024-04-23) + + +### Bug Fixes + +* **a11y:** close menu focus with voice over ([5e6d445](https://github.com/jwplayer/ott-web-app/commit/5e6d445bc78926011477121adcd4dda5b233ee40)) +* **a11y:** header navigation list ([1d22ab0](https://github.com/jwplayer/ott-web-app/commit/1d22ab05d4f5004fff8740827dc37b3d8460debf)) +* **a11y:** icon button to use button element ([7d5beae](https://github.com/jwplayer/ott-web-app/commit/7d5beae6f12ab4de55414bc2f2f1a46386915921)) +* **a11y:** lose focus after activating share button ([1cd135e](https://github.com/jwplayer/ott-web-app/commit/1cd135ea3eccae6d956d71493611d3e8cf79adc0)) +* **a11y:** read title while searching ([b46e659](https://github.com/jwplayer/ott-web-app/commit/b46e6595c423e33452185751807372ed8fc8ddd2)) +* **a11y:** sitename in logo alt ([051e46f](https://github.com/jwplayer/ott-web-app/commit/051e46f54a55aec5a6cde3b296859472bb362e6a)) +* add social login buttons to signup screen ([#496](https://github.com/jwplayer/ott-web-app/issues/496)) ([c2e3f52](https://github.com/jwplayer/ott-web-app/commit/c2e3f5266f0e29637e9e85ccef53c9dc54d962ce)) +* change wording ([#488](https://github.com/jwplayer/ott-web-app/issues/488)) ([1011dd2](https://github.com/jwplayer/ott-web-app/commit/1011dd28252afe0c001b1a27c5b1c3589a5c1cea)) +* **e2e:** search results based on typeahead changes ([1b3bebf](https://github.com/jwplayer/ott-web-app/commit/1b3bebff20027645003c657c5964ceb3580a6f2c)) +* Leave the path intact and only remove token from hash after login with social media ([#499](https://github.com/jwplayer/ott-web-app/issues/499)) ([8abc55c](https://github.com/jwplayer/ott-web-app/commit/8abc55c537fc50a39b85d9c941f038e7688d9c94)) +* **payment:** catch cleeng invalid coupon for offer ([930d52b](https://github.com/jwplayer/ott-web-app/commit/930d52b015434f968f9a0bef477ddcadcb0013c9)) +* **payment:** cleeng paypal invalid url error ([880e4af](https://github.com/jwplayer/ott-web-app/commit/880e4af3ef3a01054a65f3bebb75e32287aae469)) +* plans prompt after social register ([#498](https://github.com/jwplayer/ott-web-app/issues/498)) ([fa8c142](https://github.com/jwplayer/ott-web-app/commit/fa8c142331a87fe363aa639ab70ef14015a01439)) +* **project:** fix workflow ([bf73a1b](https://github.com/jwplayer/ott-web-app/commit/bf73a1b7e9f0fe904164db2a425269e3dd2f9bda)) +* **project:** improve form validation on account page ([0dfa380](https://github.com/jwplayer/ott-web-app/commit/0dfa380a07be113cdb691eaaa5b245a54f91afc2)) +* **project:** old password form error after validation ([7e11074](https://github.com/jwplayer/ott-web-app/commit/7e11074c1ba9aebc02f01e0dfffcc47d39a9a370)) +* **project:** retain password input during sign up ([2a5e2fe](https://github.com/jwplayer/ott-web-app/commit/2a5e2fe5a395f019e430993d14d3fd9e2de5340d)) +* **project:** scroll to top on static pages ([a9a0d1f](https://github.com/jwplayer/ott-web-app/commit/a9a0d1fa4d9266bb532544f1377010819ac47ff5)) +* **videodetail:** unnecessary scrollbar in videolist ([11a0e32](https://github.com/jwplayer/ott-web-app/commit/11a0e32f26b68d4ceeab5edfba2e912e8423198d)) + ## [6.1.0](https://github.com/jwplayer/ott-web-app/compare/v6.0.0...v6.1.0) (2024-04-05) diff --git a/package.json b/package.json index 1a8494cad..b13af62b3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@jwp/ott", - "version": "6.1.0", + "version": "6.1.1", "private": true, "license": "Apache-2.0", "repository": "https://github.com/jwplayer/ott-web-app.git", diff --git a/packages/common/src/controllers/CheckoutController.ts b/packages/common/src/controllers/CheckoutController.ts index ffe195d50..917699af9 100644 --- a/packages/common/src/controllers/CheckoutController.ts +++ b/packages/common/src/controllers/CheckoutController.ts @@ -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')] }); } } diff --git a/packages/common/src/services/integrations/cleeng/CleengCheckoutService.ts b/packages/common/src/services/integrations/cleeng/CleengCheckoutService.ts index 1dc3bce05..6aa89be0e 100644 --- a/packages/common/src/services/integrations/cleeng/CleengCheckoutService.ts +++ b/packages/common/src/services/integrations/cleeng/CleengCheckoutService.ts @@ -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; diff --git a/packages/common/src/services/integrations/jwp/JWPAccountService.ts b/packages/common/src/services/integrations/jwp/JWPAccountService.ts index a2e258592..5daba8d5e 100644 --- a/packages/common/src/services/integrations/jwp/JWPAccountService.ts +++ b/packages/common/src/services/integrations/jwp/JWPAccountService.ts @@ -393,15 +393,18 @@ export default class JWPAccountService extends AccountService { return data; }; - getCaptureStatus: GetCaptureStatus = async ({ customer }) => { + getCaptureStatus: GetCaptureStatus = async ({ customer: { firstName, lastName } }) => { + const firstNameTrimmed = firstName?.trim() || ''; + const lastNameTrimmed = lastName?.trim() || ''; + return { isCaptureEnabled: true, - shouldCaptureBeDisplayed: true, + shouldCaptureBeDisplayed: !firstNameTrimmed || !lastNameTrimmed, settings: [ { answer: { - firstName: customer.firstName || null, - lastName: customer.lastName || null, + firstName: firstNameTrimmed || null, + lastName: lastNameTrimmed || null, }, enabled: true, key: 'firstNameLastName', diff --git a/packages/common/src/utils/urlFormatting.ts b/packages/common/src/utils/urlFormatting.ts index 4ce11e919..0ba584fb9 100644 --- a/packages/common/src/utils/urlFormatting.ts +++ b/packages/common/src/utils/urlFormatting.ts @@ -5,8 +5,16 @@ import { getLegacySeriesPlaylistIdFromEpisodeTags, getSeriesPlaylistIdFromCustom export type QueryParamsArg = { [key: string]: string | number | string[] | undefined | null }; -// Creates a new URL from a url string (could include search params) and an object to add and remove query params -// For example: createURL(window.location.pathname, { foo: 'bar' }); +/** + * Creates a new URL from an url string (preserving the search params) and an object to add and remove query params + * + * @example + * createURL('/m/123456?play=1', { foo: 'bar' }) === '/m/123456?play=6&foo=bar' + * createURL('/m/123456?play=1', { play: null }) === '/m/123456' + * + * // works with absolute URLs + * createURL('https://jwplayer.com/m/123456?play=1', { play: null }) === 'https://jwplayer.com/m/123456' + */ export const createURL = (url: string, queryParams: QueryParamsArg) => { const [baseUrl, urlQueryString = ''] = url.split('?'); const urlSearchParams = new URLSearchParams(urlQueryString); diff --git a/packages/hooks-react/src/useSocialLoginUrls.ts b/packages/hooks-react/src/useSocialLoginUrls.ts index 5c3d59a02..e254ae3ca 100644 --- a/packages/hooks-react/src/useSocialLoginUrls.ts +++ b/packages/hooks-react/src/useSocialLoginUrls.ts @@ -1,3 +1,4 @@ +import { useMemo } from 'react'; import { useQuery } from 'react-query'; import { getModule } from '@jwp/ott-common/src/modules/container'; import AccountController from '@jwp/ott-common/src/controllers/AccountController'; @@ -7,14 +8,20 @@ export type SocialLoginURLs = Record; export default function useSocialLoginUrls(url: string) { const accountController = getModule(AccountController); - const urls = useQuery(['socialUrls'], () => accountController.getSocialLoginUrls(url), { + const { data, error } = useQuery(['socialUrls', url], () => accountController.getSocialLoginUrls(url), { enabled: accountController.getFeatures().hasSocialURLs, retry: false, }); - if (urls.error || !urls.data) { + const urls = useMemo(() => { + if (!data) return null; + + return data.reduce((acc, url) => ({ ...acc, ...url }), {} as SocialLoginURLs); + }, [data]); + + if (error || !urls) { return null; } - return urls.data.reduce((acc, url) => ({ ...acc, ...url }), {} as SocialLoginURLs); + return urls; } diff --git a/packages/ui-react/src/components/CheckoutForm/__snapshots__/CheckoutForm.test.tsx.snap b/packages/ui-react/src/components/CheckoutForm/__snapshots__/CheckoutForm.test.tsx.snap index ebbee84cb..68dd32a08 100644 --- a/packages/ui-react/src/components/CheckoutForm/__snapshots__/CheckoutForm.test.tsx.snap +++ b/packages/ui-react/src/components/CheckoutForm/__snapshots__/CheckoutForm.test.tsx.snap @@ -216,11 +216,10 @@ exports[` > renders and matches snapshot 1`] = ` -
-
+ `; diff --git a/packages/ui-react/src/components/Dialog/__snapshots__/Dialog.test.tsx.snap b/packages/ui-react/src/components/Dialog/__snapshots__/Dialog.test.tsx.snap index a46295ebc..ca13b6772 100644 --- a/packages/ui-react/src/components/Dialog/__snapshots__/Dialog.test.tsx.snap +++ b/packages/ui-react/src/components/Dialog/__snapshots__/Dialog.test.tsx.snap @@ -35,11 +35,10 @@ exports[` > renders and matches snapshot 1`] = ` role="dialog" > Dialog contents -
-
+ diff --git a/packages/ui-react/src/components/DialogBackButton/__snapshots__/DialogBackButton.test.tsx.snap b/packages/ui-react/src/components/DialogBackButton/__snapshots__/DialogBackButton.test.tsx.snap index 99e39c033..3b86f0b8b 100644 --- a/packages/ui-react/src/components/DialogBackButton/__snapshots__/DialogBackButton.test.tsx.snap +++ b/packages/ui-react/src/components/DialogBackButton/__snapshots__/DialogBackButton.test.tsx.snap @@ -2,11 +2,10 @@ exports[` > renders and matches snapshot 1`] = `
-
-
+
`; diff --git a/packages/ui-react/src/components/EditPasswordForm/EditPasswordForm.tsx b/packages/ui-react/src/components/EditPasswordForm/EditPasswordForm.tsx index 5aa41f030..8413310ac 100644 --- a/packages/ui-react/src/components/EditPasswordForm/EditPasswordForm.tsx +++ b/packages/ui-react/src/components/EditPasswordForm/EditPasswordForm.tsx @@ -43,7 +43,7 @@ const EditPasswordForm: React.FC = ({ }: Props) => { const { t } = useTranslation(['account', 'user']); return ( -
+ {errors.form && ( {errors.form} @@ -69,6 +69,7 @@ const EditPasswordForm: React.FC = ({ name="oldPassword" showToggleView={false} showHelperText={false} + autoComplete="current-password" required /> )} @@ -95,6 +96,7 @@ const EditPasswordForm: React.FC = ({ placeholder={t('reset.password')} error={!!errors.password} name="password" + autoComplete="new-password" required /> @@ -106,6 +108,7 @@ const EditPasswordForm: React.FC = ({ placeholder={t('reset.repeat_new_password')} error={!!errors.passwordConfirmation} name="passwordConfirmation" + autoComplete="new-password" required /> diff --git a/packages/ui-react/src/components/EditPasswordForm/__snapshots__/EditPasswordForm.test.tsx.snap b/packages/ui-react/src/components/EditPasswordForm/__snapshots__/EditPasswordForm.test.tsx.snap index 6158f4261..6588c0191 100644 --- a/packages/ui-react/src/components/EditPasswordForm/__snapshots__/EditPasswordForm.test.tsx.snap +++ b/packages/ui-react/src/components/EditPasswordForm/__snapshots__/EditPasswordForm.test.tsx.snap @@ -26,6 +26,7 @@ exports[` > renders and matches snapshot 1`] = ` > renders and matches snapshot 1`] = `
-
-
+
> renders and matches snapshot 1`] = ` > renders and matches snapshot 1`] = `
-
-
+
{alt} -

{title || 'An error occurred'}

+

+ {title || 'An error occurred'} +

{message || 'Try refreshing this page or come back later.'}

{children} diff --git a/packages/ui-react/src/components/ErrorPage/__snapshots__/ErrorPage.test.tsx.snap b/packages/ui-react/src/components/ErrorPage/__snapshots__/ErrorPage.test.tsx.snap index 7dea1eabe..018946364 100644 --- a/packages/ui-react/src/components/ErrorPage/__snapshots__/ErrorPage.test.tsx.snap +++ b/packages/ui-react/src/components/ErrorPage/__snapshots__/ErrorPage.test.tsx.snap @@ -14,6 +14,7 @@ exports[` > renders and matches snapshot 1`] = ` src="/images/logo.png" />

This is the title diff --git a/packages/ui-react/src/components/Form/FormSection.tsx b/packages/ui-react/src/components/Form/FormSection.tsx index eb4daf399..bd6737589 100644 --- a/packages/ui-react/src/components/Form/FormSection.tsx +++ b/packages/ui-react/src/components/Form/FormSection.tsx @@ -94,7 +94,7 @@ export function FormSection({ try { setFormState((s) => { - return { ...s, isBusy: true }; + return { ...s, isBusy: true, errors: [] }; }); response = await onSubmit(values); } catch (error: unknown) { diff --git a/packages/ui-react/src/components/Header/Header.module.scss b/packages/ui-react/src/components/Header/Header.module.scss index eb66f4de2..18c5d00cc 100644 --- a/packages/ui-react/src/components/Header/Header.module.scss +++ b/packages/ui-react/src/components/Header/Header.module.scss @@ -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; @@ -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 // -------------------------------- diff --git a/packages/ui-react/src/components/Header/Header.test.tsx b/packages/ui-react/src/components/Header/Header.test.tsx index 2cd961f57..138c85367 100644 --- a/packages/ui-react/src/components/Header/Header.test.tsx +++ b/packages/ui-react/src/components/Header/Header.test.tsx @@ -19,7 +19,7 @@ describe('
', () => { }); test('renders header', () => { - const playlistMenuItems = [

+`; + +exports[`
> renders header with nav buttons 1`] = ` +
+
+
+ + skip_to_content + +
+ +
+ +
+
diff --git a/packages/ui-react/src/components/IconButton/IconButton.tsx b/packages/ui-react/src/components/IconButton/IconButton.tsx index fa5d6b8e4..c03f9c622 100644 --- a/packages/ui-react/src/components/IconButton/IconButton.tsx +++ b/packages/ui-react/src/components/IconButton/IconButton.tsx @@ -1,33 +1,20 @@ import classNames from 'classnames'; -import React, { type AriaAttributes } from 'react'; +import React, { type ButtonHTMLAttributes } from 'react'; import styles from './IconButton.module.scss'; -type Props = AriaAttributes & { +type Props = ButtonHTMLAttributes & { onClick?: () => void; onBlur?: () => void; children: JSX.Element; - tabIndex?: number; className?: string; }; -const IconButton: React.FC = ({ children, onClick, tabIndex = 0, className, ...ariaProps }: Props) => { +const IconButton: React.FC = ({ children, onClick, className, ...ariaProps }: Props) => { return ( -
{ - if ((event.key === 'Enter' || event.key === ' ') && tabIndex >= 0 && onClick) { - onClick(); - event.preventDefault(); // prevent click being called when this component unmounts - } - }} - {...ariaProps} - > +
+ ); }; diff --git a/packages/ui-react/src/components/IconButton/__snapshots__/IconButton.test.tsx.snap b/packages/ui-react/src/components/IconButton/__snapshots__/IconButton.test.tsx.snap index 29886da80..fe9e53ede 100644 --- a/packages/ui-react/src/components/IconButton/__snapshots__/IconButton.test.tsx.snap +++ b/packages/ui-react/src/components/IconButton/__snapshots__/IconButton.test.tsx.snap @@ -2,11 +2,10 @@ exports[` > renders and matches snapshot 1`] = `
-
> renders and matches snapshot 1`] = ` fill="none" /> -
+
`; diff --git a/packages/ui-react/src/components/LanguageMenu/LanguageMenu.tsx b/packages/ui-react/src/components/LanguageMenu/LanguageMenu.tsx index 2a11f724a..8463b9df1 100644 --- a/packages/ui-react/src/components/LanguageMenu/LanguageMenu.tsx +++ b/packages/ui-react/src/components/LanguageMenu/LanguageMenu.tsx @@ -48,14 +48,14 @@ const LanguageMenu = ({ onClick, className, languages, currentLanguage, language aria-controls="language-panel" aria-expanded={languageMenuOpen} aria-haspopup="menu" - className={classNames(styles.iconButton, className)} + className={classNames(className)} aria-label={t('language_menu')} onClick={handleMenuToggle} onBlur={closeLanguageMenu} >
- +
    {languages.map(({ code, displayName }) => { diff --git a/packages/ui-react/src/components/LanguageMenu/__snapshots__/LanguageMenu.test.tsx.snap b/packages/ui-react/src/components/LanguageMenu/__snapshots__/LanguageMenu.test.tsx.snap index e098530c3..5d55ddd6a 100644 --- a/packages/ui-react/src/components/LanguageMenu/__snapshots__/LanguageMenu.test.tsx.snap +++ b/packages/ui-react/src/components/LanguageMenu/__snapshots__/LanguageMenu.test.tsx.snap @@ -2,15 +2,14 @@ exports[` > renders and matches snapshot 1`] = `
    - +
    `; diff --git a/packages/ui-react/src/components/LoginForm/__snapshots__/LoginForm.test.tsx.snap b/packages/ui-react/src/components/LoginForm/__snapshots__/LoginForm.test.tsx.snap index ccb3a2978..0628874b0 100644 --- a/packages/ui-react/src/components/LoginForm/__snapshots__/LoginForm.test.tsx.snap +++ b/packages/ui-react/src/components/LoginForm/__snapshots__/LoginForm.test.tsx.snap @@ -85,12 +85,11 @@ exports[` > renders and matches snapshot 1`] = `
    -
    -
    +
diff --git a/packages/ui-react/src/components/Logo/Logo.tsx b/packages/ui-react/src/components/Logo/Logo.tsx index a6eef375c..77b88bdb9 100644 --- a/packages/ui-react/src/components/Logo/Logo.tsx +++ b/packages/ui-react/src/components/Logo/Logo.tsx @@ -5,6 +5,7 @@ import styles from './Logo.module.scss'; type Props = { src: string; + alt?: string; onLoad: () => void; }; @@ -13,7 +14,7 @@ type ImgRef = { width?: number; }; -const Logo: React.FC = ({ src, onLoad }: Props) => { +const Logo: React.FC = ({ src, alt = 'logo', onLoad }: Props) => { const [imgDimensions, updateImgDimensions] = useState({ height: undefined, width: undefined }); const onLoadHandler = (event: React.SyntheticEvent) => { @@ -24,7 +25,7 @@ const Logo: React.FC = ({ src, onLoad }: Props) => { return ( - logo + {alt} ); }; diff --git a/packages/ui-react/src/components/ModalCloseButton/__snapshots__/ModalCloseButton.test.tsx.snap b/packages/ui-react/src/components/ModalCloseButton/__snapshots__/ModalCloseButton.test.tsx.snap index 587364f04..6211ad3ab 100644 --- a/packages/ui-react/src/components/ModalCloseButton/__snapshots__/ModalCloseButton.test.tsx.snap +++ b/packages/ui-react/src/components/ModalCloseButton/__snapshots__/ModalCloseButton.test.tsx.snap @@ -2,11 +2,10 @@ exports[` > renders and matches snapshot 1`] = `
-
-
+
`; diff --git a/packages/ui-react/src/components/PasswordField/PasswordField.tsx b/packages/ui-react/src/components/PasswordField/PasswordField.tsx index 0a430ee44..a4eceecd3 100644 --- a/packages/ui-react/src/components/PasswordField/PasswordField.tsx +++ b/packages/ui-react/src/components/PasswordField/PasswordField.tsx @@ -9,7 +9,7 @@ import PasswordStrength from '../PasswordStrength/PasswordStrength'; import IconButton from '../IconButton/IconButton'; import Icon from '../Icon/Icon'; -type Props = { +type Props = React.InputHTMLAttributes & { onChange?: React.ChangeEventHandler; onBlur?: React.FocusEventHandler; error?: boolean; diff --git a/packages/ui-react/src/components/PasswordField/__snapshots__/PasswordField.test.tsx.snap b/packages/ui-react/src/components/PasswordField/__snapshots__/PasswordField.test.tsx.snap index 0bc26227d..52ffd8085 100644 --- a/packages/ui-react/src/components/PasswordField/__snapshots__/PasswordField.test.tsx.snap +++ b/packages/ui-react/src/components/PasswordField/__snapshots__/PasswordField.test.tsx.snap @@ -28,12 +28,11 @@ exports[` > renders and matches snapshot 1`] = `
-
-
+
{ /**/ }; -const values = { +const initialValues = { firstName: 'Vince', lastName: 'Guy', birthDate: '27-Feb-1985', @@ -86,12 +86,8 @@ describe('', () => { test('Renders without crashing', () => { const { container } = render( ', () => { test('Renders with errors', () => { const { container } = render( ; - onChange: React.ChangeEventHandler; - setValue: (key: keyof PersonalDetailsFormData, value: string) => void; + initialValues: PersonalDetailsFormData; + onSubmit: UseFormOnSubmitHandler; error?: string; - errors: FormErrors; - validationError?: boolean; - values: PersonalDetailsFormData; - submitting: boolean; fields: Record; questions: CleengCaptureQuestionField[]; onQuestionChange: React.ChangeEventHandler; @@ -31,21 +26,14 @@ type Props = { questionErrors: Record; }; -const PersonalDetailsForm: React.FC = ({ - onSubmit, - onChange, - setValue, - validationError, - values, - errors, - submitting, - fields, - questions, - onQuestionChange, - questionValues, - questionErrors, -}: Props) => { +const PersonalDetailsForm: React.FC = ({ initialValues, onSubmit, fields, questions, onQuestionChange, questionValues, questionErrors }: Props) => { const { t } = useTranslation('account'); + + const { setValue, handleSubmit, handleChange, values, errors, validationSchemaError, submitting } = useForm({ + initialValues, + onSubmit, + }); + const renderQuestion = ({ value, key, question, required, enabled }: CleengCaptureQuestionField) => { if (!enabled) { return null; @@ -86,10 +74,10 @@ const PersonalDetailsForm: React.FC = ({ }; return ( - +

{t('personal_details.title')}

{errors.form ? ( - + {errors.form} ) : null} @@ -97,7 +85,7 @@ const PersonalDetailsForm: React.FC = ({ = ({ /> = ({ {fields.companyName?.enabled ? ( = ({ = ({ /> = ({ /> = ({ /> = ({ /> = ({ {fields.phoneNumber?.enabled ? ( > Renders with errors 1`] = ` personal_details.title
- This is a form error -
-
-
- this is wrong -
-
- also this -
-
- So much errors -
-
- Do you know where you live -
-
- Come on -
-
- stop it -
-
- Confusion -
-
- Post Code should be 5 centimeters -
-
- Invalid -
-
- February 30th? Really? -
({ + default: (props: { href: string }) => { + return Social Button; + }, +})); + +const socialLoginURLs = { + twitter: 'https://staging-v2.inplayer.com/', + facebook: 'https://www.facebook.com/', + google: 'https://accounts.google.com/', +}; + describe('', () => { - test('renders and matches snapshot', () => { + test('renders and matches snapshot', async () => { const { container } = renderWithRouter( ', () => { consentValues={{}} loading={false} onConsentChange={vi.fn()} + socialLoginURLs={socialLoginURLs} />, ); + await waitForWithFakeTimers(); + expect(container).toMatchSnapshot(); }); }); diff --git a/packages/ui-react/src/components/RegistrationForm/RegistrationForm.tsx b/packages/ui-react/src/components/RegistrationForm/RegistrationForm.tsx index 1f56b636d..85c6d943f 100644 --- a/packages/ui-react/src/components/RegistrationForm/RegistrationForm.tsx +++ b/packages/ui-react/src/components/RegistrationForm/RegistrationForm.tsx @@ -5,6 +5,7 @@ import DOMPurify from 'dompurify'; import type { FormErrors } from '@jwp/ott-common/types/form'; import type { CustomFormField, RegistrationFormData } from '@jwp/ott-common/types/account'; import { testId } from '@jwp/ott-common/src/utils/common'; +import type { SocialLoginURLs } from '@jwp/ott-hooks-react/src/useSocialLoginUrls'; import useToggle from '@jwp/ott-hooks-react/src/useToggle'; import Visibility from '@jwp/ott-theme/assets/icons/visibility.svg?react'; import VisibilityOff from '@jwp/ott-theme/assets/icons/visibility_off.svg?react'; @@ -20,6 +21,7 @@ import LoadingOverlay from '../LoadingOverlay/LoadingOverlay'; import Link from '../Link/Link'; import Icon from '../Icon/Icon'; import { modalURLFromLocation } from '../../utils/location'; +import SocialButtonsList from '../SocialButtonsList/SocialButtonsList'; import styles from './RegistrationForm.module.scss'; @@ -36,6 +38,7 @@ type Props = { submitting: boolean; validationError?: boolean; publisherConsents: CustomFormField[] | null; + socialLoginURLs: SocialLoginURLs | null; }; const RegistrationForm: React.FC = ({ @@ -51,6 +54,7 @@ const RegistrationForm: React.FC = ({ consentValues, onConsentChange, consentErrors, + socialLoginURLs, }: Props) => { const [viewPassword, toggleViewPassword] = useToggle(); @@ -80,7 +84,6 @@ const RegistrationForm: React.FC = ({ return ( -

{t('registration.sign_up')}

{errors.form ? ( @@ -88,6 +91,8 @@ const RegistrationForm: React.FC = ({ ) : null}
+ +

{t('registration.sign_up')}

> renders and matches snapshot 1`] = ` data-testid="registration-form" novalidate="" > +
+

registration.sign_up

-
@@ -65,12 +84,11 @@ exports[` > renders and matches snapshot 1`] = `
-
-
+
> renders and matches snapshot 1`] = ` type="search" value="My search query" /> -
-
+
diff --git a/packages/ui-react/src/components/Sidebar/__snapshots__/Sidebar.test.tsx.snap b/packages/ui-react/src/components/Sidebar/__snapshots__/Sidebar.test.tsx.snap index 33b7ab28a..d63f367da 100644 --- a/packages/ui-react/src/components/Sidebar/__snapshots__/Sidebar.test.tsx.snap +++ b/packages/ui-react/src/components/Sidebar/__snapshots__/Sidebar.test.tsx.snap @@ -13,11 +13,10 @@ exports[` > renders sideBar closed 1`] = `
-
> renders sideBar closed 1`] = ` fill="none" /> -
+