Skip to content

Commit 26e1786

Browse files
committed
fix(next): sign out retains current location
Because: - When a customer has manually changed their location on the checkout page, and then signs out, the previously set location is not retained. This could result in the user being navigated to their default location instead of the location selected before sign out. This commit: - Moves the Heading component into checkout and upgrade layouts - Pass countryCode and postalCode to the /new page when a customers signs out and is redirected there. Closes #FXA-11452
1 parent aa03557 commit 26e1786

6 files changed

Lines changed: 96 additions & 25 deletions

File tree

apps/payments/next/app/[locale]/[offeringId]/[interval]/checkout/[cartId]/layout.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import { headers } from 'next/headers';
55
import {
66
CouponForm,
7+
Header,
78
MetricsWrapper,
89
PurchaseDetails,
910
SelectTaxLocation,
@@ -22,7 +23,7 @@ import {
2223
TermsAndPrivacy,
2324
} from '@fxa/payments/ui/server';
2425
import { CartState } from '@fxa/shared/db/mysql/account';
25-
import { auth } from 'apps/payments/next/auth';
26+
import { auth, signOut } from 'apps/payments/next/auth';
2627
import { config } from 'apps/payments/next/config';
2728

2829
export interface CheckoutSearchParams {
@@ -57,6 +58,16 @@ export default async function CheckoutLayout({
5758
cms.defaultPurchase.purchaseDetails;
5859
return (
5960
<MetricsWrapper cart={cart}>
61+
<Header
62+
auth={{
63+
user: session?.user,
64+
signOut: async () => {
65+
'use server';
66+
await signOut({ redirect: false });
67+
},
68+
}}
69+
cart={cart}
70+
/>
6071
{session?.user?.email && (
6172
<div className="mb-8 tablet:hidden">
6273
<SignedIn email={session.user.email} />

apps/payments/next/app/[locale]/[offeringId]/[interval]/new/page.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,13 @@ export default async function New({
5656

5757
const fxaUid = session?.user?.id;
5858
const coupon = searchParams.coupon || undefined;
59+
const countryCode = searchParams.countryCode;
60+
const postalCode = searchParams.postalCode;
5961

60-
const taxAddress = await getTaxAddressAction(ipAddress, fxaUid);
62+
const taxAddress =
63+
countryCode && postalCode
64+
? { countryCode, postalCode }
65+
: await getTaxAddressAction(ipAddress, fxaUid);
6166

6267
// Check if the customer is in a location not supported by Subscription Platform
6368
// or whether the product is not available in the customer's location

apps/payments/next/app/[locale]/[offeringId]/[interval]/upgrade/[cartId]/(mainLayout)/layout.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

55
import { headers } from 'next/headers';
6-
import { MetricsWrapper, PurchaseDetails } from '@fxa/payments/ui';
6+
import { Header, MetricsWrapper, PurchaseDetails } from '@fxa/payments/ui';
77
import { fetchCMSData, getCartAction } from '@fxa/payments/ui/actions';
88
import {
99
getApp,
@@ -13,6 +13,7 @@ import {
1313
TermsAndPrivacy,
1414
} from '@fxa/payments/ui/server';
1515
import { config } from 'apps/payments/next/config';
16+
import { auth, signOut } from 'apps/payments/next/auth';
1617

1718
export default async function UpgradeSuccessLayout({
1819
children,
@@ -26,12 +27,27 @@ export default async function UpgradeSuccessLayout({
2627
const l10n = getApp().getL10n(acceptLanguage, locale);
2728
const cartDataPromise = getCartAction(params.cartId);
2829
const cmsDataPromise = fetchCMSData(params.offeringId, locale);
29-
const [cms, cart] = await Promise.all([cmsDataPromise, cartDataPromise]);
30+
const sessionPromise = auth();
31+
const [cms, cart, session] = await Promise.all([
32+
cmsDataPromise,
33+
cartDataPromise,
34+
sessionPromise,
35+
]);
3036
const purchaseDetails =
3137
cms.defaultPurchase.purchaseDetails.localizations.at(0) ||
3238
cms.defaultPurchase.purchaseDetails;
3339
return (
3440
<MetricsWrapper cart={cart}>
41+
<Header
42+
auth={{
43+
user: session?.user,
44+
signOut: async () => {
45+
'use server';
46+
await signOut({ redirect: false });
47+
},
48+
}}
49+
cart={cart}
50+
/>
3551
<div className="mx-7 tablet:grid tablet:grid-cols-[minmax(min-content,500px)_minmax(20rem,1fr)] tablet:grid-rows-[min-content] tablet:gap-x-8 tablet:mb-auto desktop:grid-cols-[600px_1fr]">
3652
<SubscriptionTitle cart={cart} l10n={l10n} />
3753
<section

apps/payments/next/app/[locale]/[offeringId]/[interval]/upgrade/[cartId]/(startLayout)/layout.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import assert from 'assert';
66
import { headers } from 'next/headers';
7-
import { MetricsWrapper } from '@fxa/payments/ui';
7+
import { Header, MetricsWrapper } from '@fxa/payments/ui';
88
import { fetchCMSData, getCartAction } from '@fxa/payments/ui/actions';
99
import {
1010
getApp,
@@ -14,6 +14,7 @@ import {
1414
UpgradePurchaseDetails,
1515
} from '@fxa/payments/ui/server';
1616
import { config } from 'apps/payments/next/config';
17+
import { auth, signOut } from 'apps/payments/next/auth';
1718

1819
export default async function UpgradeLayout({
1920
children,
@@ -28,7 +29,12 @@ export default async function UpgradeLayout({
2829

2930
const cartDataPromise = getCartAction(params.cartId);
3031
const cmsDataPromise = fetchCMSData(params.offeringId, locale);
31-
const [cms, cart] = await Promise.all([cmsDataPromise, cartDataPromise]);
32+
const sessionPromise = auth();
33+
const [cms, cart, session] = await Promise.all([
34+
cmsDataPromise,
35+
cartDataPromise,
36+
sessionPromise,
37+
]);
3238
const purchaseDetails =
3339
cms.defaultPurchase.purchaseDetails.localizations.at(0) ||
3440
cms.defaultPurchase.purchaseDetails;
@@ -43,6 +49,16 @@ export default async function UpgradeLayout({
4349

4450
return (
4551
<MetricsWrapper cart={cart}>
52+
<Header
53+
auth={{
54+
user: session?.user,
55+
signOut: async () => {
56+
'use server';
57+
await signOut({ redirect: false });
58+
},
59+
}}
60+
cart={cart}
61+
/>
4662
<div className="mx-7 tablet:grid tablet:grid-cols-[minmax(min-content,500px)_minmax(20rem,1fr)] tablet:grid-rows-[min-content] tablet:gap-x-8 tablet:mb-auto desktop:grid-cols-[600px_1fr]">
4763
<SubscriptionTitle cart={cart} l10n={l10n} />
4864

apps/payments/next/app/[locale]/layout.tsx

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44
import { getApp } from '@fxa/payments/ui/server';
55
import { headers } from 'next/headers';
6-
import { Header, Providers } from '@fxa/payments/ui';
6+
import { Providers } from '@fxa/payments/ui';
77
import { config } from 'apps/payments/next/config';
8-
import { auth, signOut } from '../../auth';
98

109
export default async function RootProviderLayout({
1110
params,
@@ -23,8 +22,6 @@ export default async function RootProviderLayout({
2322
params.locale
2423
);
2524

26-
const session = await auth();
27-
2825
return (
2926
<Providers
3027
config={{
@@ -37,15 +34,6 @@ export default async function RootProviderLayout({
3734
fetchedMessages={fetchedMessages}
3835
nonce={nonce}
3936
>
40-
<Header
41-
auth={{
42-
user: session?.user,
43-
signOut: async () => {
44-
'use server';
45-
await signOut({ redirect: false });
46-
},
47-
}}
48-
/>
4937
{children}
5038
</Providers>
5139
);

libs/payments/ui/src/lib/client/components/Header/index.tsx

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,54 @@ import { useEscKeydownEffect } from '../../hooks/useEscKeydownEffect';
2525
import { User } from 'next-auth';
2626
import { constructHrefWithUtm } from '../../../utils/constructHrefWithUtm';
2727
import { OFFERING_LINKS } from '../../../constants';
28-
import { useParams, useRouter } from 'next/navigation';
28+
import {
29+
ReadonlyURLSearchParams,
30+
useParams,
31+
useRouter,
32+
useSearchParams,
33+
} from 'next/navigation';
34+
35+
function buildSignOutRedirectPath(
36+
params: Record<string, string | string[]>,
37+
searchParams: ReadonlyURLSearchParams,
38+
countryCode: string,
39+
postalCode: string
40+
) {
41+
const { locale, offeringId, interval } = params;
42+
const remainingQueryParams = searchParams.toString();
43+
const basePath = `/${locale}/${offeringId}/${interval}/new?countryCode=${countryCode}&postalCode=${postalCode}`;
44+
45+
if (remainingQueryParams) {
46+
return `${basePath}&${remainingQueryParams}`;
47+
} else {
48+
return basePath;
49+
}
50+
}
2951

3052
type HeaderProps = {
3153
auth?: {
3254
user: User | undefined;
3355
signOut: () => Promise<void>;
3456
};
57+
cart: {
58+
taxAddress: {
59+
countryCode: string;
60+
postalCode: string;
61+
};
62+
};
3563
};
3664

37-
export const Header = ({ auth }: HeaderProps) => {
65+
export const Header = ({ auth, cart }: HeaderProps) => {
3866
const router = useRouter();
39-
const { locale, offeringId, interval } = useParams();
67+
const params = useParams();
68+
const searchParams = useSearchParams();
69+
70+
const signOutRedirectPath = buildSignOutRedirectPath(
71+
params,
72+
searchParams,
73+
cart.taxAddress.countryCode,
74+
cart.taxAddress.postalCode
75+
);
4076

4177
const signedIn = auth && auth.user;
4278

@@ -362,9 +398,8 @@ export const Header = ({ auth }: HeaderProps) => {
362398
// As of this commit, both router.push and direct location.href overwriting are necessary to ensure
363399
// the browser is in the correct state without any contentless flashes
364400
await auth.signOut();
365-
const redirectUrl = `/${locale}/${offeringId}/${interval}/new`;
366-
router.push(redirectUrl);
367-
window.location.href = redirectUrl;
401+
router.push(signOutRedirectPath);
402+
window.location.href = signOutRedirectPath;
368403
}}
369404
className="pl-3 group"
370405
>

0 commit comments

Comments
 (0)