feat(respuesta): CC y adjuntos (10MB) con descarga en el hilo

This commit is contained in:
Nurfog committed 2026-10-22 13:16:29 -03:00
1 parent dd1e1a231a
commit f88d79e2e8
3 files changed
+179 -9

No files matched your search

+60 -2
View File
@@ -136,14 +136,72 @@ export async function getComments(ticketId: number) {
export async function addComment(
ticketId: number,
content: string,
isInternal: boolean = false
isInternal: boolean = false,
cc?: string,
attachmentIds?: number[]
) {
return fetchApi<{ id: number }>(`/api/helpdesk/comments/${ticketId}`, {
method: "POST",
body: JSON.stringify({ content, isInternal }),
body: JSON.stringify({ content, isInternal, cc, attachmentIds }),
});
}
// ==================== Adjuntos del ticket ====================
export interface TicketAttachment {
id: number;
commentId?: number | null;
filename: string;
contentType: string;
size: number;
uploadedBy: string;
createdAt: string;
}
export async function uploadTicketAttachments(ticketId: number, files: File[]) {
const token =
typeof window !== "undefined" ? localStorage.getItem("helpdesk_token") : null;
const form = new FormData();
files.forEach((f) => form.append("files", f));
const res = await fetch(`${API_BASE}/api/helpdesk/ticket/${ticketId}/attachments`, {
method: "POST",
headers: token ? { Authorization: `Bearer ${token}` } : {},
body: form,
});
if (!res.ok) {
const errorData = await res.json().catch(() => ({}));
throw new Error(errorData.message || `API Error: ${res.status}`);
}
return (await res.json()) as { files: { id: number; filename: string; size: number }[] };
}
export async function getTicketAttachments(ticketId: number) {
return fetchApi<TicketAttachment[]>(`/api/helpdesk/ticket/${ticketId}/attachments`);
}
export async function downloadAttachment(attachment: TicketAttachment) {
const token =
typeof window !== "undefined" ? localStorage.getItem("helpdesk_token") : null;
const res = await fetch(`${API_BASE}/api/helpdesk/attachments/${attachment.id}`, {
headers: token ? { Authorization: `Bearer ${token}` } : {},
});
if (!res.ok) throw new Error(`No se pudo descargar (${res.status})`);
const blob = await res.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = attachment.filename;
document.body.appendChild(a);
a.click();
a.remove();
setTimeout(() => URL.revokeObjectURL(url), 5000);
}
export function formatFileSize(bytes: number): string {
if (bytes < 1024) return `${bytes} B`;
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}
// ==================== Historial de correos del ticket ====================
// Integración email <-> ticket: enviados desde soporte (mail.log) +
// respuestas recibidas (helpdesk.email_inbound). Visible para quien