Production Deployment Fixes and Enhancements #3
@ -2,6 +2,7 @@ import { NextRequest, NextResponse } from "next/server"
|
||||
import { auth } from "@/lib/auth"
|
||||
import { prisma } from "@/lib/prisma"
|
||||
import { sendNewPhotoEmail } from "@/lib/email"
|
||||
import type { Prisma } from "@prisma/client"
|
||||
|
||||
// Legacy endpoint for URL-based uploads (kept for backward compatibility)
|
||||
export async function POST(req: NextRequest) {
|
||||
@ -46,7 +47,7 @@ export async function POST(req: NextRequest) {
|
||||
answerName: answerName.trim(),
|
||||
points: pointsValue,
|
||||
maxAttempts: maxAttemptsValue,
|
||||
} as any,
|
||||
} as Prisma.PhotoUncheckedCreateInput,
|
||||
include: {
|
||||
uploader: {
|
||||
select: {
|
||||
|
||||
@ -6,7 +6,7 @@ import { writeFile } from "fs/promises"
|
||||
import { join } from "path"
|
||||
import { existsSync, mkdirSync } from "fs"
|
||||
import { createHash } from "crypto"
|
||||
import type { Photo } from "@prisma/client"
|
||||
import type { Prisma } from "@prisma/client"
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
@ -44,9 +44,9 @@ export async function POST(req: NextRequest) {
|
||||
mkdirSync(uploadsDir, { recursive: true })
|
||||
}
|
||||
|
||||
type PhotoWithUploader = Photo & {
|
||||
uploader: { name: string }
|
||||
}
|
||||
type PhotoWithUploader = Prisma.PhotoGetPayload<{
|
||||
include: { uploader: { select: { name: true } } }
|
||||
}>
|
||||
|
||||
const createdPhotos: PhotoWithUploader[] = []
|
||||
|
||||
@ -106,7 +106,7 @@ export async function POST(req: NextRequest) {
|
||||
|
||||
// Check for duplicate file
|
||||
const existingPhoto = await prisma.photo.findFirst({
|
||||
where: { fileHash } as any,
|
||||
where: { fileHash } as Prisma.PhotoWhereInput,
|
||||
})
|
||||
|
||||
if (existingPhoto) {
|
||||
@ -158,7 +158,7 @@ export async function POST(req: NextRequest) {
|
||||
penaltyEnabled: penaltyEnabled,
|
||||
penaltyPoints: penaltyPointsValue,
|
||||
maxAttempts: maxAttemptsValue,
|
||||
} as any,
|
||||
} as Prisma.PhotoUncheckedCreateInput,
|
||||
include: {
|
||||
uploader: {
|
||||
select: {
|
||||
@ -168,7 +168,7 @@ export async function POST(req: NextRequest) {
|
||||
},
|
||||
})
|
||||
|
||||
createdPhotos.push(photo as PhotoWithUploader)
|
||||
createdPhotos.push(photo)
|
||||
}
|
||||
|
||||
// Send emails to all other users for all photos
|
||||
|
||||
@ -6,6 +6,7 @@ import { writeFile } from "fs/promises"
|
||||
import { join } from "path"
|
||||
import { existsSync, mkdirSync } from "fs"
|
||||
import { createHash } from "crypto"
|
||||
import type { Prisma } from "@prisma/client"
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
@ -62,7 +63,7 @@ export async function POST(req: NextRequest) {
|
||||
|
||||
// Check for duplicate file
|
||||
const existingPhoto = await prisma.photo.findFirst({
|
||||
where: { fileHash } as any,
|
||||
where: { fileHash } as Prisma.PhotoWhereInput,
|
||||
})
|
||||
|
||||
if (existingPhoto) {
|
||||
@ -122,7 +123,7 @@ export async function POST(req: NextRequest) {
|
||||
answerName: answerName.trim(),
|
||||
points: pointsValue,
|
||||
maxAttempts: maxAttemptsValue,
|
||||
} as any,
|
||||
} as Prisma.PhotoUncheckedCreateInput,
|
||||
include: {
|
||||
uploader: {
|
||||
select: {
|
||||
|
||||
@ -49,10 +49,17 @@ export default async function PhotoPage({ params }: { params: Promise<{ id: stri
|
||||
const hasCorrectGuess = userGuess?.correct || false
|
||||
const isOwner = photo.uploaderId === session.user.id
|
||||
|
||||
// Type assertion for new fields (penaltyEnabled, penaltyPoints, maxAttempts)
|
||||
type PhotoWithNewFields = typeof photo & {
|
||||
penaltyEnabled: boolean
|
||||
penaltyPoints: number
|
||||
maxAttempts: number | null
|
||||
}
|
||||
const photoWithFields = photo as PhotoWithNewFields
|
||||
|
||||
// Calculate remaining attempts
|
||||
const photoWithMaxAttempts = photo as typeof photo & { maxAttempts: number | null | undefined }
|
||||
const userGuessCount = photo.guesses.length
|
||||
const maxAttempts = photoWithMaxAttempts.maxAttempts ?? null
|
||||
const maxAttempts = photoWithFields.maxAttempts ?? null
|
||||
const remainingAttempts = maxAttempts !== null && maxAttempts > 0
|
||||
? Math.max(0, maxAttempts - userGuessCount)
|
||||
: null
|
||||
@ -77,9 +84,9 @@ export default async function PhotoPage({ params }: { params: Promise<{ id: stri
|
||||
<span className="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-purple-100 text-purple-800">
|
||||
+{photo.points} {photo.points === 1 ? "point" : "points"} if correct
|
||||
</span>
|
||||
{(photo as any).penaltyEnabled && (photo as any).penaltyPoints > 0 && (
|
||||
{photoWithFields.penaltyEnabled && photoWithFields.penaltyPoints > 0 && (
|
||||
<span className="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-red-100 text-red-800">
|
||||
-{(photo as any).penaltyPoints} {(photo as any).penaltyPoints === 1 ? "point" : "points"} if wrong
|
||||
-{photoWithFields.penaltyPoints} {photoWithFields.penaltyPoints === 1 ? "point" : "points"} if wrong
|
||||
</span>
|
||||
)}
|
||||
{maxAttempts !== null && maxAttempts > 0 && (
|
||||
@ -117,9 +124,9 @@ export default async function PhotoPage({ params }: { params: Promise<{ id: stri
|
||||
<p className="text-sm text-red-700 mt-1">
|
||||
Your last guess: <strong>{userGuess.guessText}</strong>
|
||||
</p>
|
||||
{(photo as any).penaltyEnabled && (photo as any).penaltyPoints > 0 && (
|
||||
{photoWithFields.penaltyEnabled && photoWithFields.penaltyPoints > 0 && (
|
||||
<p className="text-sm text-red-700 mt-1">
|
||||
You lost <strong>{(photo as any).penaltyPoints} {(photo as any).penaltyPoints === 1 ? "point" : "points"}</strong> for this wrong guess.
|
||||
You lost <strong>{photoWithFields.penaltyPoints} {photoWithFields.penaltyPoints === 1 ? "point" : "points"}</strong> for this wrong guess.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user