mirror of
https://github.com/spliit-app/spliit.git
synced 2026-02-19 14:06:12 +01:00
Upgrade Next.js to 14.1.0
This commit is contained in:
1064
package-lock.json
generated
1064
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -37,13 +37,14 @@
|
||||
"dayjs": "^1.11.10",
|
||||
"lucide-react": "^0.290.0",
|
||||
"nanoid": "^5.0.4",
|
||||
"next": "^14.0.4",
|
||||
"next": "^14.1.0",
|
||||
"next-themes": "^0.2.1",
|
||||
"next13-progressbar": "^1.1.1",
|
||||
"pg": "^8.11.3",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hook-form": "^7.47.0",
|
||||
"sharp": "^0.33.2",
|
||||
"tailwind-merge": "^1.14.0",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"ts-pattern": "^5.0.6",
|
||||
@@ -56,13 +57,13 @@
|
||||
"@types/content-disposition": "^0.5.8",
|
||||
"@types/node": "^20",
|
||||
"@types/pg": "^8.10.9",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"@types/react": "^18.2.48",
|
||||
"@types/react-dom": "^18.2.18",
|
||||
"@types/uuid": "^9.0.6",
|
||||
"autoprefixer": "^10",
|
||||
"dotenv": "^16.3.1",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "^14.0.4",
|
||||
"eslint-config-next": "^14.1.0",
|
||||
"postcss": "^8",
|
||||
"prettier": "^3.0.3",
|
||||
"prettier-plugin-organize-imports": "^3.2.3",
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
import { expenseFormSchema } from '@/lib/schemas'
|
||||
import { Metadata } from 'next'
|
||||
import { notFound, redirect } from 'next/navigation'
|
||||
import { Suspense } from 'react'
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Edit expense',
|
||||
@@ -39,12 +40,14 @@ export default async function EditExpensePage({
|
||||
}
|
||||
|
||||
return (
|
||||
<ExpenseForm
|
||||
group={group}
|
||||
expense={expense}
|
||||
categories={categories}
|
||||
onSubmit={updateExpenseAction}
|
||||
onDelete={deleteExpenseAction}
|
||||
/>
|
||||
<Suspense>
|
||||
<ExpenseForm
|
||||
group={group}
|
||||
expense={expense}
|
||||
categories={categories}
|
||||
onSubmit={updateExpenseAction}
|
||||
onDelete={deleteExpenseAction}
|
||||
/>
|
||||
</Suspense>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { createExpense, getCategories, getGroup } from '@/lib/api'
|
||||
import { expenseFormSchema } from '@/lib/schemas'
|
||||
import { Metadata } from 'next'
|
||||
import { notFound, redirect } from 'next/navigation'
|
||||
import { Suspense } from 'react'
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Create expense',
|
||||
@@ -25,10 +26,12 @@ export default async function ExpensePage({
|
||||
}
|
||||
|
||||
return (
|
||||
<ExpenseForm
|
||||
group={group}
|
||||
categories={categories}
|
||||
onSubmit={createExpenseAction}
|
||||
/>
|
||||
<Suspense>
|
||||
<ExpenseForm
|
||||
group={group}
|
||||
categories={categories}
|
||||
onSubmit={createExpenseAction}
|
||||
/>
|
||||
</Suspense>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ export async function GET(
|
||||
req: Request,
|
||||
{ params: { groupId } }: { params: { groupId: string } },
|
||||
) {
|
||||
console.log({ groupId })
|
||||
const prisma = await getPrisma()
|
||||
const group = await prisma.group.findUnique({
|
||||
where: { id: groupId },
|
||||
|
||||
@@ -5,7 +5,7 @@ import { getGroup } from '@/lib/api'
|
||||
import { Metadata } from 'next'
|
||||
import Link from 'next/link'
|
||||
import { notFound } from 'next/navigation'
|
||||
import { PropsWithChildren } from 'react'
|
||||
import { PropsWithChildren, Suspense } from 'react'
|
||||
|
||||
type Props = {
|
||||
params: {
|
||||
@@ -41,7 +41,9 @@ export default async function GroupLayout({
|
||||
</h1>
|
||||
|
||||
<div className="flex gap-2 justify-between">
|
||||
<GroupTabs groupId={groupId} />
|
||||
<Suspense>
|
||||
<GroupTabs groupId={groupId} />
|
||||
</Suspense>
|
||||
<ShareButton group={group} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { PropsWithChildren } from 'react'
|
||||
import { PropsWithChildren, Suspense } from 'react'
|
||||
|
||||
export default function GroupsLayout({ children }: PropsWithChildren<{}>) {
|
||||
return (
|
||||
<>
|
||||
<Suspense>
|
||||
<main className="flex-1 max-w-screen-md w-full mx-auto px-4 py-6 flex flex-col gap-6">
|
||||
{children}
|
||||
</main>
|
||||
</>
|
||||
</Suspense>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { env } from '@/lib/env'
|
||||
import type { Metadata, Viewport } from 'next'
|
||||
import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
import { Suspense } from 'react'
|
||||
import './globals.css'
|
||||
|
||||
export const metadata: Metadata = {
|
||||
@@ -71,7 +72,9 @@ export default function RootLayout({
|
||||
enableSystem
|
||||
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">
|
||||
<Link
|
||||
className="flex items-center gap-2 hover:scale-105 transition-transform"
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Github } from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
|
||||
// FIX for https://github.com/vercel/next.js/issues/58615
|
||||
export const dynamic = 'force-dynamic'
|
||||
// export const dynamic = 'force-dynamic'
|
||||
|
||||
export default function HomePage() {
|
||||
return (
|
||||
|
||||
@@ -35,6 +35,7 @@ import { getGroup } from '@/lib/api'
|
||||
import { GroupFormValues, groupFormSchema } from '@/lib/schemas'
|
||||
import { zodResolver } from '@hookform/resolvers/zod'
|
||||
import { Save, Trash2 } from 'lucide-react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useFieldArray, useForm } from 'react-hook-form'
|
||||
|
||||
export type Props = {
|
||||
@@ -68,15 +69,25 @@ export function GroupForm({
|
||||
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 = () => {
|
||||
if (!activeUser) return
|
||||
if (group?.id) {
|
||||
const participant = group.participants.find((p) => p.name === activeUser)
|
||||
if (participant?.id) {
|
||||
localStorage.setItem(`${group.id}-activeUser`, participant.id)
|
||||
} else {
|
||||
localStorage.setItem(`${group.id}-newUser`, activeUser)
|
||||
localStorage.setItem(`${group.id}-activeUser`, activeUser)
|
||||
}
|
||||
} else {
|
||||
localStorage.setItem('newGroup-activeUser', activeUser)
|
||||
@@ -228,39 +239,35 @@ export function GroupForm({
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="grid sm:grid-cols-2 gap-4">
|
||||
<FormItem>
|
||||
<FormLabel>Active user</FormLabel>
|
||||
<FormControl>
|
||||
<Select
|
||||
onValueChange={(value) => {
|
||||
activeUser = value
|
||||
}}
|
||||
defaultValue={
|
||||
fields.find(
|
||||
(f) =>
|
||||
f.id ===
|
||||
localStorage.getItem(`${group?.id}-activeUser`),
|
||||
)?.name || 'None'
|
||||
}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select a participant" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{[{ name: 'None' }, ...form.watch('participants')]
|
||||
.filter((item) => item.name.length > 0)
|
||||
.map(({ name }) => (
|
||||
<SelectItem key={name} value={name}>
|
||||
{name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
User used as default for paying expenses.
|
||||
</FormDescription>
|
||||
</FormItem>
|
||||
{activeUser !== null && (
|
||||
<FormItem>
|
||||
<FormLabel>Active user</FormLabel>
|
||||
<FormControl>
|
||||
<Select
|
||||
onValueChange={(value) => {
|
||||
setActiveUser(value)
|
||||
}}
|
||||
defaultValue={activeUser}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select a participant" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{[{ name: 'None' }, ...form.watch('participants')]
|
||||
.filter((item) => item.name.length > 0)
|
||||
.map(({ name }) => (
|
||||
<SelectItem key={name} value={name}>
|
||||
{name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
User used as default for paying expenses.
|
||||
</FormDescription>
|
||||
</FormItem>
|
||||
)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
Reference in New Issue
Block a user