import { z } from "zod"; export const reportCategories = { inappropriate: "Inappropriate or offensive content", privacy: "Personal or private information", wrong_world: "Wrong world or misleading map", broken: "Broken panorama or map", spam: "Spam or advertising", other: "Other", } as const; export const reportSchema = z .object({ datasetId: z.string().uuid().optional(), sessionId: z.string().uuid().optional(), round: z.number().int().min(0).max(4).optional(), target: z.enum(["map", "panorama"]), category: z.enum( Object.keys(reportCategories) as [ keyof typeof reportCategories, ...Array, ], ), reason: z.string().trim().min(10).max(2000), evidenceUrl: z .string() .trim() .url() .max(1000) .refine( (url) => /^https?:\/\//i.test(url), "Use an HTTP or HTTPS evidence link", ) .optional(), }) .superRefine((report, context) => { if (Boolean(report.datasetId) === Boolean(report.sessionId)) context.addIssue({ code: "custom", message: "Choose a map or a game session", }); if ( report.target === "panorama" && (!report.sessionId || report.round === undefined) ) context.addIssue({ code: "custom", message: "Choose a panorama from your game", }); }); export const contributionCutoff = (now = Date.now()) => new Date(now - 5 * 24 * 60 * 60 * 1000).toISOString();