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

Integrate with discount api #1276

Merged
merged 18 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 0 additions & 36 deletions client/__tests__/saveEligibilityCheck.test.ts

This file was deleted.

22 changes: 11 additions & 11 deletions client/components/mma/MMAPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
import { Maintenance } from './maintenance/Maintenance';
import { MMAPageSkeleton } from './MMAPageSkeleton';

const record = (event: any) => {

Check warning on line 39 in client/components/mma/MMAPage.tsx

View workflow job for this annotation

GitHub Actions / manage-frontend build

Unexpected any. Specify a different type
if (window.guardian?.ophan?.record) {
window.guardian.ophan.record(event);
}
Expand Down Expand Up @@ -182,17 +182,17 @@

const DigiSubThankYouOffer = lazy(() =>
import(
/* webpackChunkName: "Cancellation" */ './cancel/cancellationSaves/digipack/ThankYouOffer'
).then(({ ThankYouOffer: ThankYouOffer }) => ({
default: ThankYouOffer,
/* webpackChunkName: "Cancellation" */ './cancel/cancellationSaves/digipack/DigiSubThankYouOffer'
).then(({ DigiSubThankYouOffer: DigiSubThankYouOffer }) => ({
default: DigiSubThankYouOffer,
})),
);

const ConfirmDigiSubDiscount = lazy(() =>
const DigiSubDiscountConfirmed = lazy(() =>
import(
/* webpackChunkName: "Cancellation" */ './cancel/cancellationSaves/digipack/DigiSubDiscountConfirm'
).then(({ DigiSubDiscountConfirm: DigiSubDiscountConfirm }) => ({
default: DigiSubDiscountConfirm,
/* webpackChunkName: "Cancellation" */ './cancel/cancellationSaves/digipack/DigiSubDiscountConfirmed'
).then(({ DigiSubDiscountConfirmed: DigiSubDiscountConfirmed }) => ({
default: DigiSubDiscountConfirmed,
})),
);

Expand Down Expand Up @@ -707,14 +707,14 @@
path="confirm-cancel"
element={<ConfirmDigiSubCancellation />}
/>
<Route
path="confirm-discount"
element={<ConfirmDigiSubDiscount />}
/>
<Route
path="discount-offer"
element={<DigiSubThankYouOffer />}
/>
<Route
path="discount-confirmed"
element={<DigiSubDiscountConfirmed />}
/>
</Route>
),
)}
Expand Down
1 change: 1 addition & 0 deletions client/components/mma/cancel/CancellationContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ function userIsNavigatingBackFromCompletePage(hasCompleted: boolean) {
return (
hasCompleted &&
!location.pathname.includes('reasons') &&
!location.pathname.includes('discount-confirmed') &&
!location.pathname.includes('switch-thank-you')
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ import {
import { Button, Stack } from '@guardian/source-react-components';
import { useContext, useState } from 'react';
import { useLocation, useNavigate } from 'react-router';
import type {
CancellationContextInterface,
CancellationRouterState,
} from '@/client/components/mma/cancel/CancellationContainer';
import type { CancellationContextInterface } from '@/client/components/mma/cancel/CancellationContainer';
import { CancellationContext } from '@/client/components/mma/cancel/CancellationContainer';
import type { OptionalCancellationReasonId } from '@/client/components/mma/cancel/cancellationReason';
import { JsonResponseHandler } from '@/client/components/mma/shared/asyncComponents/DefaultApiResponseHandler';
Expand All @@ -27,6 +24,7 @@ import type {
} from '@/shared/productResponse';
import { MDA_TEST_USER_HEADER } from '@/shared/productResponse';
import type { ProductTypeWithCancellationFlow } from '@/shared/productTypes';
import type { DigisubCancellationRouterState } from './DigiSubThankYouOffer';

function GreyBulletpoint() {
return (
Expand Down Expand Up @@ -99,7 +97,8 @@ export const ConfirmDigiSubCancellation = () => {
const [loadingFailed, setLoadingFailed] = useState<boolean>(false);

const location = useLocation();
const routerState = location.state as CancellationRouterState;
const routerState = location.state as DigisubCancellationRouterState;
const eligibleForDiscount = routerState?.eligibleForDiscount;

const reason: OptionalCancellationReasonId =
'mma_membership_cancellation_default'; //reason needs to be provided as undefined doesn't work. Reason updated if user provides one on next screen.
Expand Down Expand Up @@ -260,21 +259,23 @@ export const ConfirmDigiSubCancellation = () => {
>
Cancel subscription
</Button>
<Button
onClick={() =>
navigate('../discount-offer', {
state: { ...routerState },
})
}
cssOverrides={css`
display: flex;
margin-left: ${space[5]}px;
justify-content: center;
`}
priority="subdued"
>
Go back to discount
</Button>
{eligibleForDiscount && (
<Button
onClick={() =>
navigate('../discount-offer', {
state: { ...routerState },
})
}
cssOverrides={css`
display: flex;
margin-left: ${space[5]}px;
justify-content: center;
`}
priority="subdued"
>
Go back to discount
</Button>
)}
</div>
</section>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,24 @@ import {
SvgEnvelope,
SvgGift,
} from '@guardian/source-react-components';
import { captureException } from '@sentry/browser';
import { useContext, useEffect } from 'react';
import { useLocation } from 'react-router';
import type {
CancellationContextInterface,
CancellationPageTitleInterface,
CancellationRouterState,
} from '@/client/components/mma/cancel/CancellationContainer';
import {
CancellationContext,
CancellationPageTitleContext,
} from '@/client/components/mma/cancel/CancellationContainer';
import { linkCss } from '@/client/components/mma/upgrade/UpgradeSupportStyles';
import { GenericErrorScreen } from '@/client/components/shared/GenericErrorScreen';
import {
buttonCentredCss,
stackedButtonLayoutCss,
} from '@/client/styles/ButtonStyles';
import {
getDiscountMonthsForDigisub,
getNewDigisubPrice,
getOldDigisubPrice,
} from '@/client/utilities/pricingConfig/digisubDiscountPricing';
import { getDiscountMonthsForDigisub } from '@/client/utilities/pricingConfig/digisubDiscountPricing';
import { formatAmount } from '@/client/utilities/utils';
import { DATE_FNS_LONG_OUTPUT_FORMAT, parseDate } from '@/shared/dates';
import type { PaidSubscriptionPlan } from '@/shared/productResponse';
Expand All @@ -38,8 +35,9 @@ import {
listWithDividersCss,
whatHappensNextIconCss,
} from '../../../../../styles/GenericStyles';
import type { DigisubCancellationRouterState } from './DigiSubThankYouOffer';

export const DigiSubDiscountConfirm = () => {
export const DigiSubDiscountConfirmed = () => {
const pageTitleContext = useContext(
CancellationPageTitleContext,
) as CancellationPageTitleInterface;
Expand All @@ -49,15 +47,16 @@ export const DigiSubDiscountConfirm = () => {
) as CancellationContextInterface;

const location = useLocation();
const routerState = location.state as CancellationRouterState;
const routerState = location.state as DigisubCancellationRouterState;
const digiSub = cancellationContext.productDetail;

const mainPlan = getMainPlan(digiSub.subscription) as PaidSubscriptionPlan;

const currencySymbol = mainPlan.currency;
const discountMonths = getDiscountMonthsForDigisub(digiSub);
const discountedPrice = getOldDigisubPrice(mainPlan);
const newPrice = getNewDigisubPrice(mainPlan);
const discountedPrice = routerState.discountedPrice;
const newPrice =
(digiSub.subscription.nextPaymentPrice ?? mainPlan.price) / 100;

const nextBillingDate = parseDate(
digiSub.subscription.nextPaymentDate ?? undefined,
Expand All @@ -69,6 +68,12 @@ export const DigiSubDiscountConfirm = () => {
pageTitleContext.setPageTitle('Your subscription');
}, []);

if (!discountedPrice) {
const message = 'No discounted price found in router state';
captureException(message);
return <GenericErrorScreen loggingMessage={message} />;
}

return (
<>
<section
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { Meta, StoryFn, StoryObj } from '@storybook/react';
import { rest } from 'msw';
import { ReactRouterDecorator } from '@/.storybook/ReactRouterDecorator';
import { CancellationContainer } from '@/client/components/mma/cancel/CancellationContainer';
import { ConfirmDigiSubCancellation } from '@/client/components/mma/cancel/cancellationSaves/digipack/ConfirmDigiSubCancellation';
import { DigiSubDiscountConfirm } from '@/client/components/mma/cancel/cancellationSaves/digipack/DigiSubDiscountConfirm';
import { ThankYouOffer } from '@/client/components/mma/cancel/cancellationSaves/digipack/ThankYouOffer';
import { DigiSubDiscountConfirmed } from '@/client/components/mma/cancel/cancellationSaves/digipack/DigiSubDiscountConfirmed';
import { DigiSubThankYouOffer } from '@/client/components/mma/cancel/cancellationSaves/digipack/DigiSubThankYouOffer';
import {
digitalPackPaidByDirectDebit,
digitalPackWithPaymentFailure,
Expand All @@ -29,21 +30,37 @@ export default {
},
} as Meta<typeof CancellationContainer>;

export const DiscountThankYouPage: StoryFn<
typeof DigiSubDiscountConfirm
> = () => {
return <DigiSubDiscountConfirm />;
export const DiscountConfirmed: StoryObj<typeof DigiSubDiscountConfirmed> = {
render: () => {
return <DigiSubDiscountConfirmed />;
},
parameters: {
reactRouter: {
state: {
productDetail: digitalPackPaidByDirectDebit(),
user: { email: '[email protected]' },
discountedPrice: 111.75,
},
},
},
};

export const EligibleForDiscount: StoryObj<typeof ThankYouOffer> = {
export const EligibleForDiscount: StoryObj<typeof DigiSubThankYouOffer> = {
render: () => {
return <ThankYouOffer />;
return <DigiSubThankYouOffer />;
},
parameters: {
msw: [
rest.post('/api/discounts/preview-discount', (_req, res, ctx) => {
return res(ctx.json({ valid: true, discountedPrice: 111.75 }));
}),
],
},
};

export const IneligibleForDiscount: StoryObj<typeof ThankYouOffer> = {
export const IneligibleForDiscount: StoryObj<typeof DigiSubThankYouOffer> = {
render: () => {
return <ThankYouOffer />;
return <DigiSubThankYouOffer />;
},
parameters: {
reactRouter: {
Expand All @@ -52,14 +69,29 @@ export const IneligibleForDiscount: StoryObj<typeof ThankYouOffer> = {
user: { email: '[email protected]' },
},
},
msw: [
rest.post('/api/discounts/preview-discount', (_req, res, ctx) => {
return res(ctx.json({ valid: false }));
}),
],
},
};

export const ConfirmCancellation: StoryFn<
typeof ConfirmDigiSubCancellation
> = () => {
return <ConfirmDigiSubCancellation />;
};
export const ConfirmCancellation: StoryObj<typeof ConfirmDigiSubCancellation> =
{
render: () => {
return <ConfirmDigiSubCancellation />;
},
parameters: {
reactRouter: {
state: {
productDetail: digitalPackWithPaymentFailure(),
user: { email: '[email protected]' },
eligibleForDiscount: true,
},
},
},
};

export const DigiSubCancellationReason: StoryFn<typeof SelectReason> = () => {
return <SelectReason />;
Expand Down
Loading
Loading