fix: await params in Next.js 16 routes and pages for TypeScript compatibility
This commit is contained in:
@@ -12,7 +12,9 @@ interface PageProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default async function EditTournamentPage({ params }: PageProps) {
|
export default async function EditTournamentPage({ params }: PageProps) {
|
||||||
const tournamentId = parseInt(params.id, 10)
|
// Next.js 16 requires awaiting params
|
||||||
|
const { id } = await params
|
||||||
|
const tournamentId = parseInt(id, 10)
|
||||||
|
|
||||||
if (isNaN(tournamentId)) {
|
if (isNaN(tournamentId)) {
|
||||||
notFound()
|
notFound()
|
||||||
|
|||||||
@@ -31,23 +31,41 @@ interface GameEntry {
|
|||||||
score2: number
|
score2: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function TournamentEntryPage({ params }: { params: { id: string } }) {
|
export default function TournamentEntryPage({ params }: { params: Promise<{ id: string }> }) {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const [tournament, setTournament] = useState<Tournament | null>(null)
|
const [tournament, setTournament] = useState<Tournament | null>(null)
|
||||||
|
const [tournamentId, setTournamentId] = useState<number | null>(null)
|
||||||
const [gameText, setGameText] = useState("")
|
const [gameText, setGameText] = useState("")
|
||||||
const [parsedGames, setParsedGames] = useState<GameEntry[]>([])
|
const [parsedGames, setParsedGames] = useState<GameEntry[]>([])
|
||||||
const [error, setError] = useState("")
|
const [error, setError] = useState("")
|
||||||
const [success, setSuccess] = useState("")
|
const [success, setSuccess] = useState("")
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
|
|
||||||
|
// Parse params and validate tournamentId
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
async function parseParams() {
|
||||||
|
const { id } = await params
|
||||||
|
const parsedId = parseInt(id, 10)
|
||||||
|
if (isNaN(parsedId)) {
|
||||||
|
router.push('/admin/tournaments')
|
||||||
|
} else {
|
||||||
|
setTournamentId(parsedId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parseParams()
|
||||||
|
}, [params, router])
|
||||||
|
|
||||||
|
// Load tournament when tournamentId is available
|
||||||
|
useEffect(() => {
|
||||||
|
if (tournamentId) {
|
||||||
loadTournament()
|
loadTournament()
|
||||||
|
}
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [])
|
}, [tournamentId])
|
||||||
|
|
||||||
const loadTournament = async () => {
|
const loadTournament = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/tournaments/${params.id}`)
|
const response = await fetch(`/api/tournaments/${tournamentId}`)
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
setTournament(data.tournament)
|
setTournament(data.tournament)
|
||||||
@@ -103,7 +121,7 @@ export default function TournamentEntryPage({ params }: { params: { id: string }
|
|||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/tournaments/${params.id}/games/bulk`, {
|
const response = await fetch(`/api/tournaments/${tournamentId}/games/bulk`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@@ -154,7 +172,7 @@ export default function TournamentEntryPage({ params }: { params: { id: string }
|
|||||||
<div className="px-4 py-6 sm:px-0">
|
<div className="px-4 py-6 sm:px-0">
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<button
|
<button
|
||||||
onClick={() => router.push(`/admin/tournaments/${params.id}`)}
|
onClick={() => router.push(`/admin/tournaments/${tournamentId}`)}
|
||||||
className="text-green-600 hover:text-green-800 mb-4"
|
className="text-green-600 hover:text-green-800 mb-4"
|
||||||
>
|
>
|
||||||
← Back to Tournament
|
← Back to Tournament
|
||||||
@@ -281,7 +299,7 @@ export default function TournamentEntryPage({ params }: { params: { id: string }
|
|||||||
|
|
||||||
<div className="flex justify-end space-x-3">
|
<div className="flex justify-end space-x-3">
|
||||||
<button
|
<button
|
||||||
onClick={() => router.push(`/admin/tournaments/${params.id}`)}
|
onClick={() => router.push(`/admin/tournaments/${tournamentId}`)}
|
||||||
className="px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500"
|
className="px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500"
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ interface PageProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default async function TournamentDetailPage({ params }: PageProps) {
|
export default async function TournamentDetailPage({ params }: PageProps) {
|
||||||
const tournamentId = parseInt(params.id, 10)
|
// Next.js 16 requires awaiting params
|
||||||
|
const { id } = await params
|
||||||
|
const tournamentId = parseInt(id, 10)
|
||||||
|
|
||||||
if (isNaN(tournamentId)) {
|
if (isNaN(tournamentId)) {
|
||||||
notFound()
|
notFound()
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ interface PageProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default async function TournamentResultsPage({ params }: PageProps) {
|
export default async function TournamentResultsPage({ params }: PageProps) {
|
||||||
const tournamentId = parseInt(params.id, 10)
|
// Next.js 16 requires awaiting params
|
||||||
|
const { id } = await params
|
||||||
|
const tournamentId = parseInt(id, 10)
|
||||||
|
|
||||||
if (isNaN(tournamentId)) {
|
if (isNaN(tournamentId)) {
|
||||||
notFound()
|
notFound()
|
||||||
|
|||||||
@@ -10,10 +10,11 @@ import { hasRole } from "@/lib/permissions";
|
|||||||
*/
|
*/
|
||||||
export async function PATCH(
|
export async function PATCH(
|
||||||
request: Request,
|
request: Request,
|
||||||
{ params }: { params: { id: string } }
|
{ params }: { params: Promise<{ id: string }> }
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const playerId = parseInt(params.id);
|
const { id } = await params
|
||||||
|
const playerId = parseInt(id);
|
||||||
|
|
||||||
// Validate player ID
|
// Validate player ID
|
||||||
if (isNaN(playerId)) {
|
if (isNaN(playerId)) {
|
||||||
|
|||||||
@@ -8,10 +8,11 @@ const K_FACTOR = 32; // Standard K-factor for Elo calculations
|
|||||||
|
|
||||||
export async function POST(
|
export async function POST(
|
||||||
request: Request,
|
request: Request,
|
||||||
{ params }: { params: { id: string } }
|
{ params }: { params: Promise<{ id: string }> }
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const tournamentId = parseInt(params.id, 10);
|
const { id } = await params
|
||||||
|
const tournamentId = parseInt(id, 10);
|
||||||
|
|
||||||
if (isNaN(tournamentId)) {
|
if (isNaN(tournamentId)) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
|
|||||||
@@ -4,10 +4,11 @@ import { canManageTournament } from "@/lib/permissions";
|
|||||||
|
|
||||||
export async function POST(
|
export async function POST(
|
||||||
request: Request,
|
request: Request,
|
||||||
{ params }: { params: { id: string } }
|
{ params }: { params: Promise<{ id: string }> }
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const tournamentId = parseInt(params.id, 10);
|
const { id } = await params
|
||||||
|
const tournamentId = parseInt(id, 10);
|
||||||
|
|
||||||
if (isNaN(tournamentId)) {
|
if (isNaN(tournamentId)) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import { canManageTournament, canDeleteTournament } from "@/lib/permissions";
|
|||||||
import { getTournamentStatus } from "@/lib/tournamentUtils";
|
import { getTournamentStatus } from "@/lib/tournamentUtils";
|
||||||
|
|
||||||
interface RouteParams {
|
interface RouteParams {
|
||||||
params: {
|
params: Promise<{
|
||||||
id: string;
|
id: string;
|
||||||
};
|
}>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -16,7 +16,8 @@ interface RouteParams {
|
|||||||
*/
|
*/
|
||||||
export async function GET(request: Request, { params }: RouteParams) {
|
export async function GET(request: Request, { params }: RouteParams) {
|
||||||
try {
|
try {
|
||||||
const tournamentId = parseInt(params.id);
|
const { id } = await params
|
||||||
|
const tournamentId = parseInt(id);
|
||||||
|
|
||||||
// Validate tournament ID
|
// Validate tournament ID
|
||||||
if (isNaN(tournamentId)) {
|
if (isNaN(tournamentId)) {
|
||||||
@@ -105,7 +106,8 @@ export async function GET(request: Request, { params }: RouteParams) {
|
|||||||
*/
|
*/
|
||||||
export async function PUT(request: Request, { params }: RouteParams) {
|
export async function PUT(request: Request, { params }: RouteParams) {
|
||||||
try {
|
try {
|
||||||
const tournamentId = parseInt(params.id);
|
const { id } = await params
|
||||||
|
const tournamentId = parseInt(id);
|
||||||
|
|
||||||
// Validate tournament ID
|
// Validate tournament ID
|
||||||
if (isNaN(tournamentId)) {
|
if (isNaN(tournamentId)) {
|
||||||
@@ -219,7 +221,8 @@ export async function PUT(request: Request, { params }: RouteParams) {
|
|||||||
*/
|
*/
|
||||||
export async function DELETE(request: Request, { params }: RouteParams) {
|
export async function DELETE(request: Request, { params }: RouteParams) {
|
||||||
try {
|
try {
|
||||||
const tournamentId = parseInt(params.id);
|
const { id } = await params
|
||||||
|
const tournamentId = parseInt(id);
|
||||||
|
|
||||||
// Validate tournament ID
|
// Validate tournament ID
|
||||||
if (isNaN(tournamentId)) {
|
if (isNaN(tournamentId)) {
|
||||||
|
|||||||
@@ -5,9 +5,10 @@ import { canAssignTournamentAdmin } from '@/lib/permissions';
|
|||||||
|
|
||||||
export async function GET(
|
export async function GET(
|
||||||
request: NextRequest,
|
request: NextRequest,
|
||||||
{ params }: { params: { id: string } }
|
{ params }: { params: Promise<{ id: string }> }
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
const { id } = await params
|
||||||
const session = await getSession();
|
const session = await getSession();
|
||||||
|
|
||||||
if (!session) {
|
if (!session) {
|
||||||
@@ -25,12 +26,12 @@ export async function GET(
|
|||||||
return NextResponse.json({ error: 'Requesting user not found' }, { status: 404 });
|
return NextResponse.json({ error: 'Requesting user not found' }, { status: 404 });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session.user.id !== params.id && requestingUser.role !== 'club_admin') {
|
if (session.user.id !== id && requestingUser.role !== 'club_admin') {
|
||||||
return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
|
return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await prisma.user.findUnique({
|
const user = await prisma.user.findUnique({
|
||||||
where: { id: params.id },
|
where: { id },
|
||||||
select: { role: true }
|
select: { role: true }
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -46,9 +47,10 @@ export async function GET(
|
|||||||
|
|
||||||
export async function PATCH(
|
export async function PATCH(
|
||||||
request: NextRequest,
|
request: NextRequest,
|
||||||
{ params }: { params: { id: string } }
|
{ params }: { params: Promise<{ id: string }> }
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
const { id } = await params
|
||||||
// Check if the current user has permission to assign roles
|
// Check if the current user has permission to assign roles
|
||||||
const permission = await canAssignTournamentAdmin();
|
const permission = await canAssignTournamentAdmin();
|
||||||
if (!permission.allowed) {
|
if (!permission.allowed) {
|
||||||
|
|||||||
@@ -5,9 +5,10 @@ import { canEditUserProfiles } from '@/lib/permissions';
|
|||||||
|
|
||||||
export async function GET(
|
export async function GET(
|
||||||
request: NextRequest,
|
request: NextRequest,
|
||||||
{ params }: { params: { id: string } }
|
{ params }: { params: Promise<{ id: string }> }
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
const { id } = await params
|
||||||
const session = await getSession();
|
const session = await getSession();
|
||||||
|
|
||||||
if (!session) {
|
if (!session) {
|
||||||
@@ -25,13 +26,13 @@ export async function GET(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Allow if requesting own profile or if user is club_admin
|
// Allow if requesting own profile or if user is club_admin
|
||||||
const canView = session.user.id === params.id || requestingUser.role === 'club_admin';
|
const canView = session.user.id === id || requestingUser.role === 'club_admin';
|
||||||
if (!canView) {
|
if (!canView) {
|
||||||
return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
|
return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await prisma.user.findUnique({
|
const user = await prisma.user.findUnique({
|
||||||
where: { id: params.id },
|
where: { id },
|
||||||
include: {
|
include: {
|
||||||
player: true,
|
player: true,
|
||||||
}
|
}
|
||||||
@@ -49,9 +50,10 @@ export async function GET(
|
|||||||
|
|
||||||
export async function PATCH(
|
export async function PATCH(
|
||||||
request: NextRequest,
|
request: NextRequest,
|
||||||
{ params }: { params: { id: string } }
|
{ params }: { params: Promise<{ id: string }> }
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
const { id } = await params
|
||||||
const session = await getSession();
|
const session = await getSession();
|
||||||
|
|
||||||
if (!session) {
|
if (!session) {
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ interface PageProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default async function PlayerProfilePage({ params }: PageProps) {
|
export default async function PlayerProfilePage({ params }: PageProps) {
|
||||||
const playerId = parseInt(params.id, 10)
|
// Next.js 16 requires awaiting params
|
||||||
|
const { id } = await params
|
||||||
|
const playerId = parseInt(id, 10)
|
||||||
|
|
||||||
if (isNaN(playerId)) {
|
if (isNaN(playerId)) {
|
||||||
notFound()
|
notFound()
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ interface PageProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default async function PlayerSchedulePage({ params }: PageProps) {
|
export default async function PlayerSchedulePage({ params }: PageProps) {
|
||||||
const playerId = parseInt(params.id, 10)
|
// Next.js 16 requires awaiting params
|
||||||
|
const { id } = await params
|
||||||
|
const playerId = parseInt(id, 10)
|
||||||
|
|
||||||
if (isNaN(playerId)) {
|
if (isNaN(playerId)) {
|
||||||
notFound()
|
notFound()
|
||||||
|
|||||||
+16
-1
@@ -8,6 +8,21 @@ const globalForPrisma = globalThis as unknown as {
|
|||||||
|
|
||||||
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL })
|
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL })
|
||||||
|
|
||||||
export const prisma = globalForPrisma.prisma ?? new PrismaClient({ adapter })
|
// Create PrismaClient with adapter
|
||||||
|
const createPrismaClient = () => {
|
||||||
|
const client = new PrismaClient({ adapter })
|
||||||
|
|
||||||
|
// Add logging if in development
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
client.$on('query', (e) => {
|
||||||
|
console.log('Query:', e.query)
|
||||||
|
console.log('Duration:', e.duration, 'ms')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return client
|
||||||
|
}
|
||||||
|
|
||||||
|
export const prisma = globalForPrisma.prisma ?? createPrismaClient()
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
|
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
|
||||||
|
|||||||
Reference in New Issue
Block a user