import { setUserMetadata, superTokensFunctionMiddleware, getSessionContext } from "@/utils/supertokens"; import { createServerFn } from "@tanstack/react-start"; import { isRedirect } from "@tanstack/react-router"; import { Player, playerInputSchema, playerUpdateSchema, PlayerStats } from "@/features/players/types"; import { Match } from "@/features/matches/types"; import { z } from "zod"; import { Logger } from "@/lib/logger"; import { getRequest } from "@tanstack/react-start/server"; import { toServerResult } from "@/lib/tanstack-query/utils/to-server-result"; import { serverFnLoggingMiddleware } from "@/utils/activities"; const logger = new Logger('Players'); export const fetchMe = createServerFn() .handler(async () => toServerResult(async () => { const request = getRequest(); try { const context = await getSessionContext(request); return { user: context.player || undefined, roles: context.roles, metadata: context.metadata, phone: context.phone }; } catch (error: any) { if (isRedirect(error) || error instanceof Response) throw error; return { user: undefined, roles: [], metadata: {}, phone: undefined }; } }) ); export const getPlayer = createServerFn() .validator(z.string()) .middleware([superTokensFunctionMiddleware]) .handler(async ({ data }) => toServerResult(async () => { const { pbAdmin } = await import("@/lib/pocketbase/client"); return await pbAdmin.getPlayer(data); }) ); export const updatePlayer = createServerFn() .validator(playerUpdateSchema) .middleware([superTokensFunctionMiddleware, serverFnLoggingMiddleware]) .handler(async ({ context, data }) => toServerResult(async () => { const userAuthId = context.userAuthId; if (!userAuthId) return; const { pbAdmin } = await import("@/lib/pocketbase/client"); const existing = await pbAdmin.getPlayerByAuthId(userAuthId); if (!existing) return; const updatedPlayer = await pbAdmin.updatePlayer( existing.id!, { first_name: data.first_name, last_name: data.last_name } ); logger.info('Updated player name', updatedPlayer); await setUserMetadata({ data: { first_name: data.first_name, last_name: data.last_name } }); const { emitServerEvent } = await import("@/lib/events/emitter"); emitServerEvent({ type: "player", playerId: existing.id! }); return updatedPlayer; }) ); export const createPlayer = createServerFn() .validator(playerInputSchema) .middleware([superTokensFunctionMiddleware]) .handler(async ({ context, data }) => toServerResult(async () => { const userAuthId = context.userAuthId; if (!userAuthId) return; const { pbAdmin } = await import("@/lib/pocketbase/client"); const existing = await pbAdmin.getPlayerByAuthId(userAuthId); if (existing) return; logger.info('Creating player', data, userAuthId); const newPlayer = await pbAdmin.createPlayer({ auth_id: userAuthId, first_name: data.first_name, last_name: data.last_name }); await setUserMetadata({ data: { first_name: data.first_name, last_name: data.last_name, player_id: newPlayer?.id?.toString() } }); logger.info('Created player', newPlayer); if (newPlayer?.id) { const { emitServerEvent } = await import("@/lib/events/emitter"); emitServerEvent({ type: "player", playerId: newPlayer.id }); } return newPlayer; }) ); export const associatePlayer = createServerFn() .validator(z.string()) .middleware([superTokensFunctionMiddleware, serverFnLoggingMiddleware]) .handler(async ({ context, data }) => toServerResult(async () => { const userAuthId = context.userAuthId; if (!userAuthId) return; const { pbAdmin } = await import("@/lib/pocketbase/client"); const p = await pbAdmin.getPlayer(data); await pbAdmin.updatePlayer(data, { auth_id: userAuthId }); await setUserMetadata({ data: { player_id: data, first_name: p?.first_name, last_name: p?.last_name }}); const player = await pbAdmin.getPlayer(data); logger.info('Associated player', player); const { emitServerEvent } = await import("@/lib/events/emitter"); emitServerEvent({ type: "player", playerId: data }); return player; }) ); export const listPlayers = createServerFn() .middleware([superTokensFunctionMiddleware]) .handler(async () => toServerResult(async () => { const { pbAdmin } = await import("@/lib/pocketbase/client"); return await pbAdmin.listPlayers(); }) ); export const getUnassociatedPlayers = createServerFn() .middleware([superTokensFunctionMiddleware]) .handler(async () => toServerResult(async () => { const { pbAdmin } = await import("@/lib/pocketbase/client"); return await pbAdmin.getUnassociatedPlayers(); }) ); export const getPlayerStats = createServerFn() .validator(z.object({ playerId: z.string(), viewType: z.enum(['all', 'mainline', 'regional']).optional() })) .middleware([superTokensFunctionMiddleware]) .handler(async ({ data }) => toServerResult(async () => { const { pbAdmin } = await import("@/lib/pocketbase/client"); return await pbAdmin.getPlayerStats(data.playerId, data.viewType); }) ); export const getAllPlayerStats = createServerFn() .validator(z.enum(['all', 'mainline', 'regional']).optional()) .middleware([superTokensFunctionMiddleware]) .handler(async ({ data }) => toServerResult(async () => { const { pbAdmin } = await import("@/lib/pocketbase/client"); return await pbAdmin.getAllPlayerStats(data); }) ); export const getPlayerMatches = createServerFn() .validator(z.string()) .middleware([superTokensFunctionMiddleware]) .handler(async ({ data }) => toServerResult(async () => { const { pbAdmin } = await import("@/lib/pocketbase/client"); return await pbAdmin.getPlayerMatches(data); }) ); export const getUnenrolledPlayers = createServerFn() .validator(z.string()) .middleware([superTokensFunctionMiddleware]) .handler(async ({ data: tournamentId }) => toServerResult(async () => { const { pbAdmin } = await import("@/lib/pocketbase/client"); return await pbAdmin.getUnenrolledPlayers(tournamentId); }) ); export const getPlayersActivity = createServerFn() .middleware([superTokensFunctionMiddleware]) .handler(async () => toServerResult(async () => { const { pbAdmin } = await import("@/lib/pocketbase/client"); return await pbAdmin.getPlayersActivity(); }) );