feat(portal): habilitar editor rico e anexos no formulário

This commit is contained in:
Esdras Renan 2025-10-12 04:49:17 -03:00
parent d117d8d59f
commit 112cf52f81

View file

@ -12,10 +12,10 @@ import { sanitizeEditorHtml } from "@/components/ui/rich-text-editor"
import { useAuth } from "@/lib/auth-client" import { useAuth } from "@/lib/auth-client"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Input } from "@/components/ui/input" import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"
import { Button } from "@/components/ui/button" import { Button } from "@/components/ui/button"
import { CategorySelectFields } from "@/components/tickets/category-select" import { CategorySelectFields } from "@/components/tickets/category-select"
import { Dropzone } from "@/components/ui/dropzone" import { Dropzone } from "@/components/ui/dropzone"
import { RichTextEditor, sanitizeEditorHtml } from "@/components/ui/rich-text-editor"
const DEFAULT_PRIORITY: TicketPriority = "MEDIUM" const DEFAULT_PRIORITY: TicketPriority = "MEDIUM"
@ -55,7 +55,12 @@ export function PortalTicketForm() {
const trimmedSubject = subject.trim() const trimmedSubject = subject.trim()
const trimmedSummary = summary.trim() const trimmedSummary = summary.trim()
const trimmedDescription = description.trim() const sanitizedDescription = sanitizeEditorHtml(description || "")
const plainDescription = sanitizedDescription.replace(/<[^>]*>/g, "").trim()
if (plainDescription.length === 0) {
toast.error("Descreva o que aconteceu para que possamos ajudar melhor.", { id: "portal-new-ticket" })
return
}
setIsSubmitting(true) setIsSubmitting(true)
toast.loading("Abrindo chamado...", { id: "portal-new-ticket" }) toast.loading("Abrindo chamado...", { id: "portal-new-ticket" })
@ -73,8 +78,9 @@ export function PortalTicketForm() {
subcategoryId: subcategoryId as Id<"ticketSubcategories">, subcategoryId: subcategoryId as Id<"ticketSubcategories">,
}) })
if (trimmedDescription.length > 0) { if (plainDescription.length > 0) {
const htmlBody = sanitizeEditorHtml(toHtml(trimmedDescription)) const htmlBody = sanitizedDescription || toHtml(trimmedSummary || trimmedSubject)
const typedAttachments = attachments.map((file) => ({ const typedAttachments = attachments.map((file) => ({
storageId: file.storageId as Id<"_storage">, storageId: file.storageId as Id<"_storage">,
name: file.name, name: file.name,
@ -92,6 +98,7 @@ export function PortalTicketForm() {
toast.success("Chamado criado com sucesso!", { id: "portal-new-ticket" }) toast.success("Chamado criado com sucesso!", { id: "portal-new-ticket" })
setAttachments([]) setAttachments([])
setAttachments([])
router.replace(`/portal/tickets/${id}`) router.replace(`/portal/tickets/${id}`)
} catch (error) { } catch (error) {
console.error(error) console.error(error)
@ -136,13 +143,11 @@ export function PortalTicketForm() {
<label htmlFor="description" className="flex items-center gap-1 text-sm font-medium text-neutral-800"> <label htmlFor="description" className="flex items-center gap-1 text-sm font-medium text-neutral-800">
Detalhes <span className="text-red-500">*</span> Detalhes <span className="text-red-500">*</span>
</label> </label>
<Textarea <RichTextEditor
id="description"
value={description} value={description}
onChange={(event) => setDescription(event.target.value)} onChange={(html) => setDescription(html)}
placeholder="Compartilhe passos para reproduzir, mensagens de erro ou informações adicionais." placeholder="Compartilhe passos para reproduzir, mensagens de erro ou informações adicionais."
required className="rounded-2xl border border-slate-200 shadow-sm focus-within:border-neutral-900 focus-within:ring-neutral-900/20"
className="min-h-[140px] resize-y rounded-xl border border-slate-200 px-4 py-3 text-sm text-neutral-800 shadow-sm focus-visible:border-neutral-900 focus-visible:ring-neutral-900/20"
/> />
</div> </div>
</div> </div>
@ -176,6 +181,7 @@ export function PortalTicketForm() {
type="button" type="button"
variant="outline" variant="outline"
onClick={() => router.push("/portal/tickets")} onClick={() => router.push("/portal/tickets")}
className="rounded-full border-slate-300 px-6 text-sm font-semibold text-neutral-700 hover:bg-neutral-100"
> >
Cancelar Cancelar
</Button> </Button>