import { createFileRoute } from "@tanstack/react-router"; import { superTokensRequestMiddleware } from "@/utils/supertokens"; import { pbAdmin } from "@/lib/pocketbase/client"; import { logger } from "@/lib/logger"; import { z } from "zod"; const uploadSchema = z.object({ teamId: z.string().min(1, "Team ID is required"), }); export const Route = createFileRoute("/api/teams/upload-logo")({ server: { middleware: [superTokensRequestMiddleware], handlers: { POST: async ({ request, context }) => { try { const userId = context.userAuthId; const isAdmin = context.roles.includes("Admin"); if (!userId) return new Response("Unauthenticated", { status: 401 }); const formData = await request.formData(); const teamId = formData.get("teamId") as string; const logoFile = formData.get("logo") as File; const validationResult = uploadSchema.safeParse({ teamId }); if (!validationResult.success) { return new Response( JSON.stringify({ error: "Invalid input", details: validationResult.error.issues, }), { status: 400, headers: { "Content-Type": "application/json" }, } ); } if (!logoFile || logoFile.size === 0) { return new Response( JSON.stringify({ error: "Logo file is required", }), { status: 400, headers: { "Content-Type": "application/json" }, } ); } const allowedTypes = [ "image/jpeg", "image/jpg", "image/png", "image/gif", ]; if (!allowedTypes.includes(logoFile.type)) { return new Response( JSON.stringify({ error: "Invalid file type. Only JPEG, PNG and GIF are allowed.", }), { status: 400, headers: { "Content-Type": "application/json" }, } ); } const maxSize = 10 * 1024 * 1024; if (logoFile.size > maxSize) { return new Response( JSON.stringify({ error: "File too large. Maximum size is 10MB.", }), { status: 400, headers: { "Content-Type": "application/json" }, } ); } const team = await pbAdmin.getTeam(teamId); if (!team) { return new Response( JSON.stringify({ error: "Team not found", }), { status: 404, headers: { "Content-Type": "application/json" }, } ); } const user = await pbAdmin.getPlayerByAuthId(userId); if (!team.players.map((p) => p.id).includes(user?.id!) && !isAdmin) return new Response("Unauthorized", { status: 403 }); logger.info("Uploading team logo", { teamId, fileName: logoFile.name, fileSize: logoFile.size, userId, }); const pbFormData = new FormData(); pbFormData.append("logo", logoFile); await pbAdmin.updateTeam(teamId, pbFormData as any); const updatedTeam = await pbAdmin.getTeam(teamId); if (!updatedTeam) throw new Error("Failed to fetch updated team"); logger.info("Team logo uploaded successfully", { teamId, logo: updatedTeam.logo, }); return new Response( JSON.stringify({ success: true, team: updatedTeam, message: "Logo uploaded successfully", }), { status: 200, headers: { "Content-Type": "application/json" }, } ); } catch (error: any) { logger.error("Error uploading team logo:", error); return new Response( JSON.stringify({ error: "Failed to upload logo", message: error.message || "Unknown error occurred", }), { status: 500, headers: { "Content-Type": "application/json" }, } ); } }, }, }, });