feat: enhance visit scheduling and closing flow
This commit is contained in:
parent
a7f9191e1d
commit
6473e8d40f
5 changed files with 577 additions and 243 deletions
|
|
@ -32,6 +32,12 @@ const DEFAULT_PHONE_NUMBER = "(11) 4173-5368"
|
|||
const DEFAULT_COMPANY_NAME = "Rever Tecnologia"
|
||||
|
||||
const sanitizeTemplate = (html: string) => stripLeadingEmptyParagraphs(sanitizeEditorHtml(html.trim()))
|
||||
const htmlToPlainText = (value: string) =>
|
||||
value
|
||||
.replace(/<[^>]+>/g, " ")
|
||||
.replace(/ /gi, " ")
|
||||
.replace(/\s+/g, " ")
|
||||
.trim()
|
||||
|
||||
export type AdjustWorkSummaryResult = {
|
||||
ticketId: Id<"tickets">
|
||||
|
|
@ -205,6 +211,9 @@ export function CloseTicketDialog({
|
|||
|
||||
const [selectedTemplateId, setSelectedTemplateId] = useState<string | null>(null)
|
||||
const [message, setMessage] = useState<string>("")
|
||||
const [messageWarning, setMessageWarning] = useState(false)
|
||||
const messagePlainText = useMemo(() => htmlToPlainText(message ?? ""), [message])
|
||||
const hasMessage = messagePlainText.length > 0
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
const [shouldAdjustTime, setShouldAdjustTime] = useState<boolean>(false)
|
||||
const [internalHours, setInternalHours] = useState<string>("0")
|
||||
|
|
@ -228,6 +237,12 @@ export function CloseTicketDialog({
|
|||
|
||||
const draftStorageKey = useMemo(() => `${DRAFT_STORAGE_PREFIX}${ticketId}`, [ticketId])
|
||||
|
||||
useEffect(() => {
|
||||
if (messageWarning && hasMessage) {
|
||||
setMessageWarning(false)
|
||||
}
|
||||
}, [hasMessage, messageWarning])
|
||||
|
||||
const digitsOnlyReference = linkedReference.replace(/[^0-9]/g, "").trim()
|
||||
|
||||
const normalizedReference = useMemo(() => {
|
||||
|
|
@ -540,7 +555,14 @@ export function CloseTicketDialog({
|
|||
setCurrentStep(index)
|
||||
}
|
||||
|
||||
const goToNextStep = () => setCurrentStep((prev) => Math.min(prev + 1, WIZARD_STEPS.length - 1))
|
||||
const goToNextStep = useCallback(() => {
|
||||
if (currentStep === 0 && !hasMessage) {
|
||||
setMessageWarning(true)
|
||||
toast.error("Escreva uma mensagem de encerramento antes de continuar.")
|
||||
return
|
||||
}
|
||||
setCurrentStep((prev) => Math.min(prev + 1, WIZARD_STEPS.length - 1))
|
||||
}, [currentStep, hasMessage])
|
||||
const goToPreviousStep = () => setCurrentStep((prev) => Math.max(prev - 1, 0))
|
||||
const isLastStep = currentStep === WIZARD_STEPS.length - 1
|
||||
|
||||
|
|
@ -930,16 +952,27 @@ export function CloseTicketDialog({
|
|||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div
|
||||
className={cn(
|
||||
"space-y-2 rounded-2xl border px-4 py-3 transition",
|
||||
messageWarning ? "border-amber-500 bg-amber-50/70 shadow-[0_0_0_1px_rgba(251,191,36,0.4)]" : "border-transparent bg-transparent"
|
||||
)}
|
||||
>
|
||||
<p className="text-sm font-medium text-neutral-800">Mensagem de encerramento</p>
|
||||
<RichTextEditor
|
||||
value={message}
|
||||
onChange={setMessage}
|
||||
minHeight={220}
|
||||
placeholder="Escreva uma mensagem final para o cliente..."
|
||||
placeholder="Descreva o encerramento para o cliente..."
|
||||
/>
|
||||
<p className="text-xs text-neutral-500">
|
||||
Você pode editar o conteúdo antes de enviar. Deixe em branco para encerrar sem comentário adicional. O comentário será público e ficará registrado no histórico do ticket.
|
||||
<p
|
||||
className={cn(
|
||||
"text-xs",
|
||||
messageWarning ? "font-semibold text-amber-700" : "text-neutral-500"
|
||||
)}
|
||||
>
|
||||
Este texto é enviado ao cliente e é obrigatório para encerrar o ticket.
|
||||
{messageWarning ? " Digite uma mensagem para prosseguir." : ""}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue