mirror of
https://github.com/SrIzan10/echospace.git
synced 2026-06-06 00:56:54 +00:00
feat: upgrade to next 15
This commit is contained in:
@@ -28,10 +28,10 @@
|
|||||||
"ioredis": "^5.4.1",
|
"ioredis": "^5.4.1",
|
||||||
"lucia": "^3.1.1",
|
"lucia": "^3.1.1",
|
||||||
"lucide-react": "^0.368.0",
|
"lucide-react": "^0.368.0",
|
||||||
"next": "^14.2.3",
|
"next": "^15.1.2",
|
||||||
"next-themes": "^0.4.4",
|
"next-themes": "^0.4.4",
|
||||||
"react": "^18",
|
"react": "^19.0.0-rc.1",
|
||||||
"react-dom": "^18",
|
"react-dom": "^19.0.0-rc.1",
|
||||||
"react-hook-form": "^7.54.1",
|
"react-hook-form": "^7.54.1",
|
||||||
"sonner": "^1.4.41",
|
"sonner": "^1.4.41",
|
||||||
"tailwind-merge": "^2.2.2",
|
"tailwind-merge": "^2.2.2",
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
"@types/react": "^18",
|
"@types/react": "^18",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^18",
|
||||||
"eslint": "^8",
|
"eslint": "^8",
|
||||||
"eslint-config-next": "14.2.0",
|
"eslint-config-next": "^15.1.2",
|
||||||
"postcss": "^8",
|
"postcss": "^8",
|
||||||
"prisma": "^6.0.1",
|
"prisma": "^6.0.1",
|
||||||
"shadcn": "^2.1.7",
|
"shadcn": "^2.1.7",
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export async function GET(request: Request): Promise<Response> {
|
|||||||
const url = new URL(request.url);
|
const url = new URL(request.url);
|
||||||
const code = url.searchParams.get('code');
|
const code = url.searchParams.get('code');
|
||||||
const state = url.searchParams.get('state');
|
const state = url.searchParams.get('state');
|
||||||
const storedState = cookies().get('github_oauth_state')?.value ?? null;
|
const storedState = (await cookies()).get('github_oauth_state')?.value ?? null;
|
||||||
if (!code || !state || !storedState || state !== storedState) {
|
if (!code || !state || !storedState || state !== storedState) {
|
||||||
return new Response(null, {
|
return new Response(null, {
|
||||||
status: 400,
|
status: 400,
|
||||||
@@ -33,7 +33,7 @@ export async function GET(request: Request): Promise<Response> {
|
|||||||
if (existingUser) {
|
if (existingUser) {
|
||||||
const session = await lucia.createSession(existingUser.id, {});
|
const session = await lucia.createSession(existingUser.id, {});
|
||||||
const sessionCookie = lucia.createSessionCookie(session.id);
|
const sessionCookie = lucia.createSessionCookie(session.id);
|
||||||
cookies().set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
|
(await cookies()).set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
|
||||||
return new Response(null, {
|
return new Response(null, {
|
||||||
status: 302,
|
status: 302,
|
||||||
headers: {
|
headers: {
|
||||||
@@ -54,7 +54,7 @@ export async function GET(request: Request): Promise<Response> {
|
|||||||
|
|
||||||
const session = await lucia.createSession(userId, {});
|
const session = await lucia.createSession(userId, {});
|
||||||
const sessionCookie = lucia.createSessionCookie(session.id);
|
const sessionCookie = lucia.createSessionCookie(session.id);
|
||||||
cookies().set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
|
(await cookies()).set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
|
||||||
return new Response(null, {
|
return new Response(null, {
|
||||||
status: 302,
|
status: 302,
|
||||||
headers: {
|
headers: {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export async function GET(): Promise<Response> {
|
|||||||
const state = generateState();
|
const state = generateState();
|
||||||
const url = github.createAuthorizationURL(state, []);
|
const url = github.createAuthorizationURL(state, []);
|
||||||
|
|
||||||
cookies().set("github_oauth_state", state, {
|
(await cookies()).set("github_oauth_state", state, {
|
||||||
path: "/",
|
path: "/",
|
||||||
secure: process.env.NODE_ENV === "production",
|
secure: process.env.NODE_ENV === "production",
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLab
|
|||||||
import { logout } from "@/lib/auth/actions"
|
import { logout } from "@/lib/auth/actions"
|
||||||
import { useSession } from "@/lib/providers/SessionProvider"
|
import { useSession } from "@/lib/providers/SessionProvider"
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
import { useState } from "react"
|
import { useActionState } from "react"
|
||||||
import { useFormState } from "react-dom"
|
|
||||||
import MobileNavbarLinks from "../MobileNavbarLinks/MobileNavbarLinks"
|
import MobileNavbarLinks from "../MobileNavbarLinks/MobileNavbarLinks"
|
||||||
import { ThemeSwitcher } from "../ThemeSwitcher/ThemeSwitcher"
|
import { ThemeSwitcher } from "../ThemeSwitcher/ThemeSwitcher"
|
||||||
|
|
||||||
@@ -35,7 +34,7 @@ function NavbarLinks() {
|
|||||||
|
|
||||||
export default function Navbar() {
|
export default function Navbar() {
|
||||||
const { user } = useSession();
|
const { user } = useSession();
|
||||||
const [, logoutAction] = useFormState(logout, null)
|
const [, logoutAction] = useActionState(logout, null)
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<nav className="flex items-center h-16 px-4 border-b gap-3 shrink-0">
|
<nav className="flex items-center h-16 px-4 border-b gap-3 shrink-0">
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
'use client';
|
'use client';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { Path, PathValue, useForm } from 'react-hook-form';
|
import { Path, PathValue, useForm } from 'react-hook-form';
|
||||||
import { Button } from '@/components/ui/button';
|
|
||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
FormControl,
|
FormControl,
|
||||||
@@ -18,7 +17,7 @@ import { z } from 'zod';
|
|||||||
import type { UniversalFormProps } from './types';
|
import type { UniversalFormProps } from './types';
|
||||||
import { customDataSchema, projectSettingsSchema, ratelimitChangeSchema } from './zod';
|
import { customDataSchema, projectSettingsSchema, ratelimitChangeSchema } from './zod';
|
||||||
import SubmitButton from '../SubmitButton/SubmitButton';
|
import SubmitButton from '../SubmitButton/SubmitButton';
|
||||||
import { useFormState } from 'react-dom';
|
import { useActionState } from 'react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import { createSchema } from '@/lib/forms/zod';
|
import { createSchema } from '@/lib/forms/zod';
|
||||||
@@ -39,7 +38,7 @@ export function UniversalForm<T extends z.ZodType>({
|
|||||||
submitText = 'Submit',
|
submitText = 'Submit',
|
||||||
submitClassname,
|
submitClassname,
|
||||||
}: UniversalFormProps<T>) {
|
}: UniversalFormProps<T>) {
|
||||||
const [state, formAction] = useFormState(action, null);
|
const [state, formAction] = useActionState(action, null);
|
||||||
const schema = schemaDb.find((s) => s.name === schemaName)?.zod;
|
const schema = schemaDb.find((s) => s.name === schemaName)?.zod;
|
||||||
|
|
||||||
if (!schema) {
|
if (!schema) {
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ export async function logout() {
|
|||||||
const { session } = await validateRequest();
|
const { session } = await validateRequest();
|
||||||
await lucia.invalidateSession(session!.id);
|
await lucia.invalidateSession(session!.id);
|
||||||
const sessionCookie = lucia.createBlankSessionCookie();
|
const sessionCookie = lucia.createBlankSessionCookie();
|
||||||
cookies().set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
|
(await cookies()).set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
|
||||||
return redirect("/auth");
|
return redirect("/auth");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export const lucia = new Lucia(adapter, {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
export const validateRequest = cache(async () => {
|
export const validateRequest = cache(async () => {
|
||||||
const sessionId = cookies().get(lucia.sessionCookieName)?.value ?? null;
|
const sessionId = (await cookies()).get(lucia.sessionCookieName)?.value ?? null;
|
||||||
|
|
||||||
if (!sessionId)
|
if (!sessionId)
|
||||||
return {
|
return {
|
||||||
@@ -44,11 +44,11 @@ export const validateRequest = cache(async () => {
|
|||||||
try {
|
try {
|
||||||
if (session && session.fresh) {
|
if (session && session.fresh) {
|
||||||
const sessionCookie = lucia.createSessionCookie(session.id);
|
const sessionCookie = lucia.createSessionCookie(session.id);
|
||||||
cookies().set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
|
(await cookies()).set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
|
||||||
}
|
}
|
||||||
if (!session) {
|
if (!session) {
|
||||||
const sessionCookie = lucia.createBlankSessionCookie();
|
const sessionCookie = lucia.createBlankSessionCookie();
|
||||||
cookies().set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
|
(await cookies()).set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Next.js throws error attempting to set cookies when rendering page
|
// Next.js throws error attempting to set cookies when rendering page
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
export const bodyGen = (customData: string[]) => {
|
export const bodyGen = (customData: string[]) => {
|
||||||
// thankfully ai came in clutch with the comma brainfuck here
|
const customFields = customData.map((data) => `"${data}": "${data}"`).join(',\n ');
|
||||||
return `{
|
return `{
|
||||||
"message": "Hello, world!",
|
"message": "Hello, world!"${customData.length ? ',\n ' : ''}${customFields}
|
||||||
${customData.map((data) => `"${data}": "${data}"`).join(',\n ')}
|
|
||||||
}`;
|
}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const bodyGenNoIdent = (customData: string[]) => {
|
export const bodyGenNoIdent = (customData: string[]) => {
|
||||||
|
console.log(bodyGen(customData));
|
||||||
return JSON.stringify(JSON.parse(bodyGen(customData)));
|
return JSON.stringify(JSON.parse(bodyGen(customData)));
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,13 @@
|
|||||||
"use client"
|
'use client';
|
||||||
|
|
||||||
import * as React from "react"
|
import * as React from 'react';
|
||||||
import { ThemeProvider as NextThemesProvider } from "next-themes"
|
const NextThemesProvider = dynamic(() => import('next-themes').then((e) => e.ThemeProvider), {
|
||||||
import { type ThemeProviderProps } from "next-themes"
|
ssr: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
import { type ThemeProviderProps } from 'next-themes';
|
||||||
|
import dynamic from 'next/dynamic';
|
||||||
|
|
||||||
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
|
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
|
||||||
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
|
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"esnext"
|
||||||
|
],
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
@@ -18,9 +22,19 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./src/*"]
|
"@/*": [
|
||||||
}
|
"./src/*"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
"target": "ES2017"
|
||||||
"exclude": ["node_modules"]
|
},
|
||||||
|
"include": [
|
||||||
|
"next-env.d.ts",
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx",
|
||||||
|
".next/types/**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user