mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2026-03-21 22:56:47 +00:00
fix: upgrade to nextjs 16 (#888)
* Upgrade to nextjs 16 * Update sentry config * Force dynamic for health route * Upgrade eslint config * Upgrade jest * Move types to dev dependencies * Remove pages from tailwind config * Replace img with next image
This commit is contained in:
1
www/.gitignore
vendored
1
www/.gitignore
vendored
@@ -46,3 +46,4 @@ openapi-ts-error-*.log
|
||||
|
||||
# pnpm
|
||||
.pnpm-store
|
||||
/v10
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faClose } from "@fortawesome/free-solid-svg-icons";
|
||||
import type { JSX } from "react";
|
||||
import { MouseEventHandler } from "react";
|
||||
|
||||
type ModalProps = {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { Box, Stack, Link, Heading } from "@chakra-ui/react";
|
||||
import NextLink from "next/link";
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
Box,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Container, Flex, Link } from "@chakra-ui/react";
|
||||
import { Container, Flex } from "@chakra-ui/react";
|
||||
import { featureEnabled } from "../lib/features";
|
||||
import NextLink from "next/link";
|
||||
import Image from "next/image";
|
||||
@@ -30,7 +30,7 @@ export default async function AppLayout({
|
||||
mt="1"
|
||||
>
|
||||
{/* Logo on the left */}
|
||||
<Link as={NextLink} href="/" className="flex">
|
||||
<NextLink href="/" className="flex">
|
||||
<Image
|
||||
src="/reach.svg"
|
||||
width={32}
|
||||
@@ -46,22 +46,18 @@ export default async function AppLayout({
|
||||
Capture the signal, not the noise
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
</NextLink>
|
||||
<div>
|
||||
{/* Text link on the right */}
|
||||
<Link
|
||||
as={NextLink}
|
||||
href={RECORD_A_MEETING_URL}
|
||||
className="font-light px-2"
|
||||
>
|
||||
<NextLink href={RECORD_A_MEETING_URL} className="font-light px-2">
|
||||
Create
|
||||
</Link>
|
||||
</NextLink>
|
||||
{featureEnabled("browse") ? (
|
||||
<>
|
||||
·
|
||||
<Link href="/browse" as={NextLink} className="font-light px-2">
|
||||
<NextLink href="/browse" className="font-light px-2">
|
||||
Browse
|
||||
</Link>
|
||||
</NextLink>
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
@@ -69,9 +65,9 @@ export default async function AppLayout({
|
||||
{featureEnabled("rooms") ? (
|
||||
<>
|
||||
·
|
||||
<Link href="/rooms" as={NextLink} className="font-light px-2">
|
||||
<NextLink href="/rooms" className="font-light px-2">
|
||||
Rooms
|
||||
</Link>
|
||||
</NextLink>
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
@@ -79,13 +75,9 @@ export default async function AppLayout({
|
||||
{featureEnabled("requireLogin") ? (
|
||||
<>
|
||||
·
|
||||
<Link
|
||||
href="/settings/api-keys"
|
||||
as={NextLink}
|
||||
className="font-light px-2"
|
||||
>
|
||||
<NextLink href="/settings/api-keys" className="font-light px-2">
|
||||
Settings
|
||||
</Link>
|
||||
</NextLink>
|
||||
·
|
||||
<UserInfo />
|
||||
</>
|
||||
|
||||
@@ -28,7 +28,7 @@ function WherebyConsentDialogButton({
|
||||
meetingId: MeetingId;
|
||||
recordingType: Meeting["recording_type"];
|
||||
skipConsent: boolean;
|
||||
wherebyRef: React.RefObject<HTMLElement>;
|
||||
wherebyRef: React.RefObject<HTMLElement | null>;
|
||||
}) {
|
||||
const previousFocusRef = useRef<HTMLElement | null>(null);
|
||||
|
||||
|
||||
@@ -49,8 +49,8 @@ export type RoomDetails = {
|
||||
|
||||
// stages: we focus on the consent, then whereby steals focus, then we focus on the consent again, then return focus to whoever stole it initially
|
||||
const useConsentWherebyFocusManagement = (
|
||||
acceptButtonRef: RefObject<HTMLButtonElement>,
|
||||
wherebyRef: RefObject<HTMLElement>,
|
||||
acceptButtonRef: RefObject<HTMLButtonElement | null>,
|
||||
wherebyRef: RefObject<HTMLElement | null>,
|
||||
) => {
|
||||
const currentFocusRef = useRef<HTMLElement | null>(null);
|
||||
useEffect(() => {
|
||||
@@ -87,7 +87,7 @@ const useConsentWherebyFocusManagement = (
|
||||
|
||||
const useConsentDialog = (
|
||||
meetingId: MeetingId,
|
||||
wherebyRef: RefObject<HTMLElement> /*accessibility*/,
|
||||
wherebyRef: RefObject<HTMLElement | null> /*accessibility*/,
|
||||
) => {
|
||||
const { state: consentState, touch, hasAnswered } = useRecordingConsent();
|
||||
// toast would open duplicates, even with using "id=" prop
|
||||
@@ -220,7 +220,7 @@ function ConsentDialogButton({
|
||||
wherebyRef,
|
||||
}: {
|
||||
meetingId: MeetingId;
|
||||
wherebyRef: React.RefObject<HTMLElement>;
|
||||
wherebyRef: React.RefObject<HTMLElement | null>;
|
||||
}) {
|
||||
const { showConsentModal, consentState, hasAnswered, consentLoading } =
|
||||
useConsentDialog(meetingId, wherebyRef);
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
import NextAuth from "next-auth";
|
||||
import { authOptions } from "../../../lib/authBackend";
|
||||
|
||||
const handler = NextAuth(authOptions());
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export { handler as GET, handler as POST };
|
||||
// authOptions() is deferred to request time to avoid calling getNextEnvVar
|
||||
// during Turbopack's build-phase module evaluation (Next.js 16+)
|
||||
export function GET(req: Request, ctx: any) {
|
||||
return NextAuth(authOptions())(req as any, ctx);
|
||||
}
|
||||
|
||||
export function POST(req: Request, ctx: any) {
|
||||
return NextAuth(authOptions())(req as any, ctx);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export async function GET() {
|
||||
const health = {
|
||||
status: "healthy",
|
||||
|
||||
@@ -24,10 +24,9 @@ export const viewport: Viewport = {
|
||||
maximumScale: 1,
|
||||
};
|
||||
|
||||
const SITE_URL = getNextEnvVar("SITE_URL");
|
||||
const env = getClientEnv();
|
||||
|
||||
export const metadata: Metadata = {
|
||||
export function generateMetadata(): Metadata {
|
||||
const SITE_URL = getNextEnvVar("SITE_URL");
|
||||
return {
|
||||
metadataBase: new URL(SITE_URL),
|
||||
title: {
|
||||
template: "%s – Reflector",
|
||||
@@ -38,7 +37,9 @@ export const metadata: Metadata = {
|
||||
applicationName: "Reflector",
|
||||
referrer: "origin-when-cross-origin",
|
||||
keywords: ["Reflector", "Monadical", "AI", "Meetings", "Transcription"],
|
||||
authors: [{ name: "Monadical Team", url: "https://monadical.com/team.html" }],
|
||||
authors: [
|
||||
{ name: "Monadical Team", url: "https://monadical.com/team.html" },
|
||||
],
|
||||
formatDetection: {
|
||||
email: false,
|
||||
address: false,
|
||||
@@ -65,14 +66,21 @@ export const metadata: Metadata = {
|
||||
shortcut: "/r-icon.png",
|
||||
apple: "/r-icon.png",
|
||||
},
|
||||
robots: { index: false, follow: false, noarchive: true, noimageindex: true },
|
||||
};
|
||||
robots: {
|
||||
index: false,
|
||||
follow: false,
|
||||
noarchive: true,
|
||||
noimageindex: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const env = getClientEnv();
|
||||
return (
|
||||
<html lang="en" className={poppins.className} suppressHydrationWarning>
|
||||
<body
|
||||
|
||||
@@ -84,7 +84,7 @@ export const getClientEnvServer = (): ClientEnvCommon => {
|
||||
|
||||
if (isBuildPhase) {
|
||||
return {
|
||||
API_URL: getNextEnvVar("API_URL"),
|
||||
API_URL: parseNonEmptyString(process.env.API_URL ?? ""),
|
||||
WEBSOCKET_URL: parseMaybeNonEmptyString(process.env.WEBSOCKET_URL ?? ""),
|
||||
AUTH_PROVIDER: parseAuthProvider(),
|
||||
SENTRY_DSN: parseMaybeNonEmptyString(
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import type { JSX } from "react";
|
||||
|
||||
type SimpleProps = {
|
||||
children: JSX.Element | string | (JSX.Element | string)[];
|
||||
className?: string;
|
||||
|
||||
@@ -159,7 +159,7 @@ export default function WebinarPage(details: WebinarDetails) {
|
||||
<div className="max-w-4xl mx-auto px-2 py-8 bg-gray-50">
|
||||
<div className="bg-white rounded-3xl px-4 md:px-36 py-4 shadow-md mx-auto">
|
||||
<Link href="https://www.monadical.com" target="_blank">
|
||||
<img
|
||||
<Image
|
||||
src="/monadical-black-white 1.svg"
|
||||
alt="Monadical Logo"
|
||||
className="mx-auto mb-8"
|
||||
@@ -355,7 +355,7 @@ export default function WebinarPage(details: WebinarDetails) {
|
||||
<div className="max-w-4xl mx-auto px-2 py-8 bg-gray-50">
|
||||
<div className="bg-white rounded-3xl px-4 md:px-36 py-4 shadow-md mx-auto">
|
||||
<Link href="https://www.monadical.com" target="_blank">
|
||||
<img
|
||||
<Image
|
||||
src="/monadical-black-white 1.svg"
|
||||
alt="Monadical Logo"
|
||||
className="mx-auto mb-8"
|
||||
|
||||
@@ -4,47 +4,20 @@ const nextConfig = {
|
||||
env: {
|
||||
IS_CI: process.env.IS_CI,
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = nextConfig;
|
||||
|
||||
// Injected content via Sentry wizard below
|
||||
|
||||
const { withSentryConfig } = require("@sentry/nextjs");
|
||||
|
||||
module.exports = withSentryConfig(
|
||||
module.exports,
|
||||
{
|
||||
// For all available options, see:
|
||||
// https://github.com/getsentry/sentry-webpack-plugin#options
|
||||
|
||||
// Suppresses source map uploading logs during build
|
||||
silent: true,
|
||||
|
||||
org: "monadical",
|
||||
project: "reflector-www",
|
||||
},
|
||||
{
|
||||
// For all available options, see:
|
||||
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
|
||||
|
||||
// Upload a larger set of source maps for prettier stack traces (increases build time)
|
||||
widenClientFileUpload: true,
|
||||
|
||||
// Transpiles SDK to be compatible with IE11 (increases bundle size)
|
||||
transpileClientSDK: true,
|
||||
|
||||
// Routes browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers (increases server load)
|
||||
tunnelRoute: "/monitoring",
|
||||
|
||||
// Hides source maps from generated client bundles
|
||||
hideSourceMaps: true,
|
||||
|
||||
// Automatically tree-shake Sentry logger statements to reduce bundle size
|
||||
disableLogger: true,
|
||||
|
||||
experimental: {
|
||||
optimizePackageImports: ["@chakra-ui/react"],
|
||||
},
|
||||
};
|
||||
|
||||
const { withSentryConfig } = require("@sentry/nextjs");
|
||||
|
||||
module.exports = withSentryConfig(nextConfig, {
|
||||
silent: true,
|
||||
org: "monadical",
|
||||
project: "reflector-www",
|
||||
widenClientFileUpload: true,
|
||||
tunnelRoute: "/monitoring",
|
||||
bundleSizeOptimizations: {
|
||||
excludeDebugStatements: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
@@ -21,17 +21,16 @@
|
||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
||||
"@sentry/nextjs": "^10.40.0",
|
||||
"@tanstack/react-query": "^5.85.9",
|
||||
"@types/ioredis": "^5.0.0",
|
||||
"@whereby.com/browser-sdk": "^3.3.4",
|
||||
"autoprefixer": "10.4.20",
|
||||
"axios": "^1.13.5",
|
||||
"eslint": "^9.33.0",
|
||||
"eslint-config-next": "^15.5.3",
|
||||
"eslint-config-next": "^16.1.6",
|
||||
"fontawesome": "^5.6.3",
|
||||
"ioredis": "^5.7.0",
|
||||
"jest-worker": "^29.6.2",
|
||||
"lucide-react": "^0.525.0",
|
||||
"next": "^15.5.10",
|
||||
"next": "^16.1.6",
|
||||
"next-auth": "^4.24.12",
|
||||
"next-themes": "^0.4.6",
|
||||
"nuqs": "^2.4.3",
|
||||
@@ -39,8 +38,8 @@
|
||||
"openapi-react-query": "^0.5.0",
|
||||
"postcss": "8.4.31",
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"react-dropdown": "^1.11.0",
|
||||
"react-icons": "^5.0.1",
|
||||
"react-markdown": "^9.0.0",
|
||||
@@ -61,12 +60,14 @@
|
||||
"author": "Andreas <andreas@monadical.com>",
|
||||
"license": "All Rights Reserved",
|
||||
"devDependencies": {
|
||||
"@types/ioredis": "^5.0.0",
|
||||
"@types/jest": "^30.0.0",
|
||||
"@types/react": "18.2.20",
|
||||
"jest": "^30.1.3",
|
||||
"@types/react": "19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"jest": "^30.2.0",
|
||||
"openapi-typescript": "^7.9.1",
|
||||
"prettier": "^3.0.0",
|
||||
"ts-jest": "^29.4.1"
|
||||
"ts-jest": "^29.4.6"
|
||||
},
|
||||
"packageManager": "pnpm@10.14.0+sha512.ad27a79641b49c3e481a16a805baa71817a04bbe06a38d17e60e2eaee83f6a146c6a688125f5792e48dd5ba30e7da52a5cda4c3992b9ccf333f9ce223af84748"
|
||||
}
|
||||
|
||||
1754
www/pnpm-lock.yaml
generated
1754
www/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,6 @@ module.exports = {
|
||||
preflight: false,
|
||||
},
|
||||
content: [
|
||||
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./components/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./app/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
],
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"jsx": "react-jsx",
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
@@ -22,6 +22,12 @@
|
||||
"strictNullChecks": true,
|
||||
"downlevelIteration": true
|
||||
},
|
||||
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
".next/types/**/*.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/dev/types/**/*.ts"
|
||||
],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user