feat: preview de imagens com modal, download com nome correto; cartões (Conversa/Detalhes/Timeline) com sombra e padding; alias '@/convex/_generated/api'; payloads legíveis (nome de fila/responsável, label de status) e timeline amigável; Dropzone no 'Novo ticket' com comentário inicial; microtipografia refinada

This commit is contained in:
esdrasrenan 2025-10-04 01:23:34 -03:00
parent 90c3c8e4d6
commit 44c98fec4a
24 changed files with 1409 additions and 301 deletions

View file

@ -1,14 +1,15 @@
import { z } from "zod";
import {
ticketSchema,
ticketWithDetailsSchema,
ticketEventSchema,
ticketCommentSchema,
userSummarySchema,
} from "@/lib/schemas/ticket";
import { ticketSchema, ticketWithDetailsSchema } from "@/lib/schemas/ticket";
// Server shapes: datas como number (epoch ms) e alguns nullables
const serverUserSchema = userSummarySchema;
// Relaxamos email/urls no shape do servidor para evitar que payloads parciais quebrem o app.
const serverUserSchema = z.object({
id: z.string(),
name: z.string(),
email: z.string().optional(),
avatarUrl: z.string().optional(),
teams: z.array(z.string()).optional(),
});
const serverTicketSchema = z.object({
id: z.string(),
@ -75,7 +76,8 @@ export function mapTicketFromServer(input: unknown) {
firstResponseAt: s.firstResponseAt ? new Date(s.firstResponseAt) : null,
resolvedAt: s.resolvedAt ? new Date(s.resolvedAt) : null,
};
return ticketSchema.parse(ui);
// Já validamos o formato recebido (serverTicketSchema). Retornamos no shape da UI.
return ui as unknown as z.infer<typeof ticketSchema>;
}
export function mapTicketsFromServerList(arr: unknown[]) {
@ -99,5 +101,5 @@ export function mapTicketWithDetailsFromServer(input: unknown) {
updatedAt: new Date(c.updatedAt),
})),
};
return ticketWithDetailsSchema.parse(ui);
return ui as unknown as z.infer<typeof ticketWithDetailsSchema>;
}