refactor: simplify ticket form and SLA configuration handling

- Removed SLA configuration selection from the TicketForm component to streamline the ticket creation process.
- Updated the abrir-chamado route to eliminate unnecessary SLA loading logic and directly pass loading state to the TicketForm.
- Enhanced the central-chamados route to support SLA configurations by priority, allowing for better management of SLA settings.
- Introduced new mutations for SLA configuration management, including creation, updating, and deletion of SLA settings.
- Improved email templates for ticket notifications, ensuring better communication with users regarding ticket status and updates.
This commit is contained in:
2025-11-16 15:41:16 -03:00
parent 24b8eb6a14
commit fb784d6f7e
6 changed files with 755 additions and 161 deletions

View File

@@ -10,12 +10,9 @@
import { useConvexWithAuth } from "$lib/hooks/useConvexWithAuth";
type Ticket = Doc<"tickets">;
type SlaConfig = Doc<"slaConfigs">;
const client = useConvexClient();
let slaConfigs = $state<Array<SlaConfig>>([]);
let carregandoSla = $state(true);
let submitLoading = $state(false);
let resetSignal = $state(0);
let feedback = $state<{ tipo: "success" | "error"; mensagem: string; numero?: string } | null>(
@@ -42,28 +39,11 @@
},
]);
onMount(() => {
carregarSlaConfigs();
});
$effect(() => {
// Garante que o cliente Convex use o token do usuário logado
useConvexWithAuth();
});
async function carregarSlaConfigs() {
try {
carregandoSla = true;
const lista = await client.query(api.chamados.listarSlaConfigs, {});
slaConfigs = lista ?? [];
} catch (error) {
console.error("Erro ao carregar SLA:", error);
slaConfigs = [];
} finally {
carregandoSla = false;
}
}
async function uploadArquivo(file: File) {
const uploadUrl = await client.mutation(api.chamados.generateUploadUrl, {});
@@ -104,7 +84,6 @@
tipo: values.tipo,
categoria: values.categoria,
prioridade: values.prioridade,
slaConfigId: values.slaConfigId,
canalOrigem: values.canalOrigem,
anexos,
});
@@ -192,53 +171,15 @@
</p>
<div class="mt-6">
{#if resetSignal % 2 === 0}
<TicketForm {slaConfigs} loading={submitLoading} on:submit={handleSubmit} />
<TicketForm loading={submitLoading} on:submit={handleSubmit} />
{:else}
<TicketForm {slaConfigs} loading={submitLoading} on:submit={handleSubmit} />
<TicketForm loading={submitLoading} on:submit={handleSubmit} />
{/if}
</div>
</div>
</div>
<aside class="space-y-6">
<div class="rounded-3xl border border-base-200 bg-base-100/90 p-6 shadow-lg">
<h3 class="font-semibold text-base-content">Configurações de SLA</h3>
{#if carregandoSla}
<div class="flex items-center justify-center py-6">
<span class="loading loading-spinner loading-md"></span>
</div>
{:else if slaConfigs.length === 0}
<p class="text-sm text-base-content/60">
Nenhuma configuração customizada cadastrada. Os prazos padrão serão aplicados (Resposta:
4h, Conclusão: 24h).
</p>
{:else}
<div class="mt-4 space-y-4">
{#each slaConfigs as sla (sla._id)}
<div class="rounded-2xl border border-primary/20 bg-primary/5 p-4">
<p class="text-sm font-semibold text-primary">{sla.nome}</p>
<p class="text-xs text-base-content/60">{sla.descricao}</p>
<div class="mt-3 grid grid-cols-2 gap-2 text-xs">
<div class="rounded-xl bg-base-100/90 p-2 text-center">
<p class="font-semibold">{sla.tempoRespostaHoras}h</p>
<p class="text-base-content/60">Resposta</p>
</div>
<div class="rounded-xl bg-base-100/90 p-2 text-center">
<p class="font-semibold">{sla.tempoConclusaoHoras}h</p>
<p class="text-base-content/60">Conclusão</p>
</div>
</div>
{#if sla.alertaAntecedenciaHoras}
<p class="text-[11px] text-base-content/50 mt-2">
Alerta {sla.alertaAntecedenciaHoras}h antes do prazo.
</p>
{/if}
</div>
{/each}
</div>
{/if}
</div>
<div class="rounded-3xl border border-base-200 bg-base-100/90 p-6 shadow-lg">
<h3 class="font-semibold text-base-content">Como funciona a timeline</h3>
<p class="text-sm text-base-content/60 mb-4">