Skip to content

Commit 672bd65

Browse files
Upgrade to Next.js 16, React 19, and modernize dependencies (#1312)
* feat: Upgrade to Next.js 16, React 19, and modernize dependencies - Upgrade Next.js from 14.2.21 to 16.0.7 - Upgrade React/React-DOM from 18.3.1 to 19.2.1 - Upgrade next-auth from 4.x to 5.0.0-beta.30 (Auth.js) - Upgrade tRPC from v10 to v11.7.2 - Upgrade TanStack React Query from v4 to v5.90.12 - Upgrade Zod from 3.x to 4.1.13 - Upgrade Sentry from 8.x to 10.29.0 - Upgrade Framer Motion from 11.x to 12.23.25 Breaking changes addressed: - Convert all page params to async (Next.js 16 requirement) - Migrate headers() to async function calls - Update next-auth to new Auth.js v5 API with handlers export - Replace 'loading' status with 'pending' (React Query v5) - Migrate ESLint from .eslintrc to flat config (eslint.config.mjs) - Update Zod error API (error.errors → error.issues) - Fix React 19 type changes (ChildNode → React.ReactNode) - Update TRPCReactProvider to accept serialized headers object * feat: Upgrade to Node.js 24 and modernize welcome email - Update Node.js from v20 to v24 (.nvmrc and volta config) - Migrate nodemailer to v7 with AWS SESv2 API - Update dependencies for React 19 compatibility (@t3-oss/env-nextjs, next-themes, react-highlight-words) - Configure GitHub Actions to use .nvmrc for Node version - Separate newsletter subscription and welcome email error handling - Redesign welcome email template with modern styling (no images for better deliverability) * fix: Add error handling and fix typos in auth flow - Add try/catch for banned user check with fail-closed security pattern - Fix "Excluisve" typo to "Exclusive" in welcome email subject - Fix passwordless email recipient (remove hardcoded debug name) * fix: Resolve React 19 compiler ESLint errors - Replace useState+useEffect patterns with useSyncExternalStore for client-side detection (auth, ThemeToggle, Search) - Rewrite useLocalStorage hook to use useSyncExternalStore - Convert setState-in-effect patterns to useMemo where applicable - Move Placeholder component outside render to fix "cannot create components during render" error - Replace <a> with <Link> in company page - Simplify CustomTextareaAutosize to avoid mutating prop refs - Restructure settings page to avoid JSX in try/catch - Add eslint-disable comments for intentional patterns - Ignore cdk/ directory in ESLint config Reduces ESLint errors from 23 to 0 for deployment compatibility. * style: Apply Prettier formatting and fix MDX syntax Format code with Prettier across multiple files and fix markdown bold/italic syntax in MDX content to use proper triple-asterisk notation. * Update next to 16.10 * Update article tests * Fix types
1 parent 5e5e007 commit 672bd65

File tree

75 files changed

+9507
-7340
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+9507
-7340
lines changed

.eslintrc

Lines changed: 0 additions & 23 deletions
This file was deleted.

.github/workflows/e2e-tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
- name: Setup Node.js
2828
uses: actions/setup-node@v4
2929
with:
30-
node-version: "lts/*"
30+
node-version-file: '.nvmrc'
3131
cache: "npm"
3232

3333
- name: Install dependencies
@@ -55,7 +55,7 @@ jobs:
5555
- name: Setup Node.js
5656
uses: actions/setup-node@v4
5757
with:
58-
node-version: "lts/*"
58+
node-version-file: '.nvmrc'
5959
cache: "npm"
6060

6161
- name: Cache Playwright browsers

.github/workflows/pull-request.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
- name: Use Node.js
2020
uses: actions/setup-node@v4
2121
with:
22-
node-version: 'lts/*'
22+
node-version-file: '.nvmrc'
2323
cache: 'npm'
2424

2525
- name: Install dependencies

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,6 @@ ssmSetup.zsh
6868

6969
# open-next
7070
.open-next
71+
72+
# Snyk Security Extension - AI Rules (auto-generated)
73+
.github/instructions/snyk_rules.instructions.md

.mcp.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"mcpServers": {
3+
"context7": {
4+
"command": "npx",
5+
"args": ["-y", "@upstash/context7-mcp"],
6+
"env": {
7+
"CONTEXT7_API_KEY": "ctx7sk-1d829fe1-62b2-4697-b7f4-673ae5047efd"
8+
}
9+
},
10+
"puppeteer": {
11+
"command": "npx",
12+
"args": ["-y", "puppeteer-mcp-server"],
13+
"env": {}
14+
},
15+
"next-devtools": {
16+
"command": "npx",
17+
"args": ["-y", "next-devtools-mcp@latest"]
18+
},
19+
"sequential-thinking": {
20+
"command": "npx",
21+
"args": ["-y", "@modelcontextprotocol/server-sequential-thinking"]
22+
},
23+
"Sentry": {
24+
"url": "https://mcp.sentry.dev/mcp/assemble-pro/javascript-nextjs"
25+
}
26+
}
27+
}

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v20.17.0
1+
v24

app/(app)/(tsandcs)/privacy/page.mdx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ Want to learn more about what we do with any information we collect? Review the
7070

7171
**Personal information you disclose to us**
7272

73-
**_In Short:_** *We collect personal information that you provide to us.*
73+
***In Short:*** *We collect personal information that you provide to us.*
7474

7575
We collect personal information that you voluntarily provide to us when you register on the Services, express an interest in obtaining information about us or our products and Services, when you participate in activities on the Services, or otherwise when you contact us.
7676

@@ -96,7 +96,7 @@ All personal information that you provide to us must be true, complete, and accu
9696

9797
**2\. HOW DO WE PROCESS YOUR INFORMATION?**
9898

99-
**_In Short:_** *We process your information to provide, improve, and administer our Services, communicate with you, for security and fraud prevention, and to comply with law. We may also process your information for other purposes with your consent.*
99+
***In Short:*** *We process your information to provide, improve, and administer our Services, communicate with you, for security and fraud prevention, and to comply with law. We may also process your information for other purposes with your consent.*
100100

101101
**We process your personal information for a variety of reasons, depending on how you interact with our Services, including:**
102102

@@ -158,7 +158,7 @@ In some exceptional cases, we may be legally permitted under applicable law to p
158158

159159
**4\. WHEN AND WITH WHOM DO WE SHARE YOUR PERSONAL INFORMATION?**
160160

161-
**_In Short:_** *We may share information in specific situations described in this section and/or with the following third parties.*
161+
***In Short:*** *We may share information in specific situations described in this section and/or with the following third parties.*
162162

163163
We may need to share your personal information in the following situations:
164164

@@ -168,35 +168,35 @@ We may need to share your personal information in the following situations:
168168

169169
**5\. HOW DO WE HANDLE YOUR SOCIAL LOGINS?**
170170

171-
**_In Short:_** *If you choose to register or log in to our Services using a social media account, we may have access to certain information about you.*
171+
***In Short:*** *If you choose to register or log in to our Services using a social media account, we may have access to certain information about you.*
172172

173173
Our Services offer you the ability to register and log in using your third-party social media account details (like your Facebook or Twitter logins). Where you choose to do this, we will receive certain profile information about you from your social media provider. The profile information we receive may vary depending on the social media provider concerned, but will often include your name, email address, friends list, and profile picture, as well as other information you choose to make public on such a social media platform.
174174

175175
We will use the information we receive only for the purposes that are described in this privacy notice or that are otherwise made clear to you on the relevant Services. Please note that we do not control, and are not responsible for, other uses of your personal information by your third-party social media provider. We recommend that you review their privacy notice to understand how they collect, use, and share your personal information, and how you can set your privacy preferences on their sites and apps.
176176

177177
**6\. HOW LONG DO WE KEEP YOUR INFORMATION?**
178178

179-
**_In Short:_** *We keep your information for as long as necessary to fulfill the purposes outlined in this privacy notice unless otherwise required by law.*
179+
***In Short:*** *We keep your information for as long as necessary to fulfill the purposes outlined in this privacy notice unless otherwise required by law.*
180180

181181
We will only keep your personal information for as long as it is necessary for the purposes set out in this privacy notice, unless a longer retention period is required or permitted by law (such as tax, accounting, or other legal requirements). No purpose in this notice will require us keeping your personal information for longer than the period of time in which users have an account with us.
182182

183183
When we have no ongoing legitimate business need to process your personal information, we will either delete or anonymize such information, or, if this is not possible (for example, because your personal information has been stored in backup archives), then we will securely store your personal information and isolate it from any further processing until deletion is possible.
184184

185185
**7\. HOW DO WE KEEP YOUR INFORMATION SAFE?**
186186

187-
**_In Short:_** *We aim to protect your personal information through a system of organizational and technical security measures.*
187+
***In Short:*** *We aim to protect your personal information through a system of organizational and technical security measures.*
188188

189189
We have implemented appropriate and reasonable technical and organizational security measures designed to protect the security of any personal information we process. However, despite our safeguards and efforts to secure your information, no electronic transmission over the Internet or information storage technology can be guaranteed to be 100% secure, so we cannot promise or guarantee that hackers, cybercriminals, or other unauthorized third parties will not be able to defeat our security and improperly collect, access, steal, or modify your information. Although we will do our best to protect your personal information, transmission of personal information to and from our Services is at your own risk. You should only access the Services within a secure environment.
190190

191191
**8\. DO WE COLLECT INFORMATION FROM MINORS?**
192192

193-
**_In Short:_** *We do not knowingly collect data from or market to children under 18 years of age.*
193+
***In Short:*** *We do not knowingly collect data from or market to children under 18 years of age.*
194194

195195
We do not knowingly solicit data from or market to children under 18 years of age. By using the Services, you represent that you are at least 18 or that you are the parent or guardian of such a minor and consent to such minor dependent’s use of the Services. If we learn that personal information from users less than 18 years of age has been collected, we will deactivate the account and take reasonable measures to promptly delete such data from our records. If you become aware of any data we may have collected from children under age 18, please contact us at [email protected].
196196

197197
**9\. WHAT ARE YOUR PRIVACY RIGHTS?**
198198

199-
**_In Short:_** *In some regions, such as the European Economic Area (EEA), United Kingdom (UK), Switzerland, and Canada, you have rights that allow you greater access to and control over your personal information. You may review, change, or terminate your account at any time.*
199+
***In Short:*** *In some regions, such as the European Economic Area (EEA), United Kingdom (UK), Switzerland, and Canada, you have rights that allow you greater access to and control over your personal information. You may review, change, or terminate your account at any time.*
200200

201201
In some regions (like the EEA, UK, Switzerland, and Canada), you have certain rights under applicable data protection laws. These may include the right (i) to request access and obtain a copy of your personal information, (ii) to request rectification or erasure; (iii) to restrict the processing of your personal information; (iv) if applicable, to data portability; and (v) not to be subject to automated decision-making. In certain circumstances, you may also have the right to object to the processing of your personal information. You can make such a request by contacting us by using the contact details provided in the section "HOW CAN YOU CONTACT US ABOUT THIS NOTICE?" below.
202202

@@ -228,7 +228,7 @@ Most web browsers and some mobile operating systems and mobile applications incl
228228

229229
**11\. DO UNITED STATES RESIDENTS HAVE SPECIFIC PRIVACY RIGHTS?**
230230

231-
**_In Short:_** *If you are a resident of California, Colorado, Connecticut, Utah or Virginia, you are granted specific rights regarding access to your personal information.*
231+
***In Short:*** *If you are a resident of California, Colorado, Connecticut, Utah or Virginia, you are granted specific rights regarding access to your personal information.*
232232

233233
**What categories of personal information do we collect?**
234234

app/(app)/[username]/page.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ import { getServerAuthSession } from "@/server/auth";
55
import { type Metadata } from "next";
66
import { db } from "@/server/db";
77

8-
type Props = { params: { username: string } };
8+
type Props = { params: Promise<{ username: string }> };
99

10-
export async function generateMetadata({ params }: Props): Promise<Metadata> {
10+
export async function generateMetadata(props: Props): Promise<Metadata> {
11+
const params = await props.params;
1112
const username = params.username;
1213

1314
const profile = await db.query.user.findFirst({
@@ -52,11 +53,10 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
5253
};
5354
}
5455

55-
export default async function Page({
56-
params,
57-
}: {
58-
params: { username: string };
56+
export default async function Page(props: {
57+
params: Promise<{ username: string }>;
5958
}) {
59+
const params = await props.params;
6060
const username = params?.username;
6161

6262
if (!username) {

app/(app)/alpha/additional-details/_actions.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export async function slideOneSubmitAction(dataInput: TypeSlideOneSchema) {
3737
return true;
3838
} catch (error) {
3939
if (error instanceof z.ZodError) {
40-
console.error("Validation error:", error.errors);
40+
console.error("Validation error:", error.issues);
4141
} else {
4242
console.error("Error updating the User model:", error);
4343
}
@@ -65,7 +65,7 @@ export async function slideTwoSubmitAction(dataInput: TypeSlideTwoSchema) {
6565
return true;
6666
} catch (error) {
6767
if (error instanceof z.ZodError) {
68-
console.error("Validation error:", error.errors);
68+
console.error("Validation error:", error.issues);
6969
} else {
7070
console.error("Error updating the User model:", error);
7171
}
@@ -97,7 +97,7 @@ export async function slideThreeSubmitAction(dataInput: TypeSlideThreeSchema) {
9797
return true;
9898
} catch (error) {
9999
if (error instanceof z.ZodError) {
100-
console.error("Validation error:", error.errors);
100+
console.error("Validation error:", error.issues);
101101
} else {
102102
console.error("Error updating the User model:", error);
103103
}

app/(app)/alpha/additional-details/_client.tsx

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import React, { useEffect, useState } from "react";
3+
import React, { useEffect, useMemo, useState } from "react";
44
import { redirect, useRouter, useSearchParams } from "next/navigation";
55
import { useSession } from "next-auth/react";
66
import {
@@ -228,23 +228,21 @@ function SlideTwo({ details }: { details: UserDetails }) {
228228
parsedDateOfBirth?.getDate(),
229229
);
230230

231-
const [listOfDaysInSelectedMonth, setListOfDaysInSelectedMonth] = useState([
232-
0,
233-
]);
234-
235-
useEffect(() => {
236-
// If year or month change, recalculate how many days are in the specified month
231+
// Compute days in month directly from year/month (no state needed)
232+
const listOfDaysInSelectedMonth = useMemo(() => {
237233
if (year && month !== undefined) {
238234
// Returns the last day of the month, by creating a date with day 0 of the following month.
239-
const nummberOfDaysInMonth = new Date(year, month + 1, 0).getDate();
240-
const daysArray = Array.from(
241-
{ length: nummberOfDaysInMonth },
235+
const numberOfDaysInMonth = new Date(year, month + 1, 0).getDate();
236+
return Array.from(
237+
{ length: numberOfDaysInMonth },
242238
(_, index) => index + 1,
243239
);
244-
setListOfDaysInSelectedMonth(daysArray);
245240
}
241+
return [0];
242+
}, [year, month]);
246243

247-
// Update the date object when year, month or date change
244+
// Update the date object when year, month or day change
245+
useEffect(() => {
248246
if (year && month !== undefined && day) {
249247
let selectedDate: Date;
250248

@@ -257,7 +255,7 @@ function SlideTwo({ details }: { details: UserDetails }) {
257255
}
258256
setValue("dateOfBirth", selectedDate.toISOString());
259257
}
260-
}, [year, month, day]);
258+
}, [year, month, day, setValue]);
261259

262260
const startYearAgeDropdown = 1950;
263261
const endYearAgeDropdown = 2010;

0 commit comments

Comments
 (0)