Next.js 15 Update (#26)

* Update Next.js and React versions in all packages
* Replace onRedirect function with next/link in BillingSessionStatus, since it's no longer cached by default
* Remove unused revalidatePath import in billing return page, since it's no longer cached by default
* Add Turbopack module aliases to improve development server speed
* Converted new Dynamic APIs to be Promise-based
* Adjust mobile layout
* Use ENABLE_REACT_COMPILER to enable the React Compiler in Next.js 15
* Report Errors using the new onRequestError hook
This commit is contained in:
Giancarlo Buomprisco
2024-10-22 08:39:21 +02:00
committed by GitHub
parent 93cb011260
commit 5b9285a575
109 changed files with 5143 additions and 5545 deletions

View File

@@ -0,0 +1,14 @@
'use client';
import dynamic from 'next/dynamic';
export const EmbeddedCheckoutForm = dynamic(
async () => {
const { EmbeddedCheckout } = await import('@kit/billing-gateway/checkout');
return EmbeddedCheckout;
},
{
ssr: false,
},
);

View File

@@ -25,7 +25,7 @@ const enabled = featureFlagsConfig.enableTeamAccountBilling;
* @description Creates a checkout session for a team account.
*/
export const createTeamAccountCheckoutSession = enhanceAction(
(data) => {
async (data) => {
if (!enabled) {
throw new Error('Team account billing is not enabled');
}

View File

@@ -229,6 +229,7 @@ class TeamBillingService {
customerId,
accountId,
name: this.namespace,
error,
},
`Billing Portal session was not created`,
);
@@ -288,7 +289,7 @@ class TeamBillingService {
`Encountered an error while fetching the number of existing seats`,
);
return Promise.reject(error);
return Promise.reject(error as Error);
}
}
}

View File

@@ -23,10 +23,8 @@ import { loadTeamWorkspace } from '../_lib/server/team-account-workspace.loader'
import { TeamAccountCheckoutForm } from './_components/team-account-checkout-form';
import { createBillingPortalSession } from './_lib/server/server-actions';
interface Params {
params: {
account: string;
};
interface TeamAccountBillingPageProps {
params: Promise<{ account: string }>;
}
export const generateMetadata = async () => {
@@ -38,8 +36,9 @@ export const generateMetadata = async () => {
};
};
async function TeamAccountBillingPage({ params }: Params) {
const workspace = await loadTeamWorkspace(params.account);
async function TeamAccountBillingPage({ params }: TeamAccountBillingPageProps) {
const account = (await params).account;
const workspace = await loadTeamWorkspace(account);
const accountId = workspace.account.id;
const [data, customerId] = await loadTeamAccountBillingPage(accountId);
@@ -65,7 +64,7 @@ async function TeamAccountBillingPage({ params }: Params) {
return (
<form action={createBillingPortalSession}>
<input type="hidden" name={'accountId'} value={accountId} />
<input type="hidden" name={'slug'} value={params.account} />
<input type="hidden" name={'slug'} value={account} />
<BillingPortalCard />
</form>
@@ -75,7 +74,7 @@ async function TeamAccountBillingPage({ params }: Params) {
return (
<>
<TeamAccountLayoutPageHeader
account={params.account}
account={account}
title={<Trans i18nKey={'common:routes.billing'} />}
description={<AppBreadcrumbs />}
/>

View File

@@ -1,5 +1,3 @@
import { revalidatePath } from 'next/cache';
import dynamic from 'next/dynamic';
import { notFound, redirect } from 'next/navigation';
import { getBillingGatewayProvider } from '@kit/billing-gateway';
@@ -10,25 +8,16 @@ import billingConfig from '~/config/billing.config';
import { withI18n } from '~/lib/i18n/with-i18n';
import { requireUserInServerComponent } from '~/lib/server/require-user-in-server-component';
import { EmbeddedCheckoutForm } from '../_components/embedded-checkout-form';
interface SessionPageProps {
searchParams: {
searchParams: Promise<{
session_id: string;
};
}>;
}
const LazyEmbeddedCheckout = dynamic(
async () => {
const { EmbeddedCheckout } = await import('@kit/billing-gateway/checkout');
return EmbeddedCheckout;
},
{
ssr: false,
},
);
async function ReturnCheckoutSessionPage({ searchParams }: SessionPageProps) {
const sessionId = searchParams.session_id;
const sessionId = (await searchParams).session_id;
if (!sessionId) {
redirect('../');
@@ -38,7 +27,7 @@ async function ReturnCheckoutSessionPage({ searchParams }: SessionPageProps) {
if (checkoutToken) {
return (
<LazyEmbeddedCheckout
<EmbeddedCheckoutForm
checkoutToken={checkoutToken}
provider={billingConfig.provider}
/>
@@ -49,7 +38,7 @@ async function ReturnCheckoutSessionPage({ searchParams }: SessionPageProps) {
<>
<div className={'fixed left-0 top-48 z-50 mx-auto w-full'}>
<BillingSessionStatus
onRedirect={onRedirect}
redirectPath={'../billing'}
customerEmail={customerEmail ?? ''}
/>
</div>
@@ -96,19 +85,3 @@ async function loadCheckoutSession(sessionId: string) {
checkoutToken,
};
}
/**
* Revalidates the layout to update cached pages
* and redirects back to the home page.
*/
// eslint-disable-next-line @typescript-eslint/require-await
async function onRedirect() {
'use server';
// revalidate the home page to update cached pages
// which may have changed due to the billing session
revalidatePath('/home', 'layout');
// redirect back to billing page
redirect('../billing');
}