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

Release Candidate - v7.0.0 #481

Closed
wants to merge 10 commits into from
70 changes: 70 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,73 @@
## [7.0.0](https://github.com/jwplayer/ott-web-app/compare/v5.1.1...v7.0.0) (2024-04-03)


### ⚠ BREAKING CHANGES

* **project:** restructure for multiplatforms with workspaces (#435)

### Features

* **a11y:** many accessibility optimisations ([cc02259](https://github.com/jwplayer/ott-web-app/commit/cc02259ddb8faeed27813ddce850b5653fe1d0d3)), closes [#48](https://github.com/jwplayer/ott-web-app/issues/48) [#47](https://github.com/jwplayer/ott-web-app/issues/47) [#46](https://github.com/jwplayer/ott-web-app/issues/46)
* **a11y:** update font colors for contrast and adjust active state in header ([#76](https://github.com/jwplayer/ott-web-app/issues/76)) ([6444282](https://github.com/jwplayer/ott-web-app/commit/6444282c6c2adedb93980904ba968c8d5bf2680d))
* accessibility improvements and bug fixes ([82b5967](https://github.com/jwplayer/ott-web-app/commit/82b5967dcf9415aba21e8f6c7bdaabd57f1589af)), closes [#127](https://github.com/jwplayer/ott-web-app/issues/127) [#109](https://github.com/jwplayer/ott-web-app/issues/109) [#115](https://github.com/jwplayer/ott-web-app/issues/115) [#117](https://github.com/jwplayer/ott-web-app/issues/117) [#116](https://github.com/jwplayer/ott-web-app/issues/116) [#121](https://github.com/jwplayer/ott-web-app/issues/121) [#125](https://github.com/jwplayer/ott-web-app/issues/125)
* **payment:** disable deprecated receipts cleeng ([#458](https://github.com/jwplayer/ott-web-app/issues/458)) ([d37905d](https://github.com/jwplayer/ott-web-app/commit/d37905df4022103e3fdf62ad936d58af6e12617c))
* **project:** add app content search ([71433ab](https://github.com/jwplayer/ott-web-app/commit/71433abfca80431243effc246afdbe8c6901521e))
* **project:** customizable footer through env-var ([9d8ff15](https://github.com/jwplayer/ott-web-app/commit/9d8ff150dc298880bd4cdc1323a4fc68f8d0fcba))
* **project:** dynamic gtm snippet ([6babace](https://github.com/jwplayer/ott-web-app/commit/6babacefc3ae56191625207436fc6faaaca10445))
* **project:** favicons in different sizes ([a1c6188](https://github.com/jwplayer/ott-web-app/commit/a1c6188ae0e6b634977d9ac0642bad437a31df3b))
* **project:** reload site on update ([d4c851b](https://github.com/jwplayer/ott-web-app/commit/d4c851bdccc155b4953c9948ffdab86c2bfacc5e))
* **project:** restructure for multiplatforms with workspaces ([#435](https://github.com/jwplayer/ott-web-app/issues/435)) ([3e3e2b1](https://github.com/jwplayer/ott-web-app/commit/3e3e2b14c4926e596fad46c2ea7cc99dbced05f0)), closes [#8](https://github.com/jwplayer/ott-web-app/issues/8)
* **project:** update default content-type schemas ([0a9817a](https://github.com/jwplayer/ott-web-app/commit/0a9817a9b6f5bbfaae5ce5967bbf3c16436d2f15))
* **project:** update translations ([a34f686](https://github.com/jwplayer/ott-web-app/commit/a34f6863480b075d82c80a062833899fd26bbdc5))
* underline for active header item and add lineair gradient ([1d2f25f](https://github.com/jwplayer/ott-web-app/commit/1d2f25f04dc06463a0a37aa4c6fddabab455cdcf))
* **watchhistory:** change max items limit ([#418](https://github.com/jwplayer/ott-web-app/issues/418)) ([d7db57a](https://github.com/jwplayer/ott-web-app/commit/d7db57ab330630c270412ca8fa39ea94052d7675))


### Bug Fixes

* **a11y:** close search bar when pressing escape ([7a14497](https://github.com/jwplayer/ott-web-app/commit/7a14497224bc8d159bda1ac3238cc0eb566b5437))
* **a11y:** constrast enhancement for search field ([b4c3230](https://github.com/jwplayer/ott-web-app/commit/b4c323026bc713519fcd6e1ac8efbb68dc8f8fff))
* **a11y:** focus lost when submitting a form ([9001a21](https://github.com/jwplayer/ott-web-app/commit/9001a21c9a4b0bd35db6c182e2f46b4480983dc8))
* **a11y:** format date call caused an error to be raised ([aef1415](https://github.com/jwplayer/ott-web-app/commit/aef1415229901704af0e15b57fd3a0d42040cbe7))
* **a11y:** prevent duplicate global a11y selectors ([b3ccaff](https://github.com/jwplayer/ott-web-app/commit/b3ccaffe4ea1249d7ad5a80cfe6e8e20a94ef3b7))
* **a11y:** remove outline when user is not tabbing ([5fe1665](https://github.com/jwplayer/ott-web-app/commit/5fe1665ad30e08dd7eed234c93243da7df748cce))
* **a11y:** shelf item navigation with screen reader ([91dc66c](https://github.com/jwplayer/ott-web-app/commit/91dc66cd6b6bdbae3b48c0454fe1da335acc9f91))
* **account:** delete account error ([a2885eb](https://github.com/jwplayer/ott-web-app/commit/a2885eb34598b413e4b81f9cdbb542bbbd849a64))
* **auth:** capture error to prevent misleading “wrong combination” error ([588f69a](https://github.com/jwplayer/ott-web-app/commit/588f69ac9034736ddf7804bbebaddb141fe30860))
* click not working in layout grid ([2ded57b](https://github.com/jwplayer/ott-web-app/commit/2ded57b41bbac7a08f5c1d0eeccb149fdcde3242))
* e2e test optimisations and small fixes ([b700fbb](https://github.com/jwplayer/ott-web-app/commit/b700fbb7ea31cde67740bab99246a0b705058c55))
* e2e tests for a11y ([c4d09c5](https://github.com/jwplayer/ott-web-app/commit/c4d09c52494b20e0d8e31fb4595f898729817255))
* enter key not closing the account modal ([1791b4c](https://github.com/jwplayer/ott-web-app/commit/1791b4ca91e161250e354ae96e1d32f0b7bf30c9))
* favorites and history validation error ([3deabfc](https://github.com/jwplayer/ott-web-app/commit/3deabfc766a75c12ab122a775376449e316ff232))
* footer overlap fix ([bf79d10](https://github.com/jwplayer/ott-web-app/commit/bf79d108356418c80cfe7a9ddc2496977ae9bb17))
* hide start watching button in avod platform ([86b461f](https://github.com/jwplayer/ott-web-app/commit/86b461fc9df4b92401055b8c56d8e9d5aec13c99))
* **i18n:** add missing translations ([961bcd1](https://github.com/jwplayer/ott-web-app/commit/961bcd140b68c2eb8e128b898c23caa8ddcfd744))
* language menu icon not centered ([ddcfc91](https://github.com/jwplayer/ott-web-app/commit/ddcfc91973548d6cdacc084dd6b88bb3453c6d36))
* layout grid arrow down and end problem ([6a291a7](https://github.com/jwplayer/ott-web-app/commit/6a291a77f51626c46c082f268f454ff00cde9310))
* layout grid home and page down problem ([a6305ef](https://github.com/jwplayer/ott-web-app/commit/a6305efbe94b0261786a2adcb76a6530aff3e4cc))
* logo and header layout issues ([a0cca10](https://github.com/jwplayer/ott-web-app/commit/a0cca10419b9a74b4761d5701e242db2c4e8d562))
* **menu:** ensure logo does not exceed width of the header ([ea4af42](https://github.com/jwplayer/ott-web-app/commit/ea4af42e23ddefce292a0784c8a0db9b98e4895d))
* **payment:** incorrect couponCode success message ([c97c59b](https://github.com/jwplayer/ott-web-app/commit/c97c59b7268d540ee37cdb0bb41beb72d8946a7e))
* **payment:** missing feedback when submitting coupon ([5097e60](https://github.com/jwplayer/ott-web-app/commit/5097e607090bcdf098335dd39a6aa6ef82250ad7))
* **payment:** redirect after incorrect couponcode entry ([ca71f29](https://github.com/jwplayer/ott-web-app/commit/ca71f29298ea6c4af2f5c2b6c4f6379d68385df0))
* **payment:** subscription offer panel shown for authvod+tvod ([d63b056](https://github.com/jwplayer/ott-web-app/commit/d63b0562e74c624bae0690048467442595928fe2))
* **payment:** tvod offer not showing in AuthVOD platform ([d01d1b7](https://github.com/jwplayer/ott-web-app/commit/d01d1b71aba628feeb4510cb9b0b9d4132af3cb7))
* personal shelves restoration ([2741eac](https://github.com/jwplayer/ott-web-app/commit/2741eac5331657ed6156a9e5fba1906c8623227b))
* **player:** inlineplayer not supporting tvod ([bb593e9](https://github.com/jwplayer/ott-web-app/commit/bb593e97ce2635d9c33c1d027da51075509a7462))
* **project:** ensure modals obscure underlying elements ([f52a0f3](https://github.com/jwplayer/ott-web-app/commit/f52a0f3377ed1c0d22e47f27995c597d7ec71e55))
* **project:** fix es translations ([b80ab06](https://github.com/jwplayer/ott-web-app/commit/b80ab0682fbde1c9f85f7ddacfbf22b433a38cfb))
* **project:** fix live stream duration check for ott plugin ([#460](https://github.com/jwplayer/ott-web-app/issues/460)) ([69eff3c](https://github.com/jwplayer/ott-web-app/commit/69eff3c1e9763d2b80e1669809323ee9c1de5f63))
* **project:** show footer when custom footer is provided ([6503267](https://github.com/jwplayer/ott-web-app/commit/65032674e0ca75e129e5d6fca35e54fc6b690f3d))
* **project:** undouble serieIds to prevent crash ([ca3d38e](https://github.com/jwplayer/ott-web-app/commit/ca3d38e2ad82235a84cb658da0174095c2eed10e))
* **project:** unused dep ([72325a6](https://github.com/jwplayer/ott-web-app/commit/72325a63d43ca19f43b9ac1d76a024037889aab0))
* related videos title layout issue ([361c58a](https://github.com/jwplayer/ott-web-app/commit/361c58a53cb6ae56b84cb6751c7b4ad3d64c702b))
* restore personal shelves after registration ([3fdb220](https://github.com/jwplayer/ott-web-app/commit/3fdb220ef988383e6af80b72efb7c7d27e6bccb7))
* root error screen for unexpected errors ([320fe44](https://github.com/jwplayer/ott-web-app/commit/320fe4402f7338816825471de52c21aedb95a144))
* set wrong loading state in early return ([0837944](https://github.com/jwplayer/ott-web-app/commit/0837944dc4d022ecfe95d6e3f30959d943be9e99))
* update order error handling ([bf3e5b5](https://github.com/jwplayer/ott-web-app/commit/bf3e5b575624580a38301968a63023748bd9a6df))
* **user:** redirect when no integration is configured ([88ce77c](https://github.com/jwplayer/ott-web-app/commit/88ce77c587883117eb6af4dec40481ddcbfe01b2))
* **user:** tvod subscription not reloaded after login for authvod/avod ([7de84ae](https://github.com/jwplayer/ott-web-app/commit/7de84ae37f174c04bdea26af1818721dfe9956d8))

## [6.0.0](https://github.com/jwplayer/ott-web-app/compare/v5.1.1...v6.0.0) (2024-03-25)


Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@jwp/ott",
"version": "6.0.0",
"version": "7.0.0",
"private": true,
"license": "Apache-2.0",
"repository": "https://github.com/jwplayer/ott-web-app.git",
Expand Down
32 changes: 11 additions & 21 deletions packages/common/src/controllers/CheckoutController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,32 +91,22 @@ export default class CheckoutController {
};

updateOrder = async (order: Order, paymentMethodId?: number, couponCode?: string | null): Promise<void> => {
let response;

try {
response = await this.checkoutService.updateOrder({ order, paymentMethodId, couponCode });
} catch (error: unknown) {
// TODO: we currently (falsely) assume that the only error caught is because the coupon is not valid, but there
// could be a network failure as well (JWPCheckoutService)
throw new FormValidationError({ couponCode: [i18next.t('account:checkout.coupon_not_valid')] });
}
const response = await this.checkoutService.updateOrder({ order, paymentMethodId, couponCode });

if (response.errors.length > 0) {
// clear the order when the order doesn't exist on the server
if (response.errors[0].includes(`Order with ${order.id} not found`)) {
useCheckoutStore.getState().setOrder(null);
if (response.responseData.order) {
useCheckoutStore.getState().setOrder(response.responseData?.order);
}

// TODO: this handles the `Coupon ${couponCode} not found` message (CleengCheckoutService)
if (response.errors[0].includes(`not found`)) {
throw new FormValidationError({ couponCode: [i18next.t('account:checkout.coupon_not_valid')] });
} catch (error: unknown) {
if (error instanceof Error) {
if (error.message === 'Order not found') {
useCheckoutStore.getState().setOrder(null);
} else if (error.message === 'Invalid coupon code') {
throw new FormValidationError({ couponCode: [i18next.t('account:checkout.coupon_not_valid')] });
}
}

throw new FormValidationError({ form: response.errors });
}

if (response.responseData.order) {
useCheckoutStore.getState().setOrder(response.responseData?.order);
throw new FormValidationError({ form: [i18next.t('error:unknown_error')] });
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ import type {
PaymentWithPayPal,
SwitchSubscription,
UpdateOrder,
UpdateOrderResponse,
UpdatePaymentWithPayPal,
} from '../../../../types/checkout';
import CheckoutService from '../CheckoutService';
import { GET_CUSTOMER_IP } from '../../../modules/types';
import type { GetCustomerIP } from '../../../../types/get-customer-ip';
import type { ServiceResponse } from '../../../../types/service';

import CleengService from './CleengService';

Expand Down Expand Up @@ -83,7 +85,21 @@ export default class CleengCheckoutService extends CheckoutService {
};

updateOrder: UpdateOrder = async ({ order, ...payload }) => {
return this.cleengService.patch(`/orders/${order.id}`, JSON.stringify(payload), { authenticate: true });
const response = await this.cleengService.patch<ServiceResponse<UpdateOrderResponse>>(`/orders/${order.id}`, JSON.stringify(payload), {
authenticate: true,
});

if (response.errors.length) {
if (response.errors[0].includes(`Order with ${order.id} not found`)) {
throw new Error('Order not found');
}

if (response.errors[0].includes(`Coupon ${payload.couponCode} not found`)) {
throw new Error('Invalid coupon code');
}
}

return response;
};

getPaymentMethods: GetPaymentMethods = async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ export default class CleengService {
return await resp.json();
} catch (error: unknown) {
return {
errors: Array.of(error as string),
errors: Array.of(error instanceof Error ? error.message : String(error)),
};
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import type {
} from '../../../../types/checkout';
import CheckoutService from '../CheckoutService';
import type { ServiceResponse } from '../../../../types/service';
import { isCommonError } from '../../../utils/api';

@injectable()
export default class JWPCheckoutService extends CheckoutService {
Expand Down Expand Up @@ -71,6 +72,7 @@ export default class JWPCheckoutService extends CheckoutService {
totalPrice: payload.offer.customerPriceInclTax,
priceBreakdown: {
offerPrice: payload.offer.customerPriceInclTax,
// @TODO is this correct?
discountAmount: payload.offer.customerPriceInclTax,
discountedPrice: payload.offer.customerPriceInclTax,
paymentMethodFee: 0,
Expand Down Expand Up @@ -179,26 +181,37 @@ export default class JWPCheckoutService extends CheckoutService {
voucherCode: `${couponCode}`,
accessFeeId: order.id,
});
order.discount = {
applied: true,
type: 'coupon',
periods: response.data.discount_duration,

const discountAmount = order.totalPrice - response.data.amount;
const updatedOrder: Order = {
...order,
totalPrice: response.data.amount,
priceBreakdown: {
...order.priceBreakdown,
discountAmount,
discountedPrice: discountAmount,
},
discount: {
applied: true,
type: 'coupon',
periods: response.data.discount_duration,
},
};

const discountedAmount = order.totalPrice - response.data.amount;
order.totalPrice = response.data.amount;
order.priceBreakdown.discountAmount = discountedAmount;
order.priceBreakdown.discountedPrice = discountedAmount;
return {
errors: [],
responseData: {
message: 'successfully updated',
order: order,
order: updatedOrder,
success: true,
},
};
} catch {
throw new Error('Invalid coupon code');
} catch (error: unknown) {
if (isCommonError(error) && error.response.data.message === 'Voucher not found') {
throw new Error('Invalid coupon code');
}

throw new Error('An unknown error occurred');
}
};

Expand Down
2 changes: 1 addition & 1 deletion packages/common/src/stores/AccountStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type AccountStore = {
};

export const useAccountStore = createStore<AccountStore>('AccountStore', (set, get) => ({
loading: true,
loading: false,
user: null,
subscription: null,
transactions: null,
Expand Down
2 changes: 1 addition & 1 deletion packages/ui-react/src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ const Button: React.FC<Props> = ({
}

return (
<button className={buttonClassName(active)} onClick={onClick} type={type} disabled={disabled} aria-disabled={disabled} {...rest}>
<button className={buttonClassName(active)} onClick={disabled ? undefined : onClick} type={type} aria-disabled={disabled} {...rest}>
{content}
</button>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type Props = {
onCouponInputChange: React.ChangeEventHandler<HTMLInputElement>;
onRedeemCouponButtonClick: () => void;
onCloseCouponFormClick: () => void;
error?: string;
couponFormOpen: boolean;
couponFormError?: string;
couponFormApplied?: boolean;
Expand All @@ -45,6 +46,7 @@ const CheckoutForm: React.FC<Props> = ({
offerType,
onBackButtonClick,
onPaymentMethodChange,
error,
couponFormOpen,
couponInputValue,
couponFormError,
Expand Down Expand Up @@ -89,6 +91,7 @@ const CheckoutForm: React.FC<Props> = ({
const orderTitle = offerType === 'svod' ? (offer.period === 'month' ? t('checkout.monthly') : t('checkout.yearly')) : offer.offerTitle;
return (
<div>
{error ? <FormFeedback variant="error">{error}</FormFeedback> : null}
<h1 className={styles.title}>{t('checkout.payment_method')}</h1>
<div className={styles.order}>
<div className={styles.orderInfo}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ describe('<LoginForm>', () => {

await waitForWithFakeTimers();

expect(getByRole('button', { name: 'login.sign_in' })).toBeDisabled();
expect(getByRole('button', { name: 'login.sign_in' })).toHaveAttribute('aria-disabled', 'true');
});

test('calls the onSubmit callback when the form gets submitted', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ const Checkout = () => {
handleSubmit,
} = useForm({
initialValues: { couponCode: '', paymentMethodId: paymentMethods?.[0]?.id?.toString() || '' },
onSubmit: async ({ couponCode, paymentMethodId }) => {
onSubmit: ({ couponCode, paymentMethodId }) => {
setShowCouponCodeSuccess(false);

return await updateOrder.mutateAsync({ couponCode, paymentMethodId: parseInt(paymentMethodId) });
return updateOrder.mutateAsync({ couponCode, paymentMethodId: parseInt(paymentMethodId) });
},
onSubmitSuccess: ({ couponCode }): void => setShowCouponCodeSuccess(!!couponCode),
onSubmitError: ({ error }) => {
Expand Down Expand Up @@ -117,6 +117,7 @@ const Checkout = () => {
order={order}
offer={selectedOffer}
offerType={offerType}
error={errors.form}
onBackButtonClick={backButtonClickHandler}
paymentMethods={paymentMethods}
paymentMethodId={paymentMethodId}
Expand Down
2 changes: 1 addition & 1 deletion platforms/web/public/locales/en/account.json
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@
"password_helper_text": "Use a minimum of 8 characters (case sensitive) with at least one number",
"password_strength": {
"fair": "Fair",
"invalid": "Invalid",
"invalid": "",
"strong": "Strong",
"very_strong": "Very strong",
"weak": "Weak"
Expand Down
Loading
Loading