Upgrade Next.js to 14.1.0

This commit is contained in:
Sebastien Castiel
2024-01-24 09:50:37 -05:00
parent 2f58e466da
commit 7956156d70
10 changed files with 1037 additions and 163 deletions

1064
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -37,13 +37,14 @@
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"lucide-react": "^0.290.0", "lucide-react": "^0.290.0",
"nanoid": "^5.0.4", "nanoid": "^5.0.4",
"next": "^14.0.4", "next": "^14.1.0",
"next-themes": "^0.2.1", "next-themes": "^0.2.1",
"next13-progressbar": "^1.1.1", "next13-progressbar": "^1.1.1",
"pg": "^8.11.3", "pg": "^8.11.3",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-hook-form": "^7.47.0", "react-hook-form": "^7.47.0",
"sharp": "^0.33.2",
"tailwind-merge": "^1.14.0", "tailwind-merge": "^1.14.0",
"tailwindcss-animate": "^1.0.7", "tailwindcss-animate": "^1.0.7",
"ts-pattern": "^5.0.6", "ts-pattern": "^5.0.6",
@@ -56,13 +57,13 @@
"@types/content-disposition": "^0.5.8", "@types/content-disposition": "^0.5.8",
"@types/node": "^20", "@types/node": "^20",
"@types/pg": "^8.10.9", "@types/pg": "^8.10.9",
"@types/react": "^18", "@types/react": "^18.2.48",
"@types/react-dom": "^18", "@types/react-dom": "^18.2.18",
"@types/uuid": "^9.0.6", "@types/uuid": "^9.0.6",
"autoprefixer": "^10", "autoprefixer": "^10",
"dotenv": "^16.3.1", "dotenv": "^16.3.1",
"eslint": "^8", "eslint": "^8",
"eslint-config-next": "^14.0.4", "eslint-config-next": "^14.1.0",
"postcss": "^8", "postcss": "^8",
"prettier": "^3.0.3", "prettier": "^3.0.3",
"prettier-plugin-organize-imports": "^3.2.3", "prettier-plugin-organize-imports": "^3.2.3",

View File

@@ -9,6 +9,7 @@ import {
import { expenseFormSchema } from '@/lib/schemas' import { expenseFormSchema } from '@/lib/schemas'
import { Metadata } from 'next' import { Metadata } from 'next'
import { notFound, redirect } from 'next/navigation' import { notFound, redirect } from 'next/navigation'
import { Suspense } from 'react'
export const metadata: Metadata = { export const metadata: Metadata = {
title: 'Edit expense', title: 'Edit expense',
@@ -39,12 +40,14 @@ export default async function EditExpensePage({
} }
return ( return (
<ExpenseForm <Suspense>
group={group} <ExpenseForm
expense={expense} group={group}
categories={categories} expense={expense}
onSubmit={updateExpenseAction} categories={categories}
onDelete={deleteExpenseAction} onSubmit={updateExpenseAction}
/> onDelete={deleteExpenseAction}
/>
</Suspense>
) )
} }

View File

@@ -3,6 +3,7 @@ import { createExpense, getCategories, getGroup } from '@/lib/api'
import { expenseFormSchema } from '@/lib/schemas' import { expenseFormSchema } from '@/lib/schemas'
import { Metadata } from 'next' import { Metadata } from 'next'
import { notFound, redirect } from 'next/navigation' import { notFound, redirect } from 'next/navigation'
import { Suspense } from 'react'
export const metadata: Metadata = { export const metadata: Metadata = {
title: 'Create expense', title: 'Create expense',
@@ -25,10 +26,12 @@ export default async function ExpensePage({
} }
return ( return (
<ExpenseForm <Suspense>
group={group} <ExpenseForm
categories={categories} group={group}
onSubmit={createExpenseAction} categories={categories}
/> onSubmit={createExpenseAction}
/>
</Suspense>
) )
} }

View File

@@ -6,7 +6,6 @@ export async function GET(
req: Request, req: Request,
{ params: { groupId } }: { params: { groupId: string } }, { params: { groupId } }: { params: { groupId: string } },
) { ) {
console.log({ groupId })
const prisma = await getPrisma() const prisma = await getPrisma()
const group = await prisma.group.findUnique({ const group = await prisma.group.findUnique({
where: { id: groupId }, where: { id: groupId },

View File

@@ -5,7 +5,7 @@ import { getGroup } from '@/lib/api'
import { Metadata } from 'next' import { Metadata } from 'next'
import Link from 'next/link' import Link from 'next/link'
import { notFound } from 'next/navigation' import { notFound } from 'next/navigation'
import { PropsWithChildren } from 'react' import { PropsWithChildren, Suspense } from 'react'
type Props = { type Props = {
params: { params: {
@@ -41,7 +41,9 @@ export default async function GroupLayout({
</h1> </h1>
<div className="flex gap-2 justify-between"> <div className="flex gap-2 justify-between">
<GroupTabs groupId={groupId} /> <Suspense>
<GroupTabs groupId={groupId} />
</Suspense>
<ShareButton group={group} /> <ShareButton group={group} />
</div> </div>
</div> </div>

View File

@@ -1,11 +1,11 @@
import { PropsWithChildren } from 'react' import { PropsWithChildren, Suspense } from 'react'
export default function GroupsLayout({ children }: PropsWithChildren<{}>) { export default function GroupsLayout({ children }: PropsWithChildren<{}>) {
return ( return (
<> <Suspense>
<main className="flex-1 max-w-screen-md w-full mx-auto px-4 py-6 flex flex-col gap-6"> <main className="flex-1 max-w-screen-md w-full mx-auto px-4 py-6 flex flex-col gap-6">
{children} {children}
</main> </main>
</> </Suspense>
) )
} }

View File

@@ -7,6 +7,7 @@ import { env } from '@/lib/env'
import type { Metadata, Viewport } from 'next' import type { Metadata, Viewport } from 'next'
import Image from 'next/image' import Image from 'next/image'
import Link from 'next/link' import Link from 'next/link'
import { Suspense } from 'react'
import './globals.css' import './globals.css'
export const metadata: Metadata = { export const metadata: Metadata = {
@@ -71,7 +72,9 @@ export default function RootLayout({
enableSystem enableSystem
disableTransitionOnChange disableTransitionOnChange
> >
<ProgressBar /> <Suspense>
<ProgressBar />
</Suspense>
<header className="fixed top-0 left-0 right-0 h-16 flex justify-between bg-white dark:bg-gray-950 bg-opacity-50 dark:bg-opacity-50 p-2 border-b backdrop-blur-sm z-50"> <header className="fixed top-0 left-0 right-0 h-16 flex justify-between bg-white dark:bg-gray-950 bg-opacity-50 dark:bg-opacity-50 p-2 border-b backdrop-blur-sm z-50">
<Link <Link
className="flex items-center gap-2 hover:scale-105 transition-transform" className="flex items-center gap-2 hover:scale-105 transition-transform"

View File

@@ -3,7 +3,7 @@ import { Github } from 'lucide-react'
import Link from 'next/link' import Link from 'next/link'
// FIX for https://github.com/vercel/next.js/issues/58615 // FIX for https://github.com/vercel/next.js/issues/58615
export const dynamic = 'force-dynamic' // export const dynamic = 'force-dynamic'
export default function HomePage() { export default function HomePage() {
return ( return (

View File

@@ -35,6 +35,7 @@ import { getGroup } from '@/lib/api'
import { GroupFormValues, groupFormSchema } from '@/lib/schemas' import { GroupFormValues, groupFormSchema } from '@/lib/schemas'
import { zodResolver } from '@hookform/resolvers/zod' import { zodResolver } from '@hookform/resolvers/zod'
import { Save, Trash2 } from 'lucide-react' import { Save, Trash2 } from 'lucide-react'
import { useEffect, useState } from 'react'
import { useFieldArray, useForm } from 'react-hook-form' import { useFieldArray, useForm } from 'react-hook-form'
export type Props = { export type Props = {
@@ -68,15 +69,25 @@ export function GroupForm({
keyName: 'key', keyName: 'key',
}) })
let activeUser = 'None' const [activeUser, setActiveUser] = useState<string | null>(null)
useEffect(() => {
if (activeUser === null) {
const currentActiveUser =
fields.find(
(f) => f.id === localStorage.getItem(`${group?.id}-activeUser`),
)?.name || 'None'
setActiveUser(currentActiveUser)
}
}, [activeUser, fields, group?.id])
const updateActiveUser = () => { const updateActiveUser = () => {
if (!activeUser) return
if (group?.id) { if (group?.id) {
const participant = group.participants.find((p) => p.name === activeUser) const participant = group.participants.find((p) => p.name === activeUser)
if (participant?.id) { if (participant?.id) {
localStorage.setItem(`${group.id}-activeUser`, participant.id) localStorage.setItem(`${group.id}-activeUser`, participant.id)
} else { } else {
localStorage.setItem(`${group.id}-newUser`, activeUser) localStorage.setItem(`${group.id}-activeUser`, activeUser)
} }
} else { } else {
localStorage.setItem('newGroup-activeUser', activeUser) localStorage.setItem('newGroup-activeUser', activeUser)
@@ -228,39 +239,35 @@ export function GroupForm({
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div className="grid sm:grid-cols-2 gap-4"> <div className="grid sm:grid-cols-2 gap-4">
<FormItem> {activeUser !== null && (
<FormLabel>Active user</FormLabel> <FormItem>
<FormControl> <FormLabel>Active user</FormLabel>
<Select <FormControl>
onValueChange={(value) => { <Select
activeUser = value onValueChange={(value) => {
}} setActiveUser(value)
defaultValue={ }}
fields.find( defaultValue={activeUser}
(f) => >
f.id === <SelectTrigger>
localStorage.getItem(`${group?.id}-activeUser`), <SelectValue placeholder="Select a participant" />
)?.name || 'None' </SelectTrigger>
} <SelectContent>
> {[{ name: 'None' }, ...form.watch('participants')]
<SelectTrigger> .filter((item) => item.name.length > 0)
<SelectValue placeholder="Select a participant" /> .map(({ name }) => (
</SelectTrigger> <SelectItem key={name} value={name}>
<SelectContent> {name}
{[{ name: 'None' }, ...form.watch('participants')] </SelectItem>
.filter((item) => item.name.length > 0) ))}
.map(({ name }) => ( </SelectContent>
<SelectItem key={name} value={name}> </Select>
{name} </FormControl>
</SelectItem> <FormDescription>
))} User used as default for paying expenses.
</SelectContent> </FormDescription>
</Select> </FormItem>
</FormControl> )}
<FormDescription>
User used as default for paying expenses.
</FormDescription>
</FormItem>
</div> </div>
</CardContent> </CardContent>
</Card> </Card>