analytica-frontend-lib 1.7.20 → 1.7.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/dist/ActivitiesHistory/index.js +6 -6
  2. package/dist/ActivitiesHistory/index.mjs +6 -6
  3. package/dist/ActivityCardQuestionBanks/index.js +6 -6
  4. package/dist/ActivityCardQuestionBanks/index.mjs +6 -6
  5. package/dist/ActivityCardQuestionPreview/index.js +6 -6
  6. package/dist/ActivityCardQuestionPreview/index.mjs +6 -6
  7. package/dist/ActivityCreate/ActivityCreateContent/index.js +6 -6
  8. package/dist/ActivityCreate/ActivityCreateContent/index.mjs +6 -6
  9. package/dist/ActivityCreate/index.js +6 -6
  10. package/dist/ActivityCreate/index.mjs +6 -6
  11. package/dist/ActivityDetails/index.js +6 -6
  12. package/dist/ActivityDetails/index.mjs +6 -6
  13. package/dist/ActivityFilters/index.js +6 -6
  14. package/dist/ActivityFilters/index.mjs +6 -6
  15. package/dist/ActivityPageLayout/index.js +6 -6
  16. package/dist/ActivityPageLayout/index.mjs +6 -6
  17. package/dist/ActivityPreview/index.js +6 -6
  18. package/dist/ActivityPreview/index.mjs +6 -6
  19. package/dist/AlertManager/index.js +6 -6
  20. package/dist/AlertManager/index.mjs +6 -6
  21. package/dist/CheckBoxGroup/index.js +6 -6
  22. package/dist/CheckBoxGroup/index.mjs +6 -6
  23. package/dist/EnemMoment/index.js +6 -6
  24. package/dist/EnemMoment/index.mjs +6 -6
  25. package/dist/EnemMomentStudentModal/index.js +6 -6
  26. package/dist/EnemMomentStudentModal/index.mjs +6 -6
  27. package/dist/ExamDetailsLayout/ExamDetailsPage/index.js +6 -6
  28. package/dist/ExamDetailsLayout/ExamDetailsPage/index.mjs +6 -6
  29. package/dist/ExamPageLayout/index.js +6 -6
  30. package/dist/ExamPageLayout/index.mjs +6 -6
  31. package/dist/KnowledgePerformanceCard/index.js +6 -6
  32. package/dist/KnowledgePerformanceCard/index.mjs +6 -6
  33. package/dist/LessonCardPreview/index.js +6 -6
  34. package/dist/LessonCardPreview/index.mjs +6 -6
  35. package/dist/LessonMediaSections/index.js +6 -6
  36. package/dist/LessonMediaSections/index.mjs +6 -6
  37. package/dist/LessonsCatalog/index.js +6 -6
  38. package/dist/LessonsCatalog/index.mjs +6 -6
  39. package/dist/PrintableUsersTable/index.js +6 -6
  40. package/dist/PrintableUsersTable/index.mjs +6 -6
  41. package/dist/QuestionsPerformanceCard/index.js +6 -6
  42. package/dist/QuestionsPerformanceCard/index.mjs +6 -6
  43. package/dist/RecommendedLessonCreate/index.js +6 -6
  44. package/dist/RecommendedLessonCreate/index.mjs +6 -6
  45. package/dist/RecommendedLessonsHistory/index.js +6 -6
  46. package/dist/RecommendedLessonsHistory/index.mjs +6 -6
  47. package/dist/SendActivityModal/SendActivityModal.js +6 -6
  48. package/dist/SendActivityModal/SendActivityModal.mjs +6 -6
  49. package/dist/SendActivityModal/index.js +6 -6
  50. package/dist/SendActivityModal/index.mjs +6 -6
  51. package/dist/SendLessonModal/index.js +6 -6
  52. package/dist/SendLessonModal/index.mjs +6 -6
  53. package/dist/SimulatedPerformance/SimulatedPerformanceView/index.js +6 -6
  54. package/dist/SimulatedPerformance/SimulatedPerformanceView/index.mjs +6 -6
  55. package/dist/SimulationsPage/index.js +6 -6
  56. package/dist/SimulationsPage/index.mjs +6 -6
  57. package/dist/Support/TicketModal/index.js +3 -3
  58. package/dist/Support/TicketModal/index.mjs +2 -2
  59. package/dist/Support/index.js +4 -4
  60. package/dist/Support/index.mjs +3 -3
  61. package/dist/SupportChatWidget/index.js +3 -3
  62. package/dist/SupportChatWidget/index.mjs +2 -2
  63. package/dist/SupportUserPanel/index.js +3 -3
  64. package/dist/SupportUserPanel/index.mjs +2 -2
  65. package/dist/TableProvider/index.js +6 -6
  66. package/dist/TableProvider/index.mjs +6 -6
  67. package/dist/UnifiedDraftModelPage/index.js +6 -6
  68. package/dist/UnifiedDraftModelPage/index.mjs +6 -6
  69. package/dist/UnifiedHistoryPage/index.js +6 -6
  70. package/dist/UnifiedHistoryPage/index.mjs +6 -6
  71. package/dist/{chunk-NP6KVOAV.js → chunk-64WFAQC6.js} +13 -2
  72. package/dist/chunk-64WFAQC6.js.map +1 -0
  73. package/dist/{chunk-56PRQ24B.mjs → chunk-7LS5UQCQ.mjs} +7 -5
  74. package/dist/chunk-7LS5UQCQ.mjs.map +1 -0
  75. package/dist/{chunk-PH2DDIS4.mjs → chunk-B4QODMQ5.mjs} +1 -1
  76. package/dist/{chunk-PH2DDIS4.mjs.map → chunk-B4QODMQ5.mjs.map} +1 -1
  77. package/dist/{chunk-TVWATS3U.mjs → chunk-C4SBX6R2.mjs} +11 -4
  78. package/dist/chunk-C4SBX6R2.mjs.map +1 -0
  79. package/dist/{chunk-FLGSHGJY.js → chunk-CYSODZGX.js} +8 -2
  80. package/dist/chunk-CYSODZGX.js.map +1 -0
  81. package/dist/{chunk-OMBS4ACE.mjs → chunk-MVT7IVMY.mjs} +12 -1
  82. package/dist/chunk-MVT7IVMY.mjs.map +1 -0
  83. package/dist/{chunk-KBWT73XY.mjs → chunk-OES54VU6.mjs} +8 -2
  84. package/dist/{chunk-KBWT73XY.mjs.map → chunk-OES54VU6.mjs.map} +1 -1
  85. package/dist/{chunk-BWTNSVJE.js → chunk-OGD2ATAP.js} +1 -1
  86. package/dist/{chunk-BWTNSVJE.js.map → chunk-OGD2ATAP.js.map} +1 -1
  87. package/dist/{chunk-DXA4VBUN.mjs → chunk-VKQ5AJDT.mjs} +2 -2
  88. package/dist/{chunk-HE66Y2T3.js → chunk-VQ7MSYIH.js} +5 -5
  89. package/dist/{chunk-HE66Y2T3.js.map → chunk-VQ7MSYIH.js.map} +1 -1
  90. package/dist/{chunk-IMMKWOYJ.js → chunk-WUXIPIUG.js} +42 -35
  91. package/dist/chunk-WUXIPIUG.js.map +1 -0
  92. package/dist/{chunk-SQDLSJBL.js → chunk-YRTIDZTN.js} +15 -13
  93. package/dist/chunk-YRTIDZTN.js.map +1 -0
  94. package/dist/components/Support/Support.d.ts +4 -2
  95. package/dist/components/Support/Support.d.ts.map +1 -1
  96. package/dist/components/SupportChatWidget/guestSupportChatAdapter.d.ts.map +1 -1
  97. package/dist/components/SupportUserPanel/SupportHistoryTab.d.ts.map +1 -1
  98. package/dist/components/SupportUserPanel/SupportTicketDetailsTab.d.ts.map +1 -1
  99. package/dist/hooks/useAppContent/index.js +6 -6
  100. package/dist/hooks/useAppContent/index.mjs +6 -6
  101. package/dist/hooks/useSupportFeatureFlag/index.js +1 -1
  102. package/dist/hooks/useSupportFeatureFlag/index.mjs +1 -1
  103. package/dist/index.d.ts +2 -2
  104. package/dist/index.d.ts.map +1 -1
  105. package/dist/index.js +11 -7
  106. package/dist/index.js.map +1 -1
  107. package/dist/index.mjs +10 -6
  108. package/dist/types/support/index.d.ts +20 -0
  109. package/dist/types/support/index.d.ts.map +1 -1
  110. package/dist/types/support/index.js +6 -2
  111. package/dist/types/support/index.js.map +1 -1
  112. package/dist/types/support/index.mjs +5 -1
  113. package/dist/types/supportUserPanel/index.d.ts +7 -0
  114. package/dist/types/supportUserPanel/index.d.ts.map +1 -1
  115. package/dist/types/supportUserPanel/index.js +2 -2
  116. package/dist/types/supportUserPanel/index.mjs +1 -1
  117. package/dist/types/supportUserPanel.d.ts +7 -0
  118. package/dist/types/supportUserPanel.d.ts.map +1 -1
  119. package/package.json +1 -1
  120. package/dist/chunk-56PRQ24B.mjs.map +0 -1
  121. package/dist/chunk-FLGSHGJY.js.map +0 -1
  122. package/dist/chunk-IMMKWOYJ.js.map +0 -1
  123. package/dist/chunk-NP6KVOAV.js.map +0 -1
  124. package/dist/chunk-OMBS4ACE.mjs.map +0 -1
  125. package/dist/chunk-SQDLSJBL.js.map +0 -1
  126. package/dist/chunk-TVWATS3U.mjs.map +0 -1
  127. /package/dist/{chunk-DXA4VBUN.mjs.map → chunk-VKQ5AJDT.mjs.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-HE66Y2T3.js","../src/components/Support/components/TicketModal.tsx","../src/components/Support/utils/supportUtils.tsx"],"names":["jsx"],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-HE66Y2T3.js","sourcesContent":[null,"import { useState, useEffect, useCallback } from 'react';\nimport dayjs from 'dayjs';\nimport 'dayjs/locale/pt-br';\nimport Badge from '../../Badge/Badge';\nimport Button from '../../Button/Button';\nimport Divider from '../../Divider/Divider';\nimport Modal from '../../Modal/Modal';\nimport Text from '../../Text/Text';\nimport TextArea from '../../TextArea/TextArea';\nimport { SkeletonText } from '../../Skeleton/Skeleton';\nimport {\n SupportTicket,\n SupportStatus,\n SupportAnswerAPI,\n GetSupportAnswersResponse,\n SubmitSupportAnswerRequest,\n SubmitSupportAnswerResponse,\n getStatusBadgeAction,\n getStatusText,\n getCategoryText,\n SupportApiClient,\n} from '../../../types/support';\nimport { getCategoryIcon } from '../utils/supportUtils';\n\ndayjs.locale('pt-br');\n\n// Skeleton component for answer loading\nconst AnswerSkeleton = () => (\n <div className=\"bg-background p-4 space-y-6 rounded-xl\">\n {/* Date skeleton */}\n <div className=\"flex items-center space-x-6\">\n <SkeletonText width=\"80px\" height={16} />\n <SkeletonText width=\"200px\" height={16} />\n </div>\n\n <Divider />\n\n {/* Answer content skeleton */}\n <div className=\"flex items-start space-x-6\">\n <SkeletonText width=\"80px\" height={16} />\n <div className=\"flex-1 space-y-2\">\n <SkeletonText width=\"100%\" height={16} />\n <SkeletonText width=\"80%\" height={16} />\n <SkeletonText width=\"60%\" height={16} />\n </div>\n </div>\n </div>\n);\n\nexport interface TicketModalProps {\n ticket: SupportTicket;\n isOpen: boolean;\n onClose: () => void;\n onTicketClose?: (ticketId: string) => void;\n /** API client instance for making requests */\n apiClient: SupportApiClient;\n /** Current user ID */\n userId?: string;\n}\n\nexport const TicketModal = ({\n ticket,\n isOpen,\n onClose,\n onTicketClose,\n apiClient,\n userId,\n}: TicketModalProps) => {\n const [showCloseConfirmation, setShowCloseConfirmation] = useState(false);\n const [responseText, setResponseText] = useState('');\n const [answers, setAnswers] = useState<SupportAnswerAPI[]>([]);\n const [isSubmittingAnswer, setIsSubmittingAnswer] = useState(false);\n const [isLoadingAnswers, setIsLoadingAnswers] = useState(false);\n\n const handleCloseTicket = () => {\n onTicketClose?.(ticket.id);\n setShowCloseConfirmation(false);\n onClose();\n };\n\n // Fetch support answers\n const fetchAnswers = useCallback(async () => {\n if (!ticket.id || ticket.status !== SupportStatus.RESPONDIDO) return;\n\n setIsLoadingAnswers(true);\n try {\n const response = await apiClient.get<GetSupportAnswersResponse>(\n `/support/answer/${ticket.id}`\n );\n setAnswers(response.data.data || []);\n } catch (error) {\n console.error('Erro ao buscar respostas:', error);\n setAnswers([]);\n } finally {\n setIsLoadingAnswers(false);\n }\n }, [ticket.id, ticket.status, apiClient]);\n\n // Submit user answer\n const handleSubmitAnswer = async () => {\n if (!responseText.trim() || !userId || !ticket.id) {\n return;\n }\n\n setIsSubmittingAnswer(true);\n try {\n const requestData: SubmitSupportAnswerRequest = {\n userId: userId,\n supportId: ticket.id,\n answer: responseText.trim(),\n };\n\n await apiClient.post<SubmitSupportAnswerResponse>(\n '/support/answer',\n requestData\n );\n\n // Clear response text\n setResponseText('');\n\n // Refresh answers list\n await fetchAnswers();\n } catch (error) {\n console.error('Erro ao enviar resposta:', error);\n } finally {\n setIsSubmittingAnswer(false);\n }\n };\n\n const canCloseTicket = ticket.status !== SupportStatus.ENCERRADO;\n\n // Limpar o texto e carregar respostas quando o modal for aberto\n useEffect(() => {\n if (isOpen) {\n setResponseText('');\n (async () => {\n await fetchAnswers();\n })().catch((error) => {\n console.error('Erro ao carregar respostas:', error);\n });\n } else {\n setAnswers([]);\n }\n }, [isOpen, fetchAnswers]);\n\n return (\n <>\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={`Pedido: ${ticket.title}`}\n size=\"lg\"\n hideCloseButton={false}\n closeOnEscape={true}\n data-testid=\"ticket-modal\"\n >\n <div className=\"flex flex-col h-full max-h-[80vh]\">\n {/* Header com botão Encerrar Pedido */}\n <div className=\"flex justify-between items-center mb-3\">\n <Text size=\"md\" weight=\"bold\" className=\"text-text-950\">\n Detalhes\n </Text>\n {canCloseTicket && (\n <Button\n variant=\"outline\"\n size=\"small\"\n action=\"negative\"\n onClick={() => setShowCloseConfirmation(true)}\n >\n Encerrar Pedido\n </Button>\n )}\n </div>\n\n {/* Conteúdo com scroll */}\n <div className=\"flex-1 overflow-y-auto pr-2 space-y-6\">\n <div className=\"bg-background p-4 space-y-6 rounded-xl\">\n {/* ID */}\n <div className=\"flex items-center space-x-6\">\n <Text\n size=\"md\"\n weight=\"semibold\"\n className=\"text-text-700 w-20\"\n >\n ID\n </Text>\n <Text size=\"md\" weight=\"normal\" className=\"text-text-600\">\n {ticket.id}\n </Text>\n </div>\n\n {/* Aberto em */}\n <div className=\"flex items-center space-x-6\">\n <Text\n size=\"md\"\n weight=\"semibold\"\n className=\"text-text-700 w-20\"\n >\n Aberto em\n </Text>\n <Text size=\"md\" weight=\"normal\" className=\"text-text-600\">\n {dayjs(ticket.createdAt).format('DD MMMM YYYY, [às] HH[h]')}\n </Text>\n </div>\n\n {/* Status */}\n <div className=\"flex items-center space-x-6\">\n <Text\n size=\"md\"\n weight=\"semibold\"\n className=\"text-text-700 w-20\"\n >\n Status\n </Text>\n <Badge\n variant=\"solid\"\n size=\"small\"\n action={getStatusBadgeAction(ticket.status)}\n className=\"w-fit\"\n >\n {getStatusText(ticket.status)}\n </Badge>\n </div>\n\n {/* Tipo */}\n <div className=\"flex items-center space-x-6\">\n <Text\n size=\"md\"\n weight=\"semibold\"\n className=\"text-text-700 w-20\"\n >\n Tipo\n </Text>\n <Badge\n variant=\"solid\"\n size=\"small\"\n action=\"muted\"\n className=\"w-fit\"\n >\n {getCategoryIcon(ticket.category)}\n {getCategoryText(ticket.category)}\n </Badge>\n </div>\n\n <Divider />\n\n {/* Descrição */}\n <div className=\"flex items-start space-x-6\">\n <Text\n size=\"md\"\n weight=\"semibold\"\n className=\"text-text-700 w-20\"\n >\n Descrição\n </Text>\n {ticket.description && (\n <Text size=\"md\" weight=\"normal\" className=\"text-text-600\">\n {ticket.description}\n </Text>\n )}\n </div>\n </div>\n\n {/* Seção de resposta (quando há respostas do suporte ou carregando) */}\n {ticket.status === SupportStatus.RESPONDIDO && isLoadingAnswers && (\n <>\n <Text size=\"md\" weight=\"bold\" className=\"text-text-950 my-6\">\n Resposta de Suporte Técnico\n </Text>\n <AnswerSkeleton />\n </>\n )}\n\n {/* Seção de resposta (quando há respostas do suporte) */}\n {!isLoadingAnswers &&\n answers.some((answer) => answer.userId !== userId) && (\n <>\n <Text size=\"md\" weight=\"bold\" className=\"text-text-950 my-6\">\n Resposta de Suporte Técnico\n </Text>\n\n {answers\n .filter((answer) => answer.userId !== userId)\n .sort(\n (a, b) =>\n new Date(b.createdAt).getTime() -\n new Date(a.createdAt).getTime()\n )\n .slice(0, 1)\n .map((answer) => (\n <div\n key={answer.id}\n className=\"bg-background p-4 space-y-6 rounded-xl\"\n >\n {/* Recebido em */}\n <div className=\"flex items-center space-x-6\">\n <Text\n size=\"md\"\n weight=\"semibold\"\n className=\"text-text-700 w-20\"\n >\n Recebido\n </Text>\n <Text\n size=\"md\"\n weight=\"normal\"\n className=\"text-text-600\"\n >\n {dayjs(answer.createdAt).format(\n 'DD MMMM YYYY, [às] HH[h]'\n )}\n </Text>\n </div>\n\n <Divider />\n\n {/* Resposta */}\n <div className=\"flex items-start space-x-6\">\n <Text\n size=\"md\"\n weight=\"semibold\"\n className=\"text-text-700 w-20\"\n >\n Resposta\n </Text>\n <Text\n size=\"md\"\n weight=\"normal\"\n className=\"text-text-600\"\n >\n {answer.answer}\n </Text>\n </div>\n </div>\n ))}\n </>\n )}\n\n {/* Seção de resposta do usuário */}\n {!isLoadingAnswers &&\n answers.some((answer) => answer.userId === userId) && (\n <>\n <Text size=\"md\" weight=\"bold\" className=\"text-text-950 my-6\">\n Resposta enviada\n </Text>\n\n {answers\n .filter((answer) => answer.userId === userId)\n .sort(\n (a, b) =>\n new Date(b.createdAt).getTime() -\n new Date(a.createdAt).getTime()\n )\n .slice(0, 1)\n .map((answer) => (\n <div\n key={answer.id}\n className=\"bg-background p-4 space-y-6 rounded-xl\"\n >\n {/* Enviada em */}\n <div className=\"flex items-center space-x-6\">\n <Text\n size=\"md\"\n weight=\"semibold\"\n className=\"text-text-700 w-20\"\n >\n Enviada\n </Text>\n <Text\n size=\"md\"\n weight=\"normal\"\n className=\"text-text-600\"\n >\n {dayjs(answer.createdAt).format(\n 'DD MMMM YYYY, [às] HH[h]'\n )}\n </Text>\n </div>\n\n <Divider />\n\n {/* Resposta */}\n <div className=\"flex items-start space-x-6\">\n <Text\n size=\"md\"\n weight=\"semibold\"\n className=\"text-text-700 w-20\"\n >\n Resposta\n </Text>\n <Text\n size=\"md\"\n weight=\"normal\"\n className=\"text-text-600\"\n >\n {answer.answer}\n </Text>\n </div>\n </div>\n ))}\n </>\n )}\n\n {/* Seção Responder */}\n {!isLoadingAnswers &&\n answers.some((answer) => answer.userId !== userId) && (\n <>\n <Text size=\"lg\" weight=\"bold\" className=\"text-text-950 my-6\">\n Responder\n </Text>\n\n <div className=\"space-y-4\">\n <TextArea\n placeholder=\"Detalhe o problema aqui.\"\n rows={4}\n className=\"w-full\"\n value={responseText}\n onChange={(e) => setResponseText(e.target.value)}\n />\n\n {responseText.trim().length > 0 && (\n <div className=\"flex justify-end\">\n <Button\n variant=\"solid\"\n size=\"medium\"\n onClick={handleSubmitAnswer}\n disabled={isSubmittingAnswer}\n >\n {isSubmittingAnswer ? 'Enviando...' : 'Enviar'}\n </Button>\n </div>\n )}\n </div>\n </>\n )}\n </div>\n </div>\n </Modal>\n\n {/* Modal de confirmação de encerramento */}\n <Modal\n isOpen={showCloseConfirmation}\n onClose={() => setShowCloseConfirmation(false)}\n title=\"Encerrar pedido?\"\n size=\"md\"\n hideCloseButton={false}\n closeOnEscape={true}\n data-testid=\"close-ticket-modal\"\n >\n <div className=\"space-y-6\">\n <Text size=\"sm\" weight=\"normal\" className=\"text-text-700\">\n Ao encerrar este pedido, ele será fechado e não poderá mais ser\n atualizado.\n </Text>\n\n <div className=\"flex gap-3 justify-end\">\n <Button\n variant=\"outline\"\n size=\"medium\"\n onClick={() => setShowCloseConfirmation(false)}\n >\n Cancelar\n </Button>\n <Button\n variant=\"solid\"\n size=\"medium\"\n action=\"negative\"\n onClick={handleCloseTicket}\n >\n Encerrar\n </Button>\n </div>\n </div>\n </Modal>\n </>\n );\n};\n","import { KeyIcon, BugIcon, InfoIcon } from '@phosphor-icons/react';\nimport React from 'react';\nimport { SupportCategory } from '../../../types/support';\n\nexport const getCategoryIcon = (\n category: SupportCategory | null,\n size = 16\n): React.ReactNode => {\n if (!category) return null;\n switch (category) {\n case SupportCategory.ACESSO:\n return <KeyIcon size={size} />;\n case SupportCategory.TECNICO:\n return <BugIcon size={size} />;\n case SupportCategory.OUTROS:\n return <InfoIcon size={size} />;\n default:\n return <InfoIcon size={size} />;\n }\n};\n"]}
1
+ {"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-VQ7MSYIH.js","../src/components/Support/components/TicketModal.tsx","../src/components/Support/utils/supportUtils.tsx"],"names":["jsx"],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-VQ7MSYIH.js","sourcesContent":[null,"import { useState, useEffect, useCallback } from 'react';\nimport dayjs from 'dayjs';\nimport 'dayjs/locale/pt-br';\nimport Badge from '../../Badge/Badge';\nimport Button from '../../Button/Button';\nimport Divider from '../../Divider/Divider';\nimport Modal from '../../Modal/Modal';\nimport Text from '../../Text/Text';\nimport TextArea from '../../TextArea/TextArea';\nimport { SkeletonText } from '../../Skeleton/Skeleton';\nimport {\n SupportTicket,\n SupportStatus,\n SupportAnswerAPI,\n GetSupportAnswersResponse,\n SubmitSupportAnswerRequest,\n SubmitSupportAnswerResponse,\n getStatusBadgeAction,\n getStatusText,\n getCategoryText,\n SupportApiClient,\n} from '../../../types/support';\nimport { getCategoryIcon } from '../utils/supportUtils';\n\ndayjs.locale('pt-br');\n\n// Skeleton component for answer loading\nconst AnswerSkeleton = () => (\n <div className=\"bg-background p-4 space-y-6 rounded-xl\">\n {/* Date skeleton */}\n <div className=\"flex items-center space-x-6\">\n <SkeletonText width=\"80px\" height={16} />\n <SkeletonText width=\"200px\" height={16} />\n </div>\n\n <Divider />\n\n {/* Answer content skeleton */}\n <div className=\"flex items-start space-x-6\">\n <SkeletonText width=\"80px\" height={16} />\n <div className=\"flex-1 space-y-2\">\n <SkeletonText width=\"100%\" height={16} />\n <SkeletonText width=\"80%\" height={16} />\n <SkeletonText width=\"60%\" height={16} />\n </div>\n </div>\n </div>\n);\n\nexport interface TicketModalProps {\n ticket: SupportTicket;\n isOpen: boolean;\n onClose: () => void;\n onTicketClose?: (ticketId: string) => void;\n /** API client instance for making requests */\n apiClient: SupportApiClient;\n /** Current user ID */\n userId?: string;\n}\n\nexport const TicketModal = ({\n ticket,\n isOpen,\n onClose,\n onTicketClose,\n apiClient,\n userId,\n}: TicketModalProps) => {\n const [showCloseConfirmation, setShowCloseConfirmation] = useState(false);\n const [responseText, setResponseText] = useState('');\n const [answers, setAnswers] = useState<SupportAnswerAPI[]>([]);\n const [isSubmittingAnswer, setIsSubmittingAnswer] = useState(false);\n const [isLoadingAnswers, setIsLoadingAnswers] = useState(false);\n\n const handleCloseTicket = () => {\n onTicketClose?.(ticket.id);\n setShowCloseConfirmation(false);\n onClose();\n };\n\n // Fetch support answers\n const fetchAnswers = useCallback(async () => {\n if (!ticket.id || ticket.status !== SupportStatus.RESPONDIDO) return;\n\n setIsLoadingAnswers(true);\n try {\n const response = await apiClient.get<GetSupportAnswersResponse>(\n `/support/answer/${ticket.id}`\n );\n setAnswers(response.data.data || []);\n } catch (error) {\n console.error('Erro ao buscar respostas:', error);\n setAnswers([]);\n } finally {\n setIsLoadingAnswers(false);\n }\n }, [ticket.id, ticket.status, apiClient]);\n\n // Submit user answer\n const handleSubmitAnswer = async () => {\n if (!responseText.trim() || !userId || !ticket.id) {\n return;\n }\n\n setIsSubmittingAnswer(true);\n try {\n const requestData: SubmitSupportAnswerRequest = {\n userId: userId,\n supportId: ticket.id,\n answer: responseText.trim(),\n };\n\n await apiClient.post<SubmitSupportAnswerResponse>(\n '/support/answer',\n requestData\n );\n\n // Clear response text\n setResponseText('');\n\n // Refresh answers list\n await fetchAnswers();\n } catch (error) {\n console.error('Erro ao enviar resposta:', error);\n } finally {\n setIsSubmittingAnswer(false);\n }\n };\n\n const canCloseTicket = ticket.status !== SupportStatus.ENCERRADO;\n\n // Limpar o texto e carregar respostas quando o modal for aberto\n useEffect(() => {\n if (isOpen) {\n setResponseText('');\n (async () => {\n await fetchAnswers();\n })().catch((error) => {\n console.error('Erro ao carregar respostas:', error);\n });\n } else {\n setAnswers([]);\n }\n }, [isOpen, fetchAnswers]);\n\n return (\n <>\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={`Pedido: ${ticket.title}`}\n size=\"lg\"\n hideCloseButton={false}\n closeOnEscape={true}\n data-testid=\"ticket-modal\"\n >\n <div className=\"flex flex-col h-full max-h-[80vh]\">\n {/* Header com botão Encerrar Pedido */}\n <div className=\"flex justify-between items-center mb-3\">\n <Text size=\"md\" weight=\"bold\" className=\"text-text-950\">\n Detalhes\n </Text>\n {canCloseTicket && (\n <Button\n variant=\"outline\"\n size=\"small\"\n action=\"negative\"\n onClick={() => setShowCloseConfirmation(true)}\n >\n Encerrar Pedido\n </Button>\n )}\n </div>\n\n {/* Conteúdo com scroll */}\n <div className=\"flex-1 overflow-y-auto pr-2 space-y-6\">\n <div className=\"bg-background p-4 space-y-6 rounded-xl\">\n {/* ID */}\n <div className=\"flex items-center space-x-6\">\n <Text\n size=\"md\"\n weight=\"semibold\"\n className=\"text-text-700 w-20\"\n >\n ID\n </Text>\n <Text size=\"md\" weight=\"normal\" className=\"text-text-600\">\n {ticket.id}\n </Text>\n </div>\n\n {/* Aberto em */}\n <div className=\"flex items-center space-x-6\">\n <Text\n size=\"md\"\n weight=\"semibold\"\n className=\"text-text-700 w-20\"\n >\n Aberto em\n </Text>\n <Text size=\"md\" weight=\"normal\" className=\"text-text-600\">\n {dayjs(ticket.createdAt).format('DD MMMM YYYY, [às] HH[h]')}\n </Text>\n </div>\n\n {/* Status */}\n <div className=\"flex items-center space-x-6\">\n <Text\n size=\"md\"\n weight=\"semibold\"\n className=\"text-text-700 w-20\"\n >\n Status\n </Text>\n <Badge\n variant=\"solid\"\n size=\"small\"\n action={getStatusBadgeAction(ticket.status)}\n className=\"w-fit\"\n >\n {getStatusText(ticket.status)}\n </Badge>\n </div>\n\n {/* Tipo */}\n <div className=\"flex items-center space-x-6\">\n <Text\n size=\"md\"\n weight=\"semibold\"\n className=\"text-text-700 w-20\"\n >\n Tipo\n </Text>\n <Badge\n variant=\"solid\"\n size=\"small\"\n action=\"muted\"\n className=\"w-fit\"\n >\n {getCategoryIcon(ticket.category)}\n {getCategoryText(ticket.category)}\n </Badge>\n </div>\n\n <Divider />\n\n {/* Descrição */}\n <div className=\"flex items-start space-x-6\">\n <Text\n size=\"md\"\n weight=\"semibold\"\n className=\"text-text-700 w-20\"\n >\n Descrição\n </Text>\n {ticket.description && (\n <Text size=\"md\" weight=\"normal\" className=\"text-text-600\">\n {ticket.description}\n </Text>\n )}\n </div>\n </div>\n\n {/* Seção de resposta (quando há respostas do suporte ou carregando) */}\n {ticket.status === SupportStatus.RESPONDIDO && isLoadingAnswers && (\n <>\n <Text size=\"md\" weight=\"bold\" className=\"text-text-950 my-6\">\n Resposta de Suporte Técnico\n </Text>\n <AnswerSkeleton />\n </>\n )}\n\n {/* Seção de resposta (quando há respostas do suporte) */}\n {!isLoadingAnswers &&\n answers.some((answer) => answer.userId !== userId) && (\n <>\n <Text size=\"md\" weight=\"bold\" className=\"text-text-950 my-6\">\n Resposta de Suporte Técnico\n </Text>\n\n {answers\n .filter((answer) => answer.userId !== userId)\n .sort(\n (a, b) =>\n new Date(b.createdAt).getTime() -\n new Date(a.createdAt).getTime()\n )\n .slice(0, 1)\n .map((answer) => (\n <div\n key={answer.id}\n className=\"bg-background p-4 space-y-6 rounded-xl\"\n >\n {/* Recebido em */}\n <div className=\"flex items-center space-x-6\">\n <Text\n size=\"md\"\n weight=\"semibold\"\n className=\"text-text-700 w-20\"\n >\n Recebido\n </Text>\n <Text\n size=\"md\"\n weight=\"normal\"\n className=\"text-text-600\"\n >\n {dayjs(answer.createdAt).format(\n 'DD MMMM YYYY, [às] HH[h]'\n )}\n </Text>\n </div>\n\n <Divider />\n\n {/* Resposta */}\n <div className=\"flex items-start space-x-6\">\n <Text\n size=\"md\"\n weight=\"semibold\"\n className=\"text-text-700 w-20\"\n >\n Resposta\n </Text>\n <Text\n size=\"md\"\n weight=\"normal\"\n className=\"text-text-600\"\n >\n {answer.answer}\n </Text>\n </div>\n </div>\n ))}\n </>\n )}\n\n {/* Seção de resposta do usuário */}\n {!isLoadingAnswers &&\n answers.some((answer) => answer.userId === userId) && (\n <>\n <Text size=\"md\" weight=\"bold\" className=\"text-text-950 my-6\">\n Resposta enviada\n </Text>\n\n {answers\n .filter((answer) => answer.userId === userId)\n .sort(\n (a, b) =>\n new Date(b.createdAt).getTime() -\n new Date(a.createdAt).getTime()\n )\n .slice(0, 1)\n .map((answer) => (\n <div\n key={answer.id}\n className=\"bg-background p-4 space-y-6 rounded-xl\"\n >\n {/* Enviada em */}\n <div className=\"flex items-center space-x-6\">\n <Text\n size=\"md\"\n weight=\"semibold\"\n className=\"text-text-700 w-20\"\n >\n Enviada\n </Text>\n <Text\n size=\"md\"\n weight=\"normal\"\n className=\"text-text-600\"\n >\n {dayjs(answer.createdAt).format(\n 'DD MMMM YYYY, [às] HH[h]'\n )}\n </Text>\n </div>\n\n <Divider />\n\n {/* Resposta */}\n <div className=\"flex items-start space-x-6\">\n <Text\n size=\"md\"\n weight=\"semibold\"\n className=\"text-text-700 w-20\"\n >\n Resposta\n </Text>\n <Text\n size=\"md\"\n weight=\"normal\"\n className=\"text-text-600\"\n >\n {answer.answer}\n </Text>\n </div>\n </div>\n ))}\n </>\n )}\n\n {/* Seção Responder */}\n {!isLoadingAnswers &&\n answers.some((answer) => answer.userId !== userId) && (\n <>\n <Text size=\"lg\" weight=\"bold\" className=\"text-text-950 my-6\">\n Responder\n </Text>\n\n <div className=\"space-y-4\">\n <TextArea\n placeholder=\"Detalhe o problema aqui.\"\n rows={4}\n className=\"w-full\"\n value={responseText}\n onChange={(e) => setResponseText(e.target.value)}\n />\n\n {responseText.trim().length > 0 && (\n <div className=\"flex justify-end\">\n <Button\n variant=\"solid\"\n size=\"medium\"\n onClick={handleSubmitAnswer}\n disabled={isSubmittingAnswer}\n >\n {isSubmittingAnswer ? 'Enviando...' : 'Enviar'}\n </Button>\n </div>\n )}\n </div>\n </>\n )}\n </div>\n </div>\n </Modal>\n\n {/* Modal de confirmação de encerramento */}\n <Modal\n isOpen={showCloseConfirmation}\n onClose={() => setShowCloseConfirmation(false)}\n title=\"Encerrar pedido?\"\n size=\"md\"\n hideCloseButton={false}\n closeOnEscape={true}\n data-testid=\"close-ticket-modal\"\n >\n <div className=\"space-y-6\">\n <Text size=\"sm\" weight=\"normal\" className=\"text-text-700\">\n Ao encerrar este pedido, ele será fechado e não poderá mais ser\n atualizado.\n </Text>\n\n <div className=\"flex gap-3 justify-end\">\n <Button\n variant=\"outline\"\n size=\"medium\"\n onClick={() => setShowCloseConfirmation(false)}\n >\n Cancelar\n </Button>\n <Button\n variant=\"solid\"\n size=\"medium\"\n action=\"negative\"\n onClick={handleCloseTicket}\n >\n Encerrar\n </Button>\n </div>\n </div>\n </Modal>\n </>\n );\n};\n","import { KeyIcon, BugIcon, InfoIcon } from '@phosphor-icons/react';\nimport React from 'react';\nimport { SupportCategory } from '../../../types/support';\n\nexport const getCategoryIcon = (\n category: SupportCategory | null,\n size = 16\n): React.ReactNode => {\n if (!category) return null;\n switch (category) {\n case SupportCategory.ACESSO:\n return <KeyIcon size={size} />;\n case SupportCategory.TECNICO:\n return <BugIcon size={size} />;\n case SupportCategory.OUTROS:\n return <InfoIcon size={size} />;\n default:\n return <InfoIcon size={size} />;\n }\n};\n"]}
@@ -6,7 +6,7 @@ var _chunk2AP4SM46js = require('./chunk-2AP4SM46.js');
6
6
 
7
7
 
8
8
 
9
- var _chunkBWTNSVJEjs = require('./chunk-BWTNSVJE.js');
9
+ var _chunkOGD2ATAPjs = require('./chunk-OGD2ATAP.js');
10
10
 
11
11
 
12
12
  var _chunkHYCL2IYZjs = require('./chunk-HYCL2IYZ.js');
@@ -173,13 +173,13 @@ var minutesBetween = (fromIso, toIso, now = /* @__PURE__ */ new Date()) => {
173
173
  );
174
174
  };
175
175
  var matchesHistoryFilter = (ticket, filter) => {
176
- const done = ticket.status === _chunkBWTNSVJEjs.SUPPORT_TICKET_CARD_STATUS.DONE;
176
+ const done = ticket.status === _chunkOGD2ATAPjs.SUPPORT_TICKET_CARD_STATUS.DONE;
177
177
  switch (filter) {
178
- case _chunkBWTNSVJEjs.SUPPORT_HISTORY_FILTER.OPEN:
178
+ case _chunkOGD2ATAPjs.SUPPORT_HISTORY_FILTER.OPEN:
179
179
  return !done;
180
- case _chunkBWTNSVJEjs.SUPPORT_HISTORY_FILTER.DONE:
180
+ case _chunkOGD2ATAPjs.SUPPORT_HISTORY_FILTER.DONE:
181
181
  return done;
182
- case _chunkBWTNSVJEjs.SUPPORT_HISTORY_FILTER.AI:
182
+ case _chunkOGD2ATAPjs.SUPPORT_HISTORY_FILTER.AI:
183
183
  return done && _optionalChain([ticket, 'access', _ => _.resolvedBy, 'optionalAccess', _2 => _2.type]) === "ai";
184
184
  default:
185
185
  return true;
@@ -469,25 +469,25 @@ var _CaretDown = require('@phosphor-icons/react/dist/csr/CaretDown');
469
469
  var INITIAL_VISIBLE = 5;
470
470
  var PAGE_SIZE = 10;
471
471
  var FILTERS = [
472
- { value: _chunkBWTNSVJEjs.SUPPORT_HISTORY_FILTER.ALL, label: "Todos" },
473
- { value: _chunkBWTNSVJEjs.SUPPORT_HISTORY_FILTER.OPEN, label: "Abertos" },
474
- { value: _chunkBWTNSVJEjs.SUPPORT_HISTORY_FILTER.DONE, label: "Conclu\xEDdos" },
475
- { value: _chunkBWTNSVJEjs.SUPPORT_HISTORY_FILTER.AI, label: "IA" }
472
+ { value: _chunkOGD2ATAPjs.SUPPORT_HISTORY_FILTER.ALL, label: "Todos" },
473
+ { value: _chunkOGD2ATAPjs.SUPPORT_HISTORY_FILTER.OPEN, label: "Abertos" },
474
+ { value: _chunkOGD2ATAPjs.SUPPORT_HISTORY_FILTER.DONE, label: "Conclu\xEDdos" },
475
+ { value: _chunkOGD2ATAPjs.SUPPORT_HISTORY_FILTER.AI, label: "IA" }
476
476
  ];
477
477
  var STATUS_BADGE = {
478
- [_chunkBWTNSVJEjs.SUPPORT_TICKET_CARD_STATUS.IN_PROGRESS]: {
478
+ [_chunkOGD2ATAPjs.SUPPORT_TICKET_CARD_STATUS.IN_PROGRESS]: {
479
479
  label: "EM ANDAMENTO",
480
480
  action: "info"
481
481
  },
482
- [_chunkBWTNSVJEjs.SUPPORT_TICKET_CARD_STATUS.WAITING_HUMAN]: {
482
+ [_chunkOGD2ATAPjs.SUPPORT_TICKET_CARD_STATUS.WAITING_HUMAN]: {
483
483
  label: "AGUARDANDO HUMANO",
484
484
  action: "warning"
485
485
  },
486
- [_chunkBWTNSVJEjs.SUPPORT_TICKET_CARD_STATUS.HUMAN]: {
486
+ [_chunkOGD2ATAPjs.SUPPORT_TICKET_CARD_STATUS.HUMAN]: {
487
487
  label: "HUMANO",
488
488
  action: "warning"
489
489
  },
490
- [_chunkBWTNSVJEjs.SUPPORT_TICKET_CARD_STATUS.DONE]: {
490
+ [_chunkOGD2ATAPjs.SUPPORT_TICKET_CARD_STATUS.DONE]: {
491
491
  label: "CONCLU\xCDDO",
492
492
  action: "success"
493
493
  }
@@ -497,10 +497,10 @@ var resolverLabel = (ticket) => {
497
497
  return ticket.resolvedBy.type === "ai" ? "IA" : ticket.resolvedBy.name;
498
498
  };
499
499
  var PRIORITY_LABELS = {
500
- [_chunkBWTNSVJEjs.SUPPORT_TICKET_PRIORITY.LOW]: "Baixa",
501
- [_chunkBWTNSVJEjs.SUPPORT_TICKET_PRIORITY.NORMAL]: "Normal",
502
- [_chunkBWTNSVJEjs.SUPPORT_TICKET_PRIORITY.HIGH]: "Alta",
503
- [_chunkBWTNSVJEjs.SUPPORT_TICKET_PRIORITY.URGENT]: "Urgente"
500
+ [_chunkOGD2ATAPjs.SUPPORT_TICKET_PRIORITY.LOW]: "Baixa",
501
+ [_chunkOGD2ATAPjs.SUPPORT_TICKET_PRIORITY.NORMAL]: "Normal",
502
+ [_chunkOGD2ATAPjs.SUPPORT_TICKET_PRIORITY.HIGH]: "Alta",
503
+ [_chunkOGD2ATAPjs.SUPPORT_TICKET_PRIORITY.URGENT]: "Urgente"
504
504
  };
505
505
  var TicketCard = ({
506
506
  ticket,
@@ -520,7 +520,8 @@ var TicketCard = ({
520
520
  if (ticket.priority) {
521
521
  details.push(["Prioridade", PRIORITY_LABELS[ticket.priority]]);
522
522
  }
523
- if (ticket.channel) details.push(["Canal", ticket.channel]);
523
+ const channel = [ticket.channel, ticket.origin].filter(Boolean).join(" \xB7 ");
524
+ if (channel) details.push(["Canal", channel]);
524
525
  if (current) details.push(["Dura\xE7\xE3o", "Ticket atual"]);
525
526
  else if (ticket.durationMin != null) {
526
527
  details.push(["Dura\xE7\xE3o", formatDuration(ticket.durationMin)]);
@@ -637,7 +638,7 @@ function SupportHistoryTab({
637
638
  onFilterChange
638
639
  }) {
639
640
  const [filter, setFilter] = _react.useState.call(void 0,
640
- _chunkBWTNSVJEjs.SUPPORT_HISTORY_FILTER.ALL
641
+ _chunkOGD2ATAPjs.SUPPORT_HISTORY_FILTER.ALL
641
642
  );
642
643
  const [visible, setVisible] = _react.useState.call(void 0, INITIAL_VISIBLE);
643
644
  const selectFilter = (next) => {
@@ -716,7 +717,7 @@ function SupportHistoryTab({
716
717
  }
717
718
  ) }, ticket.id);
718
719
  }) }),
719
- isFirstContact && filter === _chunkBWTNSVJEjs.SUPPORT_HISTORY_FILTER.ALL && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkANT66KVKjs.Text_default, { size: "xs", color: "text-text-600", className: "text-center", children: "Primeiro atendimento deste usu\xE1rio" }),
720
+ isFirstContact && filter === _chunkOGD2ATAPjs.SUPPORT_HISTORY_FILTER.ALL && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkANT66KVKjs.Text_default, { size: "xs", color: "text-text-600", className: "text-center", children: "Primeiro atendimento deste usu\xE1rio" }),
720
721
  canShowMore && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
721
722
  _chunkXN2HPVVHjs.Button_default,
722
723
  {
@@ -769,10 +770,10 @@ var OptionSelect = ({
769
770
  ] });
770
771
  };
771
772
  var PRIORITIES = [
772
- { value: _chunkBWTNSVJEjs.SUPPORT_TICKET_PRIORITY.LOW, label: "Baixa" },
773
- { value: _chunkBWTNSVJEjs.SUPPORT_TICKET_PRIORITY.NORMAL, label: "Normal" },
774
- { value: _chunkBWTNSVJEjs.SUPPORT_TICKET_PRIORITY.HIGH, label: "Alta" },
775
- { value: _chunkBWTNSVJEjs.SUPPORT_TICKET_PRIORITY.URGENT, label: "Urgente" }
773
+ { value: _chunkOGD2ATAPjs.SUPPORT_TICKET_PRIORITY.LOW, label: "Baixa" },
774
+ { value: _chunkOGD2ATAPjs.SUPPORT_TICKET_PRIORITY.NORMAL, label: "Normal" },
775
+ { value: _chunkOGD2ATAPjs.SUPPORT_TICKET_PRIORITY.HIGH, label: "Alta" },
776
+ { value: _chunkOGD2ATAPjs.SUPPORT_TICKET_PRIORITY.URGENT, label: "Urgente" }
776
777
  ];
777
778
  var DetailsSkeleton = () => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
778
779
  "div",
@@ -818,7 +819,7 @@ function SupportTicketDetailsTab({
818
819
  onHandlerChange
819
820
  );
820
821
  const [priority, setPriority] = useOptimisticValue(
821
- _nullishCoalesce(_optionalChain([ticket, 'optionalAccess', _7 => _7.priority]), () => ( _chunkBWTNSVJEjs.SUPPORT_TICKET_PRIORITY.NORMAL)),
822
+ _nullishCoalesce(_optionalChain([ticket, 'optionalAccess', _7 => _7.priority]), () => ( _chunkOGD2ATAPjs.SUPPORT_TICKET_PRIORITY.NORMAL)),
822
823
  onPriorityChange
823
824
  );
824
825
  if (loading || !ticket) return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DetailsSkeleton, {});
@@ -828,7 +829,13 @@ function SupportTicketDetailsTab({
828
829
  const readOnly = done;
829
830
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-4", children: [
830
831
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "grid grid-cols-2 gap-2", children: [
831
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StatTile, { label: "Canal", value: ticket.channel }),
832
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
833
+ StatTile,
834
+ {
835
+ label: "Canal",
836
+ value: ticket.origin ? `${ticket.channel} \xB7 ${ticket.origin}` : ticket.channel
837
+ }
838
+ ),
832
839
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StatTile, { label: "Aberto em", value: formatOpenedAt(ticket.openedAt) }),
833
840
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StatTile, { label: "Tempo de espera", value: formatDuration(waitingMin) }),
834
841
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StatTile, { label: "Tempo total", value: formatDuration(totalMin) })
@@ -939,9 +946,9 @@ function SupportTicketDetailsTab({
939
946
  // src/components/SupportUserPanel/SupportUserPanel.tsx
940
947
 
941
948
  var TABS = [
942
- { value: _chunkBWTNSVJEjs.SUPPORT_USER_PANEL_TAB.PROFILE, label: "Perfil" },
943
- { value: _chunkBWTNSVJEjs.SUPPORT_USER_PANEL_TAB.HISTORY, label: "Hist\xF3rico" },
944
- { value: _chunkBWTNSVJEjs.SUPPORT_USER_PANEL_TAB.TICKET, label: "Detalhes" }
949
+ { value: _chunkOGD2ATAPjs.SUPPORT_USER_PANEL_TAB.PROFILE, label: "Perfil" },
950
+ { value: _chunkOGD2ATAPjs.SUPPORT_USER_PANEL_TAB.HISTORY, label: "Hist\xF3rico" },
951
+ { value: _chunkOGD2ATAPjs.SUPPORT_USER_PANEL_TAB.TICKET, label: "Detalhes" }
945
952
  ];
946
953
  function SupportUserPanel({
947
954
  tab,
@@ -953,7 +960,7 @@ function SupportUserPanel({
953
960
  className
954
961
  }) {
955
962
  const [internalTab, setInternalTab] = _react.useState.call(void 0,
956
- _chunkBWTNSVJEjs.SUPPORT_USER_PANEL_TAB.TICKET
963
+ _chunkOGD2ATAPjs.SUPPORT_USER_PANEL_TAB.TICKET
957
964
  );
958
965
  const active = _nullishCoalesce(tab, () => ( internalTab));
959
966
  const changeTab = (next) => {
@@ -986,7 +993,7 @@ function SupportUserPanel({
986
993
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "shrink-0 border-b border-border-100 px-4", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
987
994
  _chunkPMXNIJKVjs.Menu,
988
995
  {
989
- defaultValue: _chunkBWTNSVJEjs.SUPPORT_USER_PANEL_TAB.TICKET,
996
+ defaultValue: _chunkOGD2ATAPjs.SUPPORT_USER_PANEL_TAB.TICKET,
990
997
  value: active,
991
998
  variant: "menu2",
992
999
  semantics: "tabs",
@@ -1020,9 +1027,9 @@ function SupportUserPanel({
1020
1027
  "aria-label": _optionalChain([TABS, 'access', _10 => _10.find, 'call', _11 => _11((item) => item.value === active), 'optionalAccess', _12 => _12.label]),
1021
1028
  className: "min-h-0 flex-1 overflow-y-auto p-4",
1022
1029
  children: [
1023
- active === _chunkBWTNSVJEjs.SUPPORT_USER_PANEL_TAB.PROFILE && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SupportProfileTab, { ...profile }),
1024
- active === _chunkBWTNSVJEjs.SUPPORT_USER_PANEL_TAB.HISTORY && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SupportHistoryTab, { ...history }),
1025
- active === _chunkBWTNSVJEjs.SUPPORT_USER_PANEL_TAB.TICKET && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SupportTicketDetailsTab, { ...ticket })
1030
+ active === _chunkOGD2ATAPjs.SUPPORT_USER_PANEL_TAB.PROFILE && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SupportProfileTab, { ...profile }),
1031
+ active === _chunkOGD2ATAPjs.SUPPORT_USER_PANEL_TAB.HISTORY && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SupportHistoryTab, { ...history }),
1032
+ active === _chunkOGD2ATAPjs.SUPPORT_USER_PANEL_TAB.TICKET && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SupportTicketDetailsTab, { ...ticket })
1026
1033
  ]
1027
1034
  }
1028
1035
  )
@@ -1034,4 +1041,4 @@ function SupportUserPanel({
1034
1041
 
1035
1042
 
1036
1043
  exports.SupportUserPanel = SupportUserPanel;
1037
- //# sourceMappingURL=chunk-IMMKWOYJ.js.map
1044
+ //# sourceMappingURL=chunk-WUXIPIUG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-WUXIPIUG.js","../src/components/SupportUserPanel/SupportUserPanel.tsx","../src/components/SupportUserPanel/SupportProfileTab.tsx","../src/components/SupportUserPanel/SupportPanelShared.tsx","../src/components/SupportUserPanel/supportUserPanelUtils.ts","../src/components/SupportUserPanel/SupportHistoryTab.tsx","../src/components/SupportUserPanel/SupportTicketDetailsTab.tsx"],"names":["useEffect"],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-WUXIPIUG.js","sourcesContent":[null,"import { useEffect, useState } from 'react';\nimport { Menu, MenuContent, MenuItem } from '../Menu/Menu';\nimport { cn } from '../../utils/utils';\nimport {\n SUPPORT_USER_PANEL_TAB,\n type SupportUserPanelTab,\n} from '../../types/supportUserPanel';\nimport SupportProfileTab, {\n type SupportProfileTabProps,\n} from './SupportProfileTab';\nimport SupportHistoryTab, {\n type SupportHistoryTabProps,\n} from './SupportHistoryTab';\nimport SupportTicketDetailsTab, {\n type SupportTicketDetailsTabProps,\n} from './SupportTicketDetailsTab';\n\nconst TABS: { value: SupportUserPanelTab; label: string }[] = [\n { value: SUPPORT_USER_PANEL_TAB.PROFILE, label: 'Perfil' },\n { value: SUPPORT_USER_PANEL_TAB.HISTORY, label: 'Histórico' },\n { value: SUPPORT_USER_PANEL_TAB.TICKET, label: 'Detalhes' },\n];\n\n/** Props for the support user panel */\nexport interface SupportUserPanelProps {\n /** Controlled tab. Omit to let the panel keep it (default: ticket details) */\n tab?: SupportUserPanelTab;\n /**\n * Notified on tab change. Keep the panel mounted (or control `tab`) while\n * the agent moves between tickets so the chosen tab persists.\n */\n onTabChange?: (tab: SupportUserPanelTab) => void;\n /** Enables Alt+1 / Alt+2 / Alt+3 to switch tabs (default: true) */\n enableShortcuts?: boolean;\n profile: SupportProfileTabProps;\n history: SupportHistoryTabProps;\n ticket: SupportTicketDetailsTabProps;\n className?: string;\n}\n\n/**\n * Right-side panel of the agent's ticket screen (300px). Shows the contact\n * of the open conversation and the current ticket in three tabs: Perfil,\n * Histórico and Detalhes (the current ticket).\n *\n * Presentational: data comes in through props and every change goes out\n * through callbacks. Saves made from the ticket tab are optimistic, with a\n * \"Salvo\" toast, or a rollback and an error toast when the callback rejects.\n */\nexport default function SupportUserPanel({\n tab,\n onTabChange,\n enableShortcuts = true,\n profile,\n history,\n ticket,\n className,\n}: Readonly<SupportUserPanelProps>) {\n const [internalTab, setInternalTab] = useState<SupportUserPanelTab>(\n SUPPORT_USER_PANEL_TAB.TICKET\n );\n const active = tab ?? internalTab;\n\n const changeTab = (next: SupportUserPanelTab) => {\n if (tab === undefined) setInternalTab(next);\n onTabChange?.(next);\n };\n\n useEffect(() => {\n if (!enableShortcuts) return undefined;\n const handleKeyDown = (event: KeyboardEvent) => {\n if (!event.altKey || event.ctrlKey || event.metaKey) return;\n // `code` instead of `key`: on macOS Alt+1 types \"¡\", not \"1\".\n const index = ['Digit1', 'Digit2', 'Digit3'].indexOf(event.code);\n if (index === -1) return;\n event.preventDefault();\n const next = TABS[index].value;\n if (tab === undefined) setInternalTab(next);\n onTabChange?.(next);\n };\n globalThis.addEventListener('keydown', handleKeyDown);\n return () => globalThis.removeEventListener('keydown', handleKeyDown);\n }, [enableShortcuts, onTabChange, tab]);\n\n return (\n <aside\n aria-label=\"Painel do usuário\"\n className={cn(\n 'flex h-full w-[300px] shrink-0 flex-col border-l border-border-100 bg-background',\n className\n )}\n >\n <div className=\"shrink-0 border-b border-border-100 px-4\">\n <Menu\n defaultValue={SUPPORT_USER_PANEL_TAB.TICKET}\n value={active}\n variant=\"menu2\"\n semantics=\"tabs\"\n onValueChange={(value) => changeTab(value as SupportUserPanelTab)}\n className=\"!py-0\"\n >\n {/* Equal widths (`w-full`) leave ~89px per tab in 300px. Each tab\n takes the width of its label and the leftover is shared, so\n longer labels still fit on one line. */}\n <MenuContent\n variant=\"menu2\"\n className=\"!gap-1 [&>li]:!w-auto [&>li]:flex-auto [&>li]:!px-0\"\n >\n {TABS.map((item) => (\n <MenuItem\n key={item.value}\n value={item.value}\n variant=\"menu2\"\n aria-controls={`support-user-panel-${item.value}`}\n className=\"!px-0 !text-[13px] whitespace-nowrap\"\n >\n {item.label}\n </MenuItem>\n ))}\n </MenuContent>\n </Menu>\n </div>\n\n <div\n id={`support-user-panel-${active}`}\n role=\"tabpanel\"\n aria-label={TABS.find((item) => item.value === active)?.label}\n className=\"min-h-0 flex-1 overflow-y-auto p-4\"\n >\n {active === SUPPORT_USER_PANEL_TAB.PROFILE && (\n <SupportProfileTab {...profile} />\n )}\n {active === SUPPORT_USER_PANEL_TAB.HISTORY && (\n <SupportHistoryTab {...history} />\n )}\n {active === SUPPORT_USER_PANEL_TAB.TICKET && (\n <SupportTicketDetailsTab {...ticket} />\n )}\n </div>\n </aside>\n );\n}\n","import { useId, useState } from 'react';\nimport Avatar from '../Avatar/Avatar';\nimport Button from '../Button/Button';\nimport Text from '../Text/Text';\nimport TextArea from '../TextArea/TextArea';\nimport { Skeleton, SkeletonText } from '../Skeleton/Skeleton';\nimport useToastStore from '../Toast/utils/ToastStore';\nimport { cn } from '../../utils/utils';\nimport type { SupportContact } from '../../types/supportUserPanel';\nimport { FieldLabel } from './SupportPanelShared';\nimport {\n formatDate,\n formatPhone,\n formatRelativeDay,\n} from './supportUserPanelUtils';\n\n/** Props for the profile tab */\nexport interface SupportProfileTabProps {\n contact?: SupportContact | null;\n loading?: boolean;\n /** Opens \"Usuários / Contatos – Detalhe do contato\" */\n onOpenContact?: () => void;\n /** Starts linking an unlinked contact to a platform user */\n onLinkContact?: () => void;\n /** Persists a note; reject to keep the text in the box */\n onAddNote?: (text: string) => Promise<void> | void;\n}\n\nconst linkClasses =\n 'underline underline-offset-2 rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indicator-info';\n\n/** Read-only field; clicking copies the value */\nconst CopyField = ({ label, value }: { label: string; value?: string }) => {\n const addToast = useToastStore((state) => state.addToast);\n const labelId = useId();\n\n const copy = async () => {\n if (!value) return;\n try {\n await navigator.clipboard.writeText(value);\n addToast({ title: 'Copiado', action: 'success', position: 'top-right' });\n } catch {\n addToast({\n title: 'Não foi possível copiar',\n action: 'warning',\n position: 'top-right',\n });\n }\n };\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel id={labelId}>{label}</FieldLabel>\n {value ? (\n <Button\n variant=\"raw\"\n onClick={copy}\n aria-labelledby={labelId}\n aria-describedby={`${labelId}-value`}\n title=\"Clique para copiar\"\n className=\"w-full rounded-lg border border-border-300 bg-background px-3 py-2.5 text-left hover:border-border-400 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indicator-info\"\n >\n <Text\n as=\"span\"\n id={`${labelId}-value`}\n size=\"sm\"\n color=\"text-text-950\"\n className=\"block truncate\"\n >\n {value}\n </Text>\n </Button>\n ) : (\n <div\n aria-labelledby={labelId}\n className=\"w-full rounded-lg border border-border-300 bg-background px-3 py-2.5\"\n >\n <Text as=\"span\" size=\"sm\" color=\"text-text-400\">\n —\n </Text>\n </div>\n )}\n </div>\n );\n};\n\nconst ProfileSkeleton = () => (\n <div\n className=\"flex flex-col gap-4\"\n aria-busy=\"true\"\n aria-label=\"Carregando perfil\"\n >\n <div className=\"flex items-center gap-3\">\n <Skeleton variant=\"circular\" width={44} height={44} />\n <div className=\"flex flex-1 flex-col gap-1.5\">\n <SkeletonText width=\"60%\" />\n <SkeletonText width=\"80%\" />\n </div>\n </div>\n <Skeleton variant=\"rounded\" height={40} />\n <Skeleton variant=\"rounded\" height={40} />\n <SkeletonText lines={5} spacing=\"medium\" />\n </div>\n);\n\n/**\n * Profile tab: contact header, link badge, e-mail/phone, key/value facts\n * and the team notes about the user.\n */\nexport default function SupportProfileTab({\n contact,\n loading = false,\n onOpenContact,\n onLinkContact,\n onAddNote,\n}: Readonly<SupportProfileTabProps>) {\n const [note, setNote] = useState('');\n const [savingNote, setSavingNote] = useState(false);\n const addToast = useToastStore((state) => state.addToast);\n\n if (loading || !contact) return <ProfileSkeleton />;\n\n const canAddNote =\n Boolean(onAddNote) && note.trim().length > 0 && !savingNote;\n\n const submitNote = async () => {\n if (!canAddNote || !onAddNote) return;\n setSavingNote(true);\n try {\n await onAddNote(note.trim());\n setNote('');\n } catch {\n // The text stays in the box so the agent can retry.\n addToast({\n title: 'Não foi possível adicionar a nota',\n action: 'warning',\n position: 'top-right',\n });\n } finally {\n setSavingNote(false);\n }\n };\n\n const facts: [string, string][] = [\n ['Turma / cargo', contact.classOrPosition || '—'],\n ['Instituição', contact.institution || '—'],\n ['Primeiro contato', formatDate(contact.firstContactAt)],\n ['Último contato', formatRelativeDay(contact.lastContactAt)],\n ['Total de atendimentos', String(contact.ticketsCount)],\n ['Dispositivo', contact.device || '—'],\n ['Canal preferido', contact.preferredChannel],\n ];\n\n const notes = [...contact.notes].sort(\n (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n );\n\n return (\n <div className=\"flex flex-col gap-4\">\n <div className=\"flex items-center gap-3\">\n <Avatar\n src={contact.avatarUrl}\n name={contact.name}\n size={44}\n fallback=\"initials\"\n />\n <div className=\"flex min-w-0 flex-col\">\n <Text\n size=\"sm\"\n weight=\"bold\"\n color=\"text-text-950\"\n className=\"truncate\"\n >\n {contact.name}\n </Text>\n <Text size=\"xs\" color=\"text-text-600\" className=\"truncate\">\n {contact.role} · {contact.institution}\n </Text>\n </div>\n </div>\n\n {contact.linked ? (\n <Text\n size=\"xs\"\n color=\"text-success-800\"\n className=\"rounded-lg border border-success-200 bg-success-background px-3 py-2\"\n >\n ✓ Vinculado à plataforma\n {onOpenContact && (\n <>\n {' · '}\n <Button\n variant=\"raw\"\n onClick={onOpenContact}\n className={linkClasses}\n >\n ver cadastro\n </Button>\n </>\n )}\n </Text>\n ) : (\n <Text\n size=\"xs\"\n color=\"text-warning-800\"\n className=\"rounded-lg bg-warning-background px-3 py-2\"\n >\n Usuário não vinculado\n {onLinkContact && (\n <>\n {' · '}\n <Button\n variant=\"raw\"\n onClick={onLinkContact}\n className={linkClasses}\n >\n vincular\n </Button>\n </>\n )}\n </Text>\n )}\n\n <CopyField label=\"E-mail\" value={contact.email ?? undefined} />\n <CopyField\n label=\"Telefone\"\n value={contact.phone ? formatPhone(contact.phone) : undefined}\n />\n\n <dl className=\"flex flex-col\">\n {facts.map(([key, value]) => (\n <div\n key={key}\n className=\"flex items-baseline justify-between gap-3 border-b border-border-100 py-2 last:border-b-0\"\n >\n <Text as=\"dt\" size=\"xs\" color=\"text-text-600\">\n {key}\n </Text>\n <Text\n as=\"dd\"\n size=\"xs\"\n weight=\"medium\"\n color=\"text-text-950\"\n className=\"text-right\"\n >\n {value}\n </Text>\n </div>\n ))}\n </dl>\n\n <hr className=\"border-border-100\" />\n\n <div className=\"flex flex-col gap-2\">\n <FieldLabel>Notas sobre o usuário</FieldLabel>\n <TextArea\n value={note}\n onChange={(event) => setNote(event.target.value)}\n placeholder=\"Escreva uma nota visível para a equipe\"\n aria-label=\"Nota sobre o usuário\"\n size=\"small\"\n className=\"!h-16 min-h-16\"\n disabled={!onAddNote}\n />\n <div className=\"flex justify-end\">\n <Button\n size=\"small\"\n className=\"rounded-full\"\n onClick={submitNote}\n disabled={!canAddNote}\n >\n Adicionar nota\n </Button>\n </div>\n {notes.length > 0 && (\n <ul\n aria-label=\"Notas sobre o usuário\"\n className=\"flex flex-col gap-2\"\n >\n {notes.map((item) => (\n <li\n key={item.id}\n className={cn(\n 'flex flex-col gap-1 rounded-lg border border-warning-200 bg-exam-3 px-3 py-2'\n )}\n >\n <Text\n size=\"xs\"\n color=\"text-text-950\"\n className=\"whitespace-pre-line\"\n >\n {item.text}\n </Text>\n <Text size=\"2xs\" color=\"text-warning-800\">\n {item.author} · {formatDate(item.createdAt)}\n </Text>\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n );\n}\n","import { useCallback, useEffect, useState, type ReactNode } from 'react';\nimport Text from '../Text/Text';\nimport useToastStore from '../Toast/utils/ToastStore';\n\n/** Grey stat tile: small muted label over a bold value */\nexport const StatTile = ({\n label,\n value,\n valueSize = 'sm',\n}: {\n label: string;\n value: ReactNode;\n /** `sm` (14px) on the ticket grid, `md` (16px) on the history summary */\n valueSize?: 'sm' | 'md';\n}) => (\n <div className=\"flex min-w-0 flex-col gap-0.5 rounded-lg bg-background-100 px-3 py-2.5\">\n <Text size=\"xs\" color=\"text-text-600\" className=\"truncate\">\n {label}\n </Text>\n <Text\n size={valueSize}\n weight=\"bold\"\n color=\"text-text-950\"\n className=\"truncate\"\n >\n {value}\n </Text>\n </div>\n);\n\n/** Section title used above fields (13px / 600) */\nexport const FieldLabel = ({\n children,\n id,\n}: {\n children: ReactNode;\n id?: string;\n}) => (\n <Text id={id} size=\"sm\" weight=\"semibold\" color=\"text-text-950\">\n {children}\n </Text>\n);\n\n/**\n * Optimistic auto-save: applies the value right away, calls `save`, shows\n * \"Salvo\" on success and rolls back with an error toast on failure.\n *\n * @param value - Value coming from props (source of truth after a save)\n * @param save - Persists the new value; reject to trigger the rollback\n * @returns The value to render and the setter that saves it\n */\nexport function useOptimisticValue<T>(\n value: T,\n save: ((next: T) => Promise<void> | void) | undefined\n): [T, (next: T) => Promise<void>] {\n const [current, setCurrent] = useState(value);\n const addToast = useToastStore((state) => state.addToast);\n\n useEffect(() => {\n setCurrent(value);\n }, [value]);\n\n const update = useCallback(\n async (next: T) => {\n if (!save) return;\n const previous = current;\n setCurrent(next);\n try {\n await save(next);\n addToast({ title: 'Salvo', action: 'success', position: 'top-right' });\n } catch {\n setCurrent(previous);\n addToast({\n title: 'Não foi possível salvar',\n description: 'A alteração foi desfeita. Tente novamente.',\n action: 'warning',\n position: 'top-right',\n });\n }\n },\n [addToast, current, save]\n );\n\n return [current, update];\n}\n\n/**\n * Current time, refreshed every `intervalMs` while `active` — drives the\n * live wait/total counters of an open ticket.\n */\nexport function useNow(active: boolean, intervalMs = 30_000): Date {\n const [now, setNow] = useState(() => new Date());\n\n useEffect(() => {\n if (!active) return undefined;\n setNow(new Date());\n const id = setInterval(() => setNow(new Date()), intervalMs);\n return () => clearInterval(id);\n }, [active, intervalMs]);\n\n return now;\n}\n","import {\n SUPPORT_HISTORY_FILTER,\n SUPPORT_TICKET_CARD_STATUS,\n type SupportHistoryFilter,\n type SupportTicketSummary,\n} from '../../types/supportUserPanel';\n\nconst pad = (value: number) => String(value).padStart(2, '0');\n\nconst isSameDay = (a: Date, b: Date) =>\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate();\n\nconst isYesterday = (date: Date, now: Date) => {\n const yesterday = new Date(now);\n yesterday.setDate(now.getDate() - 1);\n return isSameDay(date, yesterday);\n};\n\n/** `dd/mm/aaaa` */\nexport const formatDate = (iso: string): string => {\n const date = new Date(iso);\n return `${pad(date.getDate())}/${pad(date.getMonth() + 1)}/${date.getFullYear()}`;\n};\n\n/** `HH:MM` */\nexport const formatTime = (iso: string): string => {\n const date = new Date(iso);\n return `${pad(date.getHours())}:${pad(date.getMinutes())}`;\n};\n\n/** `Hoje`, `Ontem` or `dd/mm/aaaa` — used for the contact's last contact */\nexport const formatRelativeDay = (iso: string, now = new Date()): string => {\n const date = new Date(iso);\n if (isSameDay(date, now)) return 'Hoje';\n if (isYesterday(date, now)) return 'Ontem';\n return formatDate(iso);\n};\n\n/** `Hoje, HH:MM` or `dd/mm/aaaa` — history cards */\nexport const formatCardDate = (iso: string, now = new Date()): string =>\n isSameDay(new Date(iso), now) ? `Hoje, ${formatTime(iso)}` : formatDate(iso);\n\n/** `Hoje, HH:MM` or `dd/mm, HH:MM` — \"Aberto em\" stat */\nexport const formatOpenedAt = (iso: string, now = new Date()): string => {\n const date = new Date(iso);\n if (isSameDay(date, now)) return `Hoje, ${formatTime(iso)}`;\n return `${pad(date.getDate())}/${pad(date.getMonth() + 1)}, ${formatTime(iso)}`;\n};\n\n/** `HH:MM` for today, `dd/mm HH:MM` otherwise — status timeline */\nexport const formatTimelineTime = (iso: string, now = new Date()): string => {\n const date = new Date(iso);\n if (isSameDay(date, now)) return formatTime(iso);\n return `${pad(date.getDate())}/${pad(date.getMonth() + 1)} ${formatTime(iso)}`;\n};\n\n/** `(DD) 9XXXX-XXXX`; values that are not a BR number are returned as given */\nexport const formatPhone = (phone: string): string => {\n const digits = phone.replace(/\\D/g, '');\n if (digits.length === 11) {\n return `(${digits.slice(0, 2)}) ${digits.slice(2, 7)}-${digits.slice(7)}`;\n }\n if (digits.length === 10) {\n return `(${digits.slice(0, 2)}) ${digits.slice(2, 6)}-${digits.slice(6)}`;\n }\n return phone;\n};\n\n/** `18 min`, `1h 05min` */\nexport const formatDuration = (minutes: number): string => {\n const total = Math.max(0, Math.floor(minutes));\n if (total < 60) return `${total} min`;\n return `${Math.floor(total / 60)}h ${pad(total % 60)}min`;\n};\n\n/** Whole minutes between two ISO dates (or between a date and `now`) */\nexport const minutesBetween = (\n fromIso: string,\n toIso: string | null | undefined,\n now = new Date()\n): number => {\n const to = toIso ? new Date(toIso) : now;\n return Math.max(\n 0,\n Math.floor((to.getTime() - new Date(fromIso).getTime()) / 60_000)\n );\n};\n\n/** Whether a ticket card matches the selected history filter */\nexport const matchesHistoryFilter = (\n ticket: SupportTicketSummary,\n filter: SupportHistoryFilter\n): boolean => {\n const done = ticket.status === SUPPORT_TICKET_CARD_STATUS.DONE;\n switch (filter) {\n case SUPPORT_HISTORY_FILTER.OPEN:\n return !done;\n case SUPPORT_HISTORY_FILTER.DONE:\n return done;\n case SUPPORT_HISTORY_FILTER.AI:\n return done && ticket.resolvedBy?.type === 'ai';\n default:\n return true;\n }\n};\n","import { useId, useState } from 'react';\nimport { CaretDownIcon } from '@phosphor-icons/react/dist/csr/CaretDown';\nimport Badge from '../Badge/Badge';\nimport Button from '../Button/Button';\nimport Chips from '../Chips/Chips';\nimport Text from '../Text/Text';\nimport { Skeleton } from '../Skeleton/Skeleton';\nimport { cn } from '../../utils/utils';\nimport {\n SUPPORT_HISTORY_FILTER,\n SUPPORT_TICKET_CARD_STATUS,\n SUPPORT_TICKET_PRIORITY,\n type SupportHistoryFilter,\n type SupportHistorySummary,\n type SupportTicketCardStatus,\n type SupportTicketId,\n type SupportTicketPriority,\n type SupportTicketSummary,\n} from '../../types/supportUserPanel';\nimport { StatTile } from './SupportPanelShared';\nimport {\n formatCardDate,\n formatDuration,\n matchesHistoryFilter,\n} from './supportUserPanelUtils';\n\n/** Cards shown before \"Ver todos os atendimentos\" */\nconst INITIAL_VISIBLE = 5;\n/** Cards added by each \"Ver todos os atendimentos\" click */\nconst PAGE_SIZE = 10;\n\n/** Props for the history tab */\nexport interface SupportHistoryTabProps {\n /** Id of the ticket open in the conversation (pinned on top, not clickable) */\n currentTicketId: SupportTicketId;\n /** Every ticket of the contact, including the current one */\n tickets: SupportTicketSummary[];\n summary: SupportHistorySummary;\n loading?: boolean;\n /** Whether the server has tickets beyond `tickets` */\n hasMore?: boolean;\n /** Asks the consumer for the next page once the loaded cards run out */\n onLoadMore?: () => void;\n /** Opens another ticket in the central area */\n onOpenTicket?: (ticketId: SupportTicketId) => void;\n /** Notified on filter change (e.g. to filter on the server) */\n onFilterChange?: (filter: SupportHistoryFilter) => void;\n}\n\nconst FILTERS: { value: SupportHistoryFilter; label: string }[] = [\n { value: SUPPORT_HISTORY_FILTER.ALL, label: 'Todos' },\n { value: SUPPORT_HISTORY_FILTER.OPEN, label: 'Abertos' },\n { value: SUPPORT_HISTORY_FILTER.DONE, label: 'Concluídos' },\n { value: SUPPORT_HISTORY_FILTER.AI, label: 'IA' },\n];\n\n// `warning` rather than `orange` for the human statuses: the `orange-*`\n// colors are not theme tokens, so they would not follow dark mode.\nconst STATUS_BADGE: Record<\n SupportTicketCardStatus,\n { label: string; action: 'info' | 'warning' | 'success' }\n> = {\n [SUPPORT_TICKET_CARD_STATUS.IN_PROGRESS]: {\n label: 'EM ANDAMENTO',\n action: 'info',\n },\n [SUPPORT_TICKET_CARD_STATUS.WAITING_HUMAN]: {\n label: 'AGUARDANDO HUMANO',\n action: 'warning',\n },\n [SUPPORT_TICKET_CARD_STATUS.HUMAN]: {\n label: 'HUMANO',\n action: 'warning',\n },\n [SUPPORT_TICKET_CARD_STATUS.DONE]: {\n label: 'CONCLUÍDO',\n action: 'success',\n },\n};\n\nconst resolverLabel = (ticket: SupportTicketSummary) => {\n if (!ticket.resolvedBy) return null;\n return ticket.resolvedBy.type === 'ai' ? 'IA' : ticket.resolvedBy.name;\n};\n\nconst PRIORITY_LABELS: Record<SupportTicketPriority, string> = {\n [SUPPORT_TICKET_PRIORITY.LOW]: 'Baixa',\n [SUPPORT_TICKET_PRIORITY.NORMAL]: 'Normal',\n [SUPPORT_TICKET_PRIORITY.HIGH]: 'Alta',\n [SUPPORT_TICKET_PRIORITY.URGENT]: 'Urgente',\n};\n\n/**\n * Ticket of the history list. The primary info is always visible; the\n * chevron expands the secondary details (priority, channel, duration) and\n * the link that opens the ticket.\n */\nconst TicketCard = ({\n ticket,\n current,\n onOpen,\n}: {\n ticket: SupportTicketSummary;\n current: boolean;\n onOpen?: () => void;\n}) => {\n const [expanded, setExpanded] = useState(false);\n const detailsId = useId();\n const badge = STATUS_BADGE[ticket.status];\n const resolver = current ? 'Você' : resolverLabel(ticket);\n const meta = [\n formatCardDate(ticket.createdAt),\n ticket.reason,\n ticket.subreason,\n ]\n .filter(Boolean)\n .join(' · ');\n\n const details: [string, string][] = [];\n if (ticket.priority) {\n details.push(['Prioridade', PRIORITY_LABELS[ticket.priority]]);\n }\n const channel = [ticket.channel, ticket.origin].filter(Boolean).join(' · ');\n if (channel) details.push(['Canal', channel]);\n if (current) details.push(['Duração', 'Ticket atual']);\n else if (ticket.durationMin != null) {\n details.push(['Duração', formatDuration(ticket.durationMin)]);\n }\n const canOpen = !current && Boolean(onOpen);\n const expandable = details.length > 0 || canOpen;\n\n return (\n <div\n aria-current={current ? 'true' : undefined}\n className={cn(\n 'flex w-full flex-col gap-1.5 rounded-xl border border-border-200 bg-background px-3 py-2.5 hover:border-primary-100'\n )}\n >\n <div className=\"flex items-center justify-between gap-2\">\n {/* The current ticket is marked by color only (no background). */}\n <Text\n size=\"xs\"\n weight={current ? 'semibold' : undefined}\n color={current ? 'text-primary-800' : 'text-text-600'}\n >\n {ticket.code ?? `#${ticket.id}`}\n </Text>\n <div className=\"flex shrink-0 items-center gap-1\">\n <Badge\n variant=\"solid\"\n action={badge.action}\n size=\"small\"\n className=\"font-bold\"\n >\n {badge.label}\n </Badge>\n {expandable && (\n <Button\n variant=\"raw\"\n onClick={() => setExpanded((open) => !open)}\n aria-expanded={expanded}\n aria-controls={detailsId}\n aria-label={`${expanded ? 'Recolher' : 'Expandir'} ticket ${ticket.code ?? `#${ticket.id}`}`}\n className=\"rounded-sm p-0.5 text-text-600 hover:text-text-950 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indicator-info\"\n >\n <CaretDownIcon\n size={14}\n aria-hidden=\"true\"\n className={cn('transition-transform', expanded && 'rotate-180')}\n />\n </Button>\n )}\n </div>\n </div>\n <Text\n size=\"sm\"\n weight=\"semibold\"\n color=\"text-text-950\"\n className=\"line-clamp-2\"\n >\n {ticket.title}\n </Text>\n <Text size=\"xs\" color=\"text-text-600\">\n {meta}\n </Text>\n {resolver && (\n <Text size=\"xs\" color=\"text-text-600\">\n {current ? 'Atendido por: ' : 'Resolvido por: '}\n <Text as=\"span\" size=\"xs\" weight=\"medium\" color=\"text-text-950\">\n {resolver}\n </Text>\n </Text>\n )}\n {expandable && expanded && (\n <div\n id={detailsId}\n className=\"flex flex-col gap-1.5 border-t border-border-100 pt-2\"\n >\n {details.length > 0 && (\n <dl className=\"flex flex-col gap-1\">\n {details.map(([key, value]) => (\n <div\n key={key}\n className=\"flex items-baseline justify-between gap-3\"\n >\n <Text as=\"dt\" size=\"xs\" color=\"text-text-600\">\n {key}\n </Text>\n <Text as=\"dd\" size=\"xs\" weight=\"medium\" color=\"text-text-950\">\n {value}\n </Text>\n </div>\n ))}\n </dl>\n )}\n {canOpen && (\n <Button\n variant=\"link\"\n size=\"extra-small\"\n onClick={onOpen}\n className=\"self-start p-0! font-medium\"\n >\n Abrir atendimento\n </Button>\n )}\n </div>\n )}\n </div>\n );\n};\n\n/**\n * History tab: summary stats, single-choice filter and the contact's\n * tickets, current one pinned on top.\n */\nexport default function SupportHistoryTab({\n currentTicketId,\n tickets,\n summary,\n loading = false,\n hasMore = false,\n onLoadMore,\n onOpenTicket,\n onFilterChange,\n}: Readonly<SupportHistoryTabProps>) {\n const [filter, setFilter] = useState<SupportHistoryFilter>(\n SUPPORT_HISTORY_FILTER.ALL\n );\n const [visible, setVisible] = useState(INITIAL_VISIBLE);\n\n const selectFilter = (next: SupportHistoryFilter) => {\n setFilter(next);\n setVisible(INITIAL_VISIBLE);\n onFilterChange?.(next);\n };\n\n const current = tickets.find((ticket) => ticket.id === currentTicketId);\n const others = tickets\n .filter((ticket) => ticket.id !== currentTicketId)\n .sort(\n (a, b) =>\n new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n );\n const ordered = [...(current ? [current] : []), ...others].filter((ticket) =>\n matchesHistoryFilter(ticket, filter)\n );\n const shown = ordered.slice(0, visible);\n const canShowMore = ordered.length > visible || hasMore;\n const isFirstContact = !loading && tickets.length <= 1;\n\n const showMore = () => {\n if (ordered.length <= visible + PAGE_SIZE && hasMore) onLoadMore?.();\n setVisible((count) => count + PAGE_SIZE);\n };\n\n return (\n <div className=\"flex flex-col gap-4\">\n <div className=\"grid grid-cols-3 gap-2\">\n <StatTile label=\"Tickets\" value={summary.total} valueSize=\"md\" />\n <StatTile label=\"Resolvidos\" value={summary.resolved} valueSize=\"md\" />\n <StatTile\n label=\"Média\"\n value={summary.avgMin == null ? '—' : formatDuration(summary.avgMin)}\n valueSize=\"md\"\n />\n </div>\n\n <div\n role=\"radiogroup\"\n aria-label=\"Filtrar tickets\"\n className=\"flex flex-wrap gap-1.5\"\n >\n {FILTERS.map((item) => (\n <Chips\n key={item.value}\n role=\"radio\"\n aria-checked={filter === item.value}\n selected={filter === item.value}\n onClick={() => selectFilter(item.value)}\n className=\"px-3 py-1 text-xs\"\n >\n {item.label}\n </Chips>\n ))}\n </div>\n\n {loading ? (\n <div\n className=\"flex flex-col gap-2\"\n aria-busy=\"true\"\n aria-label=\"Carregando histórico\"\n >\n <Skeleton variant=\"rounded\" height={96} />\n <Skeleton variant=\"rounded\" height={96} />\n <Skeleton variant=\"rounded\" height={96} />\n </div>\n ) : (\n <>\n {shown.length === 0 ? (\n <Text size=\"xs\" color=\"text-text-600\" className=\"text-center\">\n Nenhum ticket com esse filtro\n </Text>\n ) : (\n <ul aria-label=\"Tickets do usuário\" className=\"flex flex-col gap-2\">\n {shown.map((ticket) => {\n const isCurrent = ticket.id === currentTicketId;\n return (\n <li key={ticket.id}>\n <TicketCard\n ticket={ticket}\n current={isCurrent}\n onOpen={\n onOpenTicket ? () => onOpenTicket(ticket.id) : undefined\n }\n />\n </li>\n );\n })}\n </ul>\n )}\n\n {isFirstContact && filter === SUPPORT_HISTORY_FILTER.ALL && (\n <Text size=\"xs\" color=\"text-text-600\" className=\"text-center\">\n Primeiro atendimento deste usuário\n </Text>\n )}\n\n {canShowMore && (\n <Button\n variant=\"link\"\n size=\"extra-small\"\n onClick={showMore}\n className=\"self-center p-0! font-medium\"\n >\n Ver todos os atendimentos\n </Button>\n )}\n </>\n )}\n </div>\n );\n}\n","import { useId } from 'react';\nimport Select, {\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../Select/Select';\nimport Text from '../Text/Text';\nimport { Skeleton } from '../Skeleton/Skeleton';\nimport SupportTimelineItem from '../SupportTimeline/SupportTimelineItem';\nimport {\n SUPPORT_TICKET_PRIORITY,\n type SupportReasonOption,\n type SupportTicketDetails,\n type SupportTicketPriority,\n} from '../../types/supportUserPanel';\nimport {\n FieldLabel,\n StatTile,\n useNow,\n useOptimisticValue,\n} from './SupportPanelShared';\nimport {\n formatDuration,\n formatOpenedAt,\n formatTimelineTime,\n minutesBetween,\n} from './supportUserPanelUtils';\n\n/** Props for the ticket details tab */\nexport interface SupportTicketDetailsTabProps {\n ticket?: SupportTicketDetails | null;\n loading?: boolean;\n /** Reason catalog (motivos / FAQ) */\n reasonOptions: SupportReasonOption[];\n /** Persists the reason; reject to roll back */\n onReasonChange?: (reason: string) => Promise<void> | void;\n /** Persists the priority; reject to roll back */\n onPriorityChange?: (priority: SupportTicketPriority) => Promise<void> | void;\n /**\n * Current status of the ticket (e.g. \"EM_ANDAMENTO\"). With `statusOptions`\n * the tab shows a Status select on top; it stays editable on a concluded\n * ticket, so the agent can reopen it.\n */\n status?: string;\n statusOptions?: SupportReasonOption[];\n /** Persists the status; reject to roll back */\n onStatusChange?: (status: string) => Promise<void> | void;\n /** Who handles the ticket (e.g. \"HUMANO\"); shown with `handlerOptions` */\n handler?: string;\n handlerOptions?: SupportReasonOption[];\n /** Persists who handles the ticket; reject to roll back */\n onHandlerChange?: (handler: string) => Promise<void> | void;\n}\n\n/** Labelled select of the tab, with optimistic save and rollback */\nconst OptionSelect = ({\n label,\n value,\n options,\n onChange,\n disabled,\n placeholder,\n}: {\n label: string;\n value: string;\n options: SupportReasonOption[];\n onChange: (value: string) => void;\n disabled: boolean;\n placeholder?: string;\n}) => {\n const labelId = useId();\n return (\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel id={labelId}>{label}</FieldLabel>\n <Select\n value={value}\n onValueChange={(next) => {\n if (next !== value) onChange(next);\n }}\n >\n <SelectTrigger\n aria-labelledby={labelId}\n disabled={disabled}\n className=\"w-full\"\n >\n <SelectValue placeholder={placeholder} />\n </SelectTrigger>\n <SelectContent>\n {options.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n );\n};\n\nconst PRIORITIES: { value: SupportTicketPriority; label: string }[] = [\n { value: SUPPORT_TICKET_PRIORITY.LOW, label: 'Baixa' },\n { value: SUPPORT_TICKET_PRIORITY.NORMAL, label: 'Normal' },\n { value: SUPPORT_TICKET_PRIORITY.HIGH, label: 'Alta' },\n { value: SUPPORT_TICKET_PRIORITY.URGENT, label: 'Urgente' },\n];\n\nconst DetailsSkeleton = () => (\n <div\n className=\"flex flex-col gap-4\"\n aria-busy=\"true\"\n aria-label=\"Carregando ticket\"\n >\n <div className=\"grid grid-cols-2 gap-2\">\n {[0, 1, 2, 3].map((key) => (\n <Skeleton key={key} variant=\"rounded\" height={56} />\n ))}\n </div>\n <Skeleton variant=\"rounded\" height={40} />\n <Skeleton variant=\"rounded\" height={36} />\n <Skeleton variant=\"rounded\" height={88} />\n </div>\n);\n\n/**\n * Ticket details tab: channel/time stats, the optional status and \"Atendido\n * por\" selects, the editable reason and priority (read-only once the ticket\n * is concluded, except the status, which can reopen it), the AI summary and\n * the status timeline.\n */\nexport default function SupportTicketDetailsTab({\n ticket,\n loading = false,\n reasonOptions,\n onReasonChange,\n onPriorityChange,\n status,\n statusOptions,\n onStatusChange,\n handler,\n handlerOptions,\n onHandlerChange,\n}: Readonly<SupportTicketDetailsTabProps>) {\n const reasonLabelId = useId();\n const priorityLabelId = useId();\n const done = ticket?.done ?? false;\n const now = useNow(Boolean(ticket) && !done);\n const [reason, setReason] = useOptimisticValue(\n ticket?.reason ?? '',\n onReasonChange\n );\n const [statusValue, setStatusValue] = useOptimisticValue(\n status ?? '',\n onStatusChange\n );\n const [handlerValue, setHandlerValue] = useOptimisticValue(\n handler ?? '',\n onHandlerChange\n );\n const [priority, setPriority] = useOptimisticValue<SupportTicketPriority>(\n ticket?.priority ?? SUPPORT_TICKET_PRIORITY.NORMAL,\n onPriorityChange\n );\n\n if (loading || !ticket) return <DetailsSkeleton />;\n\n // Wait = opening → first human reply; it keeps running while nobody has\n // answered yet. Total = opening → conclusion (or now while open).\n const waitEnd = ticket.firstHumanAt ?? ticket.closedAt;\n const waitingMin = minutesBetween(ticket.openedAt, waitEnd, now);\n const totalMin = minutesBetween(ticket.openedAt, ticket.closedAt, now);\n const readOnly = done;\n\n return (\n <div className=\"flex flex-col gap-4\">\n <div className=\"grid grid-cols-2 gap-2\">\n <StatTile\n label=\"Canal\"\n value={\n ticket.origin\n ? `${ticket.channel} · ${ticket.origin}`\n : ticket.channel\n }\n />\n <StatTile label=\"Aberto em\" value={formatOpenedAt(ticket.openedAt)} />\n <StatTile label=\"Tempo de espera\" value={formatDuration(waitingMin)} />\n <StatTile label=\"Tempo total\" value={formatDuration(totalMin)} />\n </div>\n\n {statusOptions && statusOptions.length > 0 && (\n <OptionSelect\n label=\"Status\"\n value={statusValue}\n options={statusOptions}\n onChange={(value) => void setStatusValue(value)}\n disabled={!onStatusChange}\n />\n )}\n\n {handlerOptions && handlerOptions.length > 0 && (\n <OptionSelect\n label=\"Atendido por\"\n value={handlerValue}\n options={handlerOptions}\n onChange={(value) => void setHandlerValue(value)}\n disabled={readOnly || !onHandlerChange}\n />\n )}\n\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel id={reasonLabelId}>Motivo</FieldLabel>\n <Select value={reason} onValueChange={setReason}>\n <SelectTrigger\n aria-labelledby={reasonLabelId}\n disabled={readOnly || !onReasonChange}\n className=\"w-full\"\n >\n <SelectValue placeholder=\"Não definido\" />\n </SelectTrigger>\n <SelectContent>\n {reasonOptions.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"flex flex-col gap-1.5\">\n <FieldLabel id={priorityLabelId}>Prioridade</FieldLabel>\n <Select\n value={priority}\n onValueChange={(value) => {\n if (value !== priority) {\n setPriority(value as SupportTicketPriority);\n }\n }}\n >\n <SelectTrigger\n aria-labelledby={priorityLabelId}\n disabled={readOnly || !onPriorityChange}\n className=\"w-full\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {PRIORITIES.map((item) => (\n <SelectItem key={item.value} value={item.value}>\n {item.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <section\n aria-label=\"Resumo da IA\"\n className=\"flex flex-col gap-1.5 rounded-xl border border-info-100 bg-info-background p-3\"\n >\n <Text\n as=\"h3\"\n size=\"xs\"\n weight=\"bold\"\n color=\"text-info-800\"\n className=\"uppercase\"\n >\n <span aria-hidden=\"true\">✦ </span>Resumo da IA\n </Text>\n <Text\n size=\"xs\"\n color={ticket.aiSummary ? 'text-text-950' : 'text-text-600'}\n className=\"leading-[1.45]\"\n >\n {ticket.aiSummary ||\n 'A IA ainda não gerou um resumo para este ticket.'}\n </Text>\n </section>\n\n {ticket.timeline.length > 0 && (\n <ol aria-label=\"Linha do tempo de status\" className=\"flex flex-col\">\n {ticket.timeline.map((event) => (\n <li key={`${event.status}-${event.at}`}>\n <SupportTimelineItem\n status={event.status}\n time={formatTimelineTime(event.at)}\n />\n </li>\n ))}\n </ol>\n )}\n </div>\n );\n}\n"]}
@@ -1,14 +1,14 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
3
 
4
- var _chunkHE66Y2T3js = require('./chunk-HE66Y2T3.js');
4
+ var _chunkVQ7MSYIHjs = require('./chunk-VQ7MSYIH.js');
5
5
 
6
6
 
7
7
 
8
8
 
9
9
 
10
10
 
11
- var _chunkNP6KVOAVjs = require('./chunk-NP6KVOAV.js');
11
+ var _chunk64WFAQC6js = require('./chunk-64WFAQC6.js');
12
12
 
13
13
 
14
14
  var _chunkQOF47WYZjs = require('./chunk-QOF47WYZ.js');
@@ -105,13 +105,13 @@ var TicketCard = ({
105
105
  {
106
106
  variant: "solid",
107
107
  className: "flex items-center gap-1",
108
- action: _chunkNP6KVOAVjs.getStatusBadgeAction.call(void 0, ticket.status),
109
- children: _chunkNP6KVOAVjs.getStatusText.call(void 0, ticket.status)
108
+ action: _chunk64WFAQC6js.getStatusBadgeAction.call(void 0, ticket.status),
109
+ children: _chunk64WFAQC6js.getStatusText.call(void 0, ticket.status)
110
110
  }
111
111
  ),
112
112
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkJVDEOFXDjs.Badge_default, { variant: "solid", className: "flex items-center gap-1", action: "muted", children: [
113
- _chunkHE66Y2T3js.getCategoryIcon.call(void 0, ticket.category, 18),
114
- _chunkNP6KVOAVjs.getCategoryText.call(void 0, ticket.category)
113
+ _chunkVQ7MSYIHjs.getCategoryIcon.call(void 0, ticket.category, 18),
114
+ _chunk64WFAQC6js.getCategoryText.call(void 0, ticket.category)
115
115
  ] }),
116
116
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.CaretRightIcon, { size: 24, className: "text-text-800" })
117
117
  ] })
@@ -156,7 +156,8 @@ var Support = ({
156
156
  emptyStateImage,
157
157
  title = "Suporte",
158
158
  onTicketCreated,
159
- onTicketClosed
159
+ onTicketClosed,
160
+ origin
160
161
  }) => {
161
162
  const [activeTab, setActiveTab] = _react.useState.call(void 0, "criar-pedido");
162
163
  const [selectedProblem, setSelectedProblem] = _react.useState.call(void 0, null);
@@ -198,7 +199,7 @@ var Support = ({
198
199
  return {
199
200
  id: apiTicket.id,
200
201
  title: apiTicket.subject,
201
- status: _chunkNP6KVOAVjs.mapApiStatusToInternal.call(void 0, apiTicket.status),
202
+ status: _chunk64WFAQC6js.mapApiStatusToInternal.call(void 0, apiTicket.status),
202
203
  createdAt: apiTicket.createdAt,
203
204
  category: apiTicket.type,
204
205
  description: apiTicket.description
@@ -248,7 +249,7 @@ var Support = ({
248
249
  // Buscar o máximo permitido pela API
249
250
  });
250
251
  if (status && status !== "todos") {
251
- const apiStatus = _chunkNP6KVOAVjs.mapInternalStatusToApi.call(void 0, status);
252
+ const apiStatus = _chunk64WFAQC6js.mapInternalStatusToApi.call(void 0, status);
252
253
  params.append("status", apiStatus);
253
254
  }
254
255
  const response = await apiClient.get(
@@ -274,7 +275,8 @@ var Support = ({
274
275
  const requestData = {
275
276
  subject: data.title,
276
277
  description: data.description,
277
- type: data.problemType
278
+ type: data.problemType,
279
+ ...origin ? { origin } : {}
278
280
  };
279
281
  await apiClient.post(
280
282
  "/support",
@@ -303,7 +305,7 @@ var Support = ({
303
305
  const handleTicketClose = async (ticketId) => {
304
306
  try {
305
307
  await apiClient.patch(`/support/${ticketId}`, {
306
- status: _chunkNP6KVOAVjs.mapInternalStatusToApi.call(void 0, "encerrado" /* ENCERRADO */)
308
+ status: _chunk64WFAQC6js.mapInternalStatusToApi.call(void 0, "encerrado" /* ENCERRADO */)
307
309
  });
308
310
  setShowCloseSuccessToast(true);
309
311
  setTimeout(() => setShowCloseSuccessToast(false), 4e3);
@@ -517,7 +519,7 @@ var Support = ({
517
519
  ] })
518
520
  ] }) }),
519
521
  selectedTicket && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
520
- _chunkHE66Y2T3js.TicketModal,
522
+ _chunkVQ7MSYIHjs.TicketModal,
521
523
  {
522
524
  ticket: selectedTicket,
523
525
  isOpen: isModalOpen,
@@ -1098,4 +1100,4 @@ var TicketList = ({
1098
1100
 
1099
1101
 
1100
1102
  exports.supportSchema = supportSchema; exports.Support_default = Support_default; exports.SidebarMenuItem = SidebarMenuItem; exports.formatTicketTime = formatTicketTime; exports.TicketListItem = TicketListItem; exports.useInfiniteScrollSentinel = useInfiniteScrollSentinel; exports.TicketList = TicketList;
1101
- //# sourceMappingURL=chunk-SQDLSJBL.js.map
1103
+ //# sourceMappingURL=chunk-YRTIDZTN.js.map