analytica-frontend-lib
Version:
Repositório público dos componentes utilizados nas plataformas da Analytica Ensino
747 lines (682 loc) • 27.9 kB
JavaScript
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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; }
var _chunk4GQ3XCIGjs = require('./chunk-4GQ3XCIG.js');
var _chunkBMPQID7Yjs = require('./chunk-BMPQID7Y.js');
var _chunkHZE6VBF5js = require('./chunk-HZE6VBF5.js');
var _chunkSZD7L65Qjs = require('./chunk-SZD7L65Q.js');
var _chunkJL5R5KTYjs = require('./chunk-JL5R5KTY.js');
var _chunkNEDUOGWUjs = require('./chunk-NEDUOGWU.js');
var _chunkBVUPM6EYjs = require('./chunk-BVUPM6EY.js');
var _chunk34ST3MKOjs = require('./chunk-34ST3MKO.js');
var _chunkANT66KVKjs = require('./chunk-ANT66KVK.js');
var _chunkTN3AYOMVjs = require('./chunk-TN3AYOMV.js');
// src/components/Chatbot/Chatbot.tsx
var _react = require('react');
// src/components/Chatbot/ChatbotFab.tsx
var _react3 = require('@phosphor-icons/react');
var _jsxruntime = require('react/jsx-runtime');
function ChatbotFab({
onClick,
isOpen = false,
unreadCount = 0,
className
}) {
const noun = unreadCount === 1 ? "mensagem n\xE3o lida" : "mensagens n\xE3o lidas";
let badgeLabel;
if (unreadCount > 9) {
badgeLabel = "Mais de 9 mensagens n\xE3o lidas";
} else {
badgeLabel = `${unreadCount} ${noun}`;
}
const baseAriaLabel = isOpen ? "Fechar assistente" : "Abrir assistente de estudos";
const ariaLabel = unreadCount > 0 ? `${baseAriaLabel} (${badgeLabel})` : baseAriaLabel;
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
_chunk34ST3MKOjs.Button_default,
{
variant: "raw",
onClick,
"aria-label": ariaLabel,
"aria-expanded": isOpen,
className: _chunkTN3AYOMVjs.cn.call(void 0,
"fixed bottom-6 right-6 z-40",
"flex h-14 w-14 items-center justify-center rounded-full",
"bg-primary-500 text-white shadow-lg",
"transition-all hover:bg-primary-600 active:scale-95",
"focus:outline-none focus:ring-2 focus:ring-primary-300",
className
),
children: [
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.ChatCircleDotsIcon, { size: 26, weight: "fill" }),
unreadCount > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunkANT66KVKjs.Text_default,
{
as: "span",
size: "xs",
weight: "bold",
color: "text-white",
"data-testid": "chatbot-fab-badge",
"aria-live": "polite",
"aria-label": badgeLabel,
className: "absolute -top-1 -right-1 flex h-5 min-w-5 items-center justify-center rounded-full bg-error-500 px-1",
children: unreadCount > 9 ? "9+" : unreadCount
}
)
]
}
);
}
// src/components/Chatbot/ChatbotPanel.tsx
var HEADER_ICON_BUTTON_CLASSES = "!text-white hover:!bg-white/15 hover:!text-white focus-visible:!ring-white/60";
function ChatbotPanel({
isOpen,
onClose,
onStartNew,
historySlot,
messagesSlot,
inputSlot,
errorMessage,
className
}) {
const [showHistory, setShowHistory] = _react.useState.call(void 0, false);
const [isMinimized, setIsMinimized] = _react.useState.call(void 0, false);
const closeButtonRef = _react.useRef.call(void 0, null);
const previouslyFocusedRef = _react.useRef.call(void 0, null);
const previousErrorRef = _react.useRef.call(void 0, errorMessage);
_react.useEffect.call(void 0, () => {
if (isOpen) {
setIsMinimized(false);
}
}, [isOpen]);
_react.useEffect.call(void 0, () => {
const previous = previousErrorRef.current;
if (errorMessage && errorMessage !== previous) {
setIsMinimized(false);
}
previousErrorRef.current = errorMessage;
}, [errorMessage]);
_react.useEffect.call(void 0, () => {
if (!isOpen) return;
previouslyFocusedRef.current = document.activeElement;
_optionalChain([closeButtonRef, 'access', _ => _.current, 'optionalAccess', _2 => _2.focus, 'call', _3 => _3()]);
const handleKeyDown = (event) => {
if (event.key === "Escape") {
event.stopPropagation();
onClose();
}
};
globalThis.addEventListener("keydown", handleKeyDown);
return () => {
globalThis.removeEventListener("keydown", handleKeyDown);
const previous = previouslyFocusedRef.current;
if (previous && typeof previous.focus === "function") {
previous.focus();
}
};
}, [isOpen, onClose]);
if (!isOpen) return null;
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
"dialog",
{
open: true,
"aria-label": "Assistente de estudos",
style: isMinimized ? void 0 : { height: "min(720px, calc(100vh - 3rem))" },
className: _chunkTN3AYOMVjs.cn.call(void 0,
// `<dialog open>` comes with `margin: auto` by default; `m-0`
// resets that so the `fixed` positioning below pins the panel
// to the bottom-right as intended. The panel sits at the same
// bottom-right corner as the FAB (the FAB is hidden while the
// panel is open to avoid stacking).
"fixed bottom-6 right-6 z-40 m-0",
// Responsive sizing: fills small viewports without overflowing,
// yet caps at the intended desktop footprint on larger screens.
// The panel widens when the history sidebar is visible so the
// main chat column keeps enough horizontal room for messages.
"flex w-[calc(100vw-3rem)] flex-col overflow-hidden rounded-2xl p-0",
showHistory ? "max-w-[620px] sm:max-w-[640px]" : "max-w-[400px] sm:max-w-[420px]",
"border border-background-200 bg-background shadow-2xl",
className
),
children: [
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-between gap-2 bg-primary-500 px-4 py-3 text-white", children: [
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex min-w-0 items-center gap-3", children: [
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"div",
{
"aria-hidden": "true",
className: "flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-full bg-white/15 text-white",
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.RobotIcon, { size: 20, weight: "fill" })
}
),
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex min-w-0 flex-col", children: [
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunkANT66KVKjs.Text_default,
{
size: "md",
weight: "semibold",
className: "truncate leading-tight text-white",
children: "Assistente de estudos"
}
),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkANT66KVKjs.Text_default, { size: "2xs", className: "truncate leading-tight text-white/80", children: "Tire d\xFAvidas enquanto estuda" })
] })
] }),
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1", children: [
!isMinimized && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunkBVUPM6EYjs.IconButton_default,
{
size: "sm",
"aria-label": showHistory ? "Ocultar hist\xF3rico" : "Mostrar hist\xF3rico",
onClick: () => setShowHistory((v) => !v),
icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.ListIcon, { size: 18 }),
className: HEADER_ICON_BUTTON_CLASSES
}
),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunkBVUPM6EYjs.IconButton_default,
{
size: "sm",
"aria-label": "Nova conversa",
onClick: onStartNew,
icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.PlusIcon, { size: 18 }),
className: HEADER_ICON_BUTTON_CLASSES
}
)
] }),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunkBVUPM6EYjs.IconButton_default,
{
size: "sm",
"aria-label": isMinimized ? "Expandir assistente" : "Minimizar assistente",
"aria-expanded": !isMinimized,
onClick: () => setIsMinimized((v) => !v),
icon: isMinimized ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.CaretUpIcon, { size: 18 }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.MinusIcon, { size: 18 }),
className: HEADER_ICON_BUTTON_CLASSES
}
),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunkBVUPM6EYjs.IconButton_default,
{
ref: closeButtonRef,
size: "sm",
"aria-label": "Fechar assistente",
onClick: onClose,
icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.XIcon, { size: 18 }),
className: HEADER_ICON_BUTTON_CLASSES
}
)
] })
] }),
!isMinimized && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-1 overflow-hidden border-t border-background-200", children: [
showHistory && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-44 shrink-0 border-r border-background-200", children: historySlot }),
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-1 flex-col", children: [
messagesSlot,
errorMessage && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"div",
{
role: "alert",
"aria-live": "assertive",
className: "border-t border-error-200 bg-error-50 px-3 py-2",
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkANT66KVKjs.Text_default, { size: "xs", className: "text-error-700", children: errorMessage })
}
),
inputSlot
] })
] })
]
}
);
}
// src/components/Chatbot/ChatbotMessageList.tsx
// src/components/Chatbot/ChatbotMessage.tsx
// src/components/Chatbot/ChatbotContentRenderer.tsx
var _reactmarkdown = require('react-markdown'); var _reactmarkdown2 = _interopRequireDefault(_reactmarkdown);
var _remarkgfm = require('remark-gfm'); var _remarkgfm2 = _interopRequireDefault(_remarkgfm);
var MATH_CHAR_PATTERN = /[\\^_{}]/;
function collectDollarIndices(content) {
const result = [];
for (let i = 0; i < content.length; i++) {
if (content[i] === "$" && content[i - 1] !== "\\") {
result.push(i);
}
}
return result;
}
function hasInlineMathSpan(content, indices) {
for (let i = 0; i < indices.length; i++) {
for (let j = i + 1; j < indices.length; j++) {
const inner = content.slice(indices[i] + 1, indices[j]);
if (inner.includes("\n")) break;
if (MATH_CHAR_PATTERN.test(inner)) return true;
}
}
return false;
}
function looksLikeMath(content) {
if (!_chunkHZE6VBF5js.containsMath.call(void 0, content)) return false;
if (/\$\$[\s\S]+?\$\$/.test(content)) return true;
if (/\\begin\{[^}]+\}[\s\S]+?\\end\{[^}]+\}/.test(content)) return true;
return hasInlineMathSpan(content, collectDollarIndices(content));
}
function ChatbotContentRenderer({
content,
className
}) {
if (looksLikeMath(content)) {
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunkHZE6VBF5js.HtmlMathRenderer_default,
{
content,
className: _chunkTN3AYOMVjs.cn.call(void 0, "whitespace-pre-wrap break-words", className)
}
);
}
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"div",
{
className: _chunkTN3AYOMVjs.cn.call(void 0,
"prose prose-sm max-w-none break-words",
// tighten prose defaults so the bubble feels compact
"[&>*:first-child]:mt-0 [&>*:last-child]:mb-0",
className
),
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactmarkdown2.default, { remarkPlugins: [_remarkgfm2.default], children: content })
}
);
}
// src/components/Chatbot/ChatbotMessage.tsx
function formatTimestamp(value) {
const date = value instanceof Date ? value : new Date(value);
if (Number.isNaN(date.getTime())) return "";
return date.toLocaleTimeString("pt-BR", {
hour: "2-digit",
minute: "2-digit"
});
}
function ChatbotMessage({
message,
className,
contentClassName
}) {
const isUser = message.role === _chunkBMPQID7Yjs.CHATBOT_MESSAGE_ROLES.USER;
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
"div",
{
className: _chunkTN3AYOMVjs.cn.call(void 0,
"flex w-full gap-2",
isUser ? "justify-end" : "justify-start",
className
),
children: [
!isUser && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"div",
{
role: "img",
"aria-label": "Mensagem do assistente",
className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-primary-100 text-primary-600",
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.RobotIcon, { size: 18, weight: "fill", "aria-hidden": "true" })
}
),
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
"div",
{
className: _chunkTN3AYOMVjs.cn.call(void 0,
"max-w-[80%] px-4 py-2",
isUser ? "rounded-2xl rounded-br-md bg-background-200 text-text-900" : "rounded-2xl rounded-bl-md bg-background-100 text-text-900"
),
children: [
isUser ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkANT66KVKjs.Text_default, { size: "sm", className: "whitespace-pre-wrap break-words", children: message.content }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
ChatbotContentRenderer,
{
content: message.content,
className: contentClassName
}
),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkANT66KVKjs.Text_default, { size: "2xs", className: "mt-1 block text-right text-text-700", children: formatTimestamp(message.createdAt) })
]
}
),
isUser && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
"div",
{
role: "img",
"aria-label": "Sua mensagem",
className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-primary-500 text-white",
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.UserIcon, { size: 18, weight: "fill", "aria-hidden": "true" })
}
)
]
}
);
}
// src/components/Chatbot/ChatbotTypingIndicator.tsx
function ChatbotTypingIndicator({
className
}) {
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
"output",
{
"aria-label": "Assistente digitando",
className: _chunkTN3AYOMVjs.cn.call(void 0,
"inline-flex items-center gap-1 rounded-2xl rounded-bl-md bg-background-100 px-4 py-3",
className
),
children: [
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunkANT66KVKjs.Text_default,
{
as: "span",
className: "h-2 w-2 animate-bounce rounded-full bg-text-400 [animation-delay:-0.3s]"
}
),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunkANT66KVKjs.Text_default,
{
as: "span",
className: "h-2 w-2 animate-bounce rounded-full bg-text-400 [animation-delay:-0.15s]"
}
),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunkANT66KVKjs.Text_default,
{
as: "span",
className: "h-2 w-2 animate-bounce rounded-full bg-text-400"
}
)
]
}
);
}
// src/components/Chatbot/ChatbotMessageList.tsx
function ChatbotMessageList({
messages,
isSending = false,
isLoading = false,
emptyHint = "Comece a conversa enviando uma pergunta.",
className
}) {
const bottomRef = _react.useRef.call(void 0, null);
const didMountRef = _react.useRef.call(void 0, false);
_react.useEffect.call(void 0, () => {
if (!didMountRef.current) {
didMountRef.current = true;
return;
}
if (bottomRef.current) {
bottomRef.current.scrollIntoView({ behavior: "smooth", block: "end" });
}
}, [messages.length, isSending]);
const showEmpty = !isLoading && messages.length === 0 && !isSending;
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
"div",
{
role: "log",
"aria-live": "polite",
"aria-relevant": "additions",
className: _chunkTN3AYOMVjs.cn.call(void 0,
"flex-1 overflow-y-auto p-4 space-y-3",
"bg-background-50",
className
),
children: [
showEmpty && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkANT66KVKjs.Text_default, { size: "sm", className: "text-center text-text-400", children: emptyHint }) }),
messages.map((msg) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ChatbotMessage, { message: msg }, msg.id)),
isSending && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex justify-start", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ChatbotTypingIndicator, {}) }),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref: bottomRef })
]
}
);
}
// src/components/Chatbot/ChatbotInput.tsx
var MIN_HEIGHT = 40;
var MAX_HEIGHT = 120;
function ChatbotInput({
onSend,
disabled = false,
placeholder = "Pergunte ao assistente...",
className
}) {
const [value, setValue] = _react.useState.call(void 0, "");
const submit = _react.useCallback.call(void 0, () => {
const trimmed = value.trim();
if (!trimmed || disabled) return;
onSend(trimmed);
setValue("");
}, [disabled, onSend, value]);
const handleKeyDown = _react.useCallback.call(void 0,
(e) => {
if (e.nativeEvent.isComposing) return;
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
submit();
}
},
[submit]
);
const isSendDisabled = disabled || value.trim().length === 0;
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
"div",
{
className: _chunkTN3AYOMVjs.cn.call(void 0,
"flex items-center gap-2 border-t border-background-200 bg-background p-3",
className
),
children: [
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunkSZD7L65Qjs.TextArea_default,
{
value,
onChange: (e) => setValue(e.target.value),
onKeyDown: handleKeyDown,
placeholder,
disabled,
autoResize: true,
minHeight: MIN_HEIGHT,
"aria-label": "Mensagem para o assistente",
className: "w-full",
style: { maxHeight: MAX_HEIGHT, overflowY: "auto" }
}
) }),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunk34ST3MKOjs.Button_default,
{
variant: "raw",
type: "button",
onClick: submit,
disabled: isSendDisabled,
"aria-label": "Enviar mensagem",
className: _chunkTN3AYOMVjs.cn.call(void 0,
"flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-full",
"bg-primary-500 text-white transition-colors",
"hover:bg-primary-600",
"disabled:bg-background-200 disabled:text-text-500 disabled:cursor-not-allowed",
"focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-300"
),
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.PaperPlaneTiltIcon, { size: 20, weight: "fill" })
}
)
]
}
);
}
// src/components/Chatbot/ChatbotConversationList.tsx
function formatDate(value) {
const d = value instanceof Date ? value : new Date(value);
if (Number.isNaN(d.getTime())) return "";
return d.toLocaleDateString("pt-BR", {
day: "2-digit",
month: "2-digit"
});
}
function ChatbotConversationList({
conversations,
activeConversationId,
isLoading = false,
onSelect,
onDelete,
onStartNew,
className
}) {
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
"div",
{
className: _chunkTN3AYOMVjs.cn.call(void 0,
"flex h-full flex-col border-r border-background-200 bg-background",
className
),
children: [
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "p-3", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunk34ST3MKOjs.Button_default,
{
variant: "solid",
action: "primary",
size: "small",
onClick: onStartNew,
iconLeft: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.PlusIcon, { size: 14 }),
className: "w-full",
children: "Nova conversa"
}
) }),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 overflow-y-auto px-2 pb-2", children: renderBody() })
]
}
);
function renderBody() {
if (isLoading) {
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2 px-2", children: [
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNEDUOGWUjs.SkeletonText, {}),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNEDUOGWUjs.SkeletonText, {}),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNEDUOGWUjs.SkeletonText, {})
] });
}
if (conversations.length === 0) {
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "mt-4", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunkJL5R5KTYjs.EmptyState_default,
{
title: "Sem conversas ainda",
description: "Comece sua primeira conversa com o assistente."
}
) });
}
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "space-y-1", children: conversations.map((c) => {
const isActive = c.id === activeConversationId;
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
"div",
{
className: _chunkTN3AYOMVjs.cn.call(void 0,
"group flex items-start gap-2 rounded-md px-2 py-2 transition-colors",
isActive ? "bg-primary-50" : "hover:bg-background-100"
),
children: [
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
_chunk34ST3MKOjs.Button_default,
{
variant: "raw",
onClick: () => onSelect(c.id),
className: "flex-1 text-left",
children: [
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunkANT66KVKjs.Text_default,
{
size: "sm",
weight: "semibold",
className: "truncate text-text-900",
children: c.title || "Conversa sem t\xEDtulo"
}
),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkANT66KVKjs.Text_default, { size: "2xs", className: "text-text-400", children: formatDate(c.lastMessageAt) })
]
}
),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
_chunkBVUPM6EYjs.IconButton_default,
{
size: "sm",
"aria-label": `Excluir conversa ${c.title || ""}`.trim(),
onClick: () => onDelete(c.id),
icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.TrashIcon, { size: 14 })
}
)
]
}
) }, c.id);
}) });
}
}
// src/components/Chatbot/Chatbot.tsx
function Chatbot({
apiClient,
user,
currentContext,
fabClassName,
panelClassName
}) {
const apiClientRef = _react.useRef.call(void 0, apiClient);
apiClientRef.current = apiClient;
const boundHookRef = _react.useRef.call(void 0, null);
boundHookRef.current ??= _chunk4GQ3XCIGjs.createUseChatbot.call(void 0, () => apiClientRef.current);
const useBoundChatbot = boundHookRef.current;
const {
isOpen,
isSending,
isLoadingHistory,
isLoadingMessages,
errorMessage,
conversations,
activeConversationId,
messages,
togglePanel,
closePanel,
selectConversation,
startNewConversation,
sendMessage,
deleteConversation
} = useBoundChatbot();
const firstName = _optionalChain([user, 'access', _4 => _4.name, 'optionalAccess', _5 => _5.trim, 'call', _6 => _6(), 'access', _7 => _7.split, 'call', _8 => _8(/\s+/), 'access', _9 => _9[0]]);
const emptyHint = firstName ? `Ol\xE1, ${firstName}! Como posso ajudar nos seus estudos?` : "Comece a conversa enviando uma pergunta.";
const handleSend = (text) => {
sendMessage(text, currentContext).catch(() => void 0);
};
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
!isOpen && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
ChatbotFab,
{
onClick: togglePanel,
isOpen,
className: fabClassName
}
),
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
ChatbotPanel,
{
isOpen,
onClose: closePanel,
onStartNew: startNewConversation,
className: panelClassName,
errorMessage,
historySlot: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
ChatbotConversationList,
{
conversations,
activeConversationId,
isLoading: isLoadingHistory,
onSelect: selectConversation,
onDelete: deleteConversation,
onStartNew: startNewConversation
}
),
messagesSlot: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
ChatbotMessageList,
{
messages,
isSending,
isLoading: isLoadingMessages,
emptyHint
}
),
inputSlot: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ChatbotInput, { onSend: handleSend, disabled: isSending })
}
)
] });
}
exports.ChatbotFab = ChatbotFab; exports.ChatbotPanel = ChatbotPanel; exports.ChatbotContentRenderer = ChatbotContentRenderer; exports.ChatbotMessage = ChatbotMessage; exports.ChatbotTypingIndicator = ChatbotTypingIndicator; exports.ChatbotMessageList = ChatbotMessageList; exports.ChatbotInput = ChatbotInput; exports.ChatbotConversationList = ChatbotConversationList; exports.Chatbot = Chatbot;
//# sourceMappingURL=chunk-HL5MF7EO.js.map