UNPKG

analytica-frontend-lib

Version:

Repositório público dos componentes utilizados nas plataformas da Analytica Ensino

935 lines (933 loc) 30.1 kB
import { RichEditor } from "./chunk-73DEBAQ6.mjs"; import { ImageUpload } from "./chunk-IPVIZIHN.mjs"; import { sanitizeHtmlForDisplay, stripHtml } from "./chunk-FN4G43WK.mjs"; import { TextArea_default } from "./chunk-LI2FS7M2.mjs"; import { Radio_default } from "./chunk-NLK3GG73.mjs"; import { SkeletonCard, SkeletonList } from "./chunk-NKVUUWCA.mjs"; import { Input_default } from "./chunk-EXVVHZOO.mjs"; import { DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, DropdownMenu_default } from "./chunk-DHHHYBOU.mjs"; import { Modal_default } from "./chunk-TNLGS7SB.mjs"; import { Button_default } from "./chunk-LAYB7IKW.mjs"; import { Text_default } from "./chunk-IMCIR6TJ.mjs"; import { cn } from "./chunk-53ICLDGS.mjs"; // src/components/Forum/Forum.tsx import { useState, useEffect, useCallback } from "react"; import { CaretLeftIcon, ChatCircleTextIcon, CheckIcon, DotsThreeVerticalIcon, ImageIcon, PencilSimpleIcon, TrashIcon } from "@phosphor-icons/react"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; var MONTHS_PT = [ "Janeiro", "Fevereiro", "Mar\xE7o", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro" ]; function formatForumDate(isoDate) { const d = new Date(isoDate); const day = d.getDate(); const month = MONTHS_PT[d.getMonth()]; const year = d.getFullYear(); const hours = d.getHours(); const minutes = d.getMinutes().toString().padStart(2, "0"); return `${day} ${month} ${year} \u2022 ${hours}:${minutes}`; } function getInitials(name) { return name.split(" ").slice(0, 2).map((word) => word[0] ?? "").join("").toUpperCase(); } function formatReplyCount(count) { if (count === 1) return "1 resposta"; return `${count} respostas`; } function AuthorAvatar({ name, photoUrl }) { if (photoUrl) { return /* @__PURE__ */ jsx( "img", { src: photoUrl, alt: name, className: "w-8 h-8 rounded-full object-cover shrink-0" } ); } return /* @__PURE__ */ jsx("div", { className: "w-8 h-8 rounded-full bg-primary-600 flex items-center justify-center shrink-0", children: /* @__PURE__ */ jsx(Text_default, { size: "xs", weight: "semibold", color: "text-white", children: getInitials(name) }) }); } function AuthorMeta({ authorName, authorPhoto, createdAt }) { return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [ /* @__PURE__ */ jsx(AuthorAvatar, { name: authorName, photoUrl: authorPhoto }), /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [ /* @__PURE__ */ jsxs(Text_default, { size: "xs", weight: "semibold", color: "text-primary-700", children: [ "Postado por ", authorName ] }), /* @__PURE__ */ jsxs(Text_default, { size: "xs", color: "text-text-600", children: [ "\u2022 ", formatForumDate(createdAt) ] }) ] }) ] }); } function PostActionsMenu({ onEdit, onDelete }) { return /* @__PURE__ */ jsxs(DropdownMenu_default, { children: [ /* @__PURE__ */ jsx( DropdownMenuTrigger, { "aria-label": "Abrir a\xE7\xF5es do post", className: "p-1 rounded hover:bg-background-100 transition-colors shrink-0", children: /* @__PURE__ */ jsx(DotsThreeVerticalIcon, { size: 20, className: "text-text-600" }) } ), /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", children: [ /* @__PURE__ */ jsx( DropdownMenuItem, { iconLeft: /* @__PURE__ */ jsx(PencilSimpleIcon, { size: 16 }), onClick: onEdit, children: "Editar" } ), /* @__PURE__ */ jsx(DropdownMenuItem, { iconLeft: /* @__PURE__ */ jsx(TrashIcon, { size: 16 }), onClick: onDelete, children: "Deletar" }) ] }) ] }); } function PostContentModal({ isOpen, title, submitLabel, content, imageUrl, isSubmitting, onContentChange, onClose, onSubmit, onUploadImage, onImageUploaded, maxLength, richText = false, showGradeQuestion = false, countsForGrade, onCountsForGradeChange }) { const handleImageSelect = useCallback( async (file) => { if (!onUploadImage) return; try { const url = await onUploadImage(file); onImageUploaded(url); } catch { } }, [onUploadImage, onImageUploaded] ); const plainTextContent = richText ? stripHtml(content) : content; const isContentEmpty = !plainTextContent.trim(); const exceedsMaxLength = plainTextContent.trim().length > maxLength; return /* @__PURE__ */ jsx( Modal_default, { isOpen, onClose, title, size: "md", footer: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [ /* @__PURE__ */ jsx( Button_default, { variant: "outline", action: "secondary", size: "medium", onClick: onClose, children: "Cancelar" } ), /* @__PURE__ */ jsx( Button_default, { variant: "solid", action: "primary", size: "medium", disabled: isContentEmpty || exceedsMaxLength || isSubmitting, onClick: onSubmit, children: submitLabel } ) ] }), children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [ richText ? ( // key forces remount (and thus reset) whenever the modal opens/closes /* @__PURE__ */ jsx( RichEditor, { content, onChange: (data) => onContentChange(data.html), placeholder: "Escreva o conte\xFAdo do seu post aqui." }, String(isOpen) ) ) : /* @__PURE__ */ jsx( TextArea_default, { placeholder: "Escreva o conte\xFAdo do seu post aqui.", value: content, onChange: (e) => onContentChange(e.target.value), autoResize: true, minHeight: 120, maxLength } ), /* @__PURE__ */ jsx( ImageUpload, { variant: "compact", onFileSelect: handleImageSelect, onRemoveFile: () => onImageUploaded(""), buttonIcon: /* @__PURE__ */ jsx(ImageIcon, { size: 16 }) } ), imageUrl && /* @__PURE__ */ jsx( "img", { src: imageUrl, alt: "Preview da imagem", className: "max-h-40 rounded-lg object-contain" } ), showGradeQuestion && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [ /* @__PURE__ */ jsx(Text_default, { size: "sm", weight: "medium", children: "Este f\xF3rum vale nota no boletim?" }), /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [ /* @__PURE__ */ jsx( Radio_default, { name: "countsForGrade", value: "yes", label: "Sim", size: "small", checked: countsForGrade === true, onChange: () => onCountsForGradeChange?.(true) } ), /* @__PURE__ */ jsx( Radio_default, { name: "countsForGrade", value: "no", label: "N\xE3o", size: "small", checked: countsForGrade === false, onChange: () => onCountsForGradeChange?.(false) } ) ] }) ] }) ] }) } ); } function TopicListSkeleton() { return /* @__PURE__ */ jsx(SkeletonList, { items: 3, showAvatar: true, showTitle: true, showDescription: true, lines: 2 }); } function TopicDetailSkeleton() { return /* @__PURE__ */ jsx( SkeletonCard, { showAvatar: true, showTitle: true, showDescription: true, showActions: false, lines: 2 } ); } function Forum({ apiClient, currentUserId, userRole = "STUDENT" /* STUDENT */, title = "F\xF3rum", subtitle = "Espa\xE7o para troca de conhecimento", onUploadImage, onEvaluateReply, className }) { const isTeacher = userRole === "TEACHER" /* TEACHER */; const [view, setView] = useState("list"); const [topics, setTopics] = useState([]); const [isLoadingTopics, setIsLoadingTopics] = useState(false); const [selectedTopic, setSelectedTopic] = useState(null); const [replies, setReplies] = useState([]); const [isLoadingTopic, setIsLoadingTopic] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); const [createContent, setCreateContent] = useState(""); const [createImageUrl, setCreateImageUrl] = useState(); const [createCountsForGrade, setCreateCountsForGrade] = useState(); const [isReplyModalOpen, setIsReplyModalOpen] = useState(false); const [replyContent, setReplyContent] = useState(""); const [replyImageUrl, setReplyImageUrl] = useState(); const [editingTopic, setEditingTopic] = useState(null); const [editTopicContent, setEditTopicContent] = useState(""); const [editTopicImageUrl, setEditTopicImageUrl] = useState(); const [editingReply, setEditingReply] = useState(null); const [editReplyContent, setEditReplyContent] = useState(""); const [editReplyImageUrl, setEditReplyImageUrl] = useState(); const [evaluatingReplyId, setEvaluatingReplyId] = useState( null ); const [gradeValue, setGradeValue] = useState(null); const [isEditingGrade, setIsEditingGrade] = useState(false); const [pendingDelete, setPendingDelete] = useState(null); const fetchTopics = useCallback(async () => { setIsLoadingTopics(true); try { const response = await apiClient.getTopics({ limit: 50 }); setTopics(response.topics); } finally { setIsLoadingTopics(false); } }, [apiClient]); const fetchTopic = useCallback( async (topicId) => { setIsLoadingTopic(true); try { const response = await apiClient.getTopic(topicId); setSelectedTopic(response.topic); setReplies(response.replies); } finally { setIsLoadingTopic(false); } }, [apiClient] ); useEffect(() => { fetchTopics(); }, [fetchTopics]); const handleTopicClick = useCallback( (topic) => { setSelectedTopic(topic); setView("detail"); fetchTopic(topic.id); }, [fetchTopic] ); const handleBack = useCallback(() => { setView("list"); setSelectedTopic(null); setReplies([]); fetchTopics(); }, [fetchTopics]); const handleCloseCreateModal = useCallback(() => { setIsCreateModalOpen(false); setCreateContent(""); setCreateImageUrl(void 0); setCreateCountsForGrade(void 0); }, []); const handleCreateTopic = useCallback(async () => { if (!createContent.trim()) return; setIsSubmitting(true); try { await apiClient.createTopic({ content: createContent.trim(), ...createImageUrl && { imageUrl: createImageUrl }, ...isTeacher && createCountsForGrade !== void 0 && { countsForGrade: createCountsForGrade } }); handleCloseCreateModal(); await fetchTopics(); } finally { setIsSubmitting(false); } }, [ apiClient, createContent, createImageUrl, createCountsForGrade, isTeacher, handleCloseCreateModal, fetchTopics ]); const handleOpenEditTopic = useCallback((topic) => { setEditingTopic(topic); setEditTopicContent(topic.content); setEditTopicImageUrl(topic.imageUrl ?? void 0); }, []); const handleCloseEditTopic = useCallback(() => { setEditingTopic(null); setEditTopicContent(""); setEditTopicImageUrl(void 0); }, []); const handleEditTopic = useCallback(async () => { if (!editingTopic || !editTopicContent.trim()) return; setIsSubmitting(true); try { await apiClient.updateTopic(editingTopic.id, { content: editTopicContent.trim(), imageUrl: editTopicImageUrl ?? null }); handleCloseEditTopic(); if (view === "list") { await fetchTopics(); } else { await fetchTopic(editingTopic.id); } } finally { setIsSubmitting(false); } }, [ apiClient, editingTopic, editTopicContent, editTopicImageUrl, handleCloseEditTopic, view, fetchTopics, fetchTopic ]); const handleDeleteTopic = useCallback( async (topicId) => { setIsSubmitting(true); try { await apiClient.deleteTopic(topicId); if (view === "detail") { handleBack(); } else { await fetchTopics(); } } finally { setIsSubmitting(false); setPendingDelete(null); } }, [apiClient, view, handleBack, fetchTopics] ); const handleCloseReplyModal = useCallback(() => { setIsReplyModalOpen(false); setReplyContent(""); setReplyImageUrl(void 0); }, []); const handleCreateReply = useCallback(async () => { if (!selectedTopic || !replyContent.trim()) return; setIsSubmitting(true); try { await apiClient.createReply(selectedTopic.id, { content: replyContent.trim(), ...replyImageUrl && { imageUrl: replyImageUrl } }); handleCloseReplyModal(); await fetchTopic(selectedTopic.id); } finally { setIsSubmitting(false); } }, [ apiClient, selectedTopic, replyContent, replyImageUrl, handleCloseReplyModal, fetchTopic ]); const handleOpenEditReply = useCallback((reply) => { setEditingReply(reply); setEditReplyContent(reply.content); setEditReplyImageUrl(reply.imageUrl ?? void 0); }, []); const handleCloseEditReply = useCallback(() => { setEditingReply(null); setEditReplyContent(""); setEditReplyImageUrl(void 0); }, []); const handleEditReply = useCallback(async () => { if (!editingReply || !editReplyContent.trim() || !selectedTopic) return; setIsSubmitting(true); try { await apiClient.updateReply(editingReply.id, { content: editReplyContent.trim(), imageUrl: editReplyImageUrl ?? null }); handleCloseEditReply(); await fetchTopic(selectedTopic.id); } finally { setIsSubmitting(false); } }, [ apiClient, editingReply, editReplyContent, editReplyImageUrl, handleCloseEditReply, selectedTopic, fetchTopic ]); const handleDeleteReply = useCallback( async (replyId) => { if (!selectedTopic) return; setIsSubmitting(true); try { await apiClient.deleteReply(replyId); await fetchTopic(selectedTopic.id); } finally { setIsSubmitting(false); setPendingDelete(null); } }, [apiClient, selectedTopic, fetchTopic] ); const handleCloseEvaluateModal = useCallback(() => { setEvaluatingReplyId(null); setGradeValue(null); setIsEditingGrade(false); }, []); const handleOpenEvaluate = useCallback((reply) => { setEvaluatingReplyId(reply.id); setGradeValue(null); setIsEditingGrade(false); }, []); const handleOpenEditGrade = useCallback((reply) => { setEvaluatingReplyId(reply.id); setGradeValue(reply.grade ?? null); setIsEditingGrade(true); }, []); const isValidGrade = gradeValue !== null && Number.isInteger(gradeValue) && gradeValue >= 0 && gradeValue <= 10; const handleSubmitEvaluation = useCallback(async () => { if (!evaluatingReplyId || !isValidGrade || !onEvaluateReply) return; setIsSubmitting(true); try { await onEvaluateReply(evaluatingReplyId, gradeValue); setReplies( (prev) => prev.map( (r) => r.id === evaluatingReplyId ? { ...r, grade: gradeValue } : r ) ); handleCloseEvaluateModal(); } finally { setIsSubmitting(false); } }, [ evaluatingReplyId, gradeValue, isValidGrade, onEvaluateReply, handleCloseEvaluateModal ]); const handleConfirmDelete = useCallback(async () => { if (!pendingDelete) return; if (pendingDelete.type === "topic") { await handleDeleteTopic(pendingDelete.id); } else { await handleDeleteReply(pendingDelete.id); } }, [pendingDelete, handleDeleteTopic, handleDeleteReply]); const topicListContent = (() => { if (isLoadingTopics) return /* @__PURE__ */ jsx(TopicListSkeleton, {}); if (topics.length === 0) { return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-16 border border-border-200 rounded-lg", children: /* @__PURE__ */ jsx(Text_default, { size: "md", color: "text-text-500", children: "Nenhum t\xF3pico ainda. Seja o primeiro a criar um post!" }) }); } return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4", children: topics.map((topic) => /* @__PURE__ */ jsxs( "div", { className: "flex items-start bg-white border border-border-100 rounded-lg pt-4 pr-2 pb-4 pl-2 shadow-sm", children: [ /* @__PURE__ */ jsxs( "button", { type: "button", className: "flex flex-col gap-3 flex-1 min-w-0 text-left hover:opacity-90 transition-opacity", onClick: () => handleTopicClick(topic), children: [ /* @__PURE__ */ jsx( AuthorMeta, { authorName: topic.authorName, authorPhoto: topic.authorPhoto, createdAt: topic.createdAt } ), /* @__PURE__ */ jsx(Text_default, { size: "sm", className: "leading-normal line-clamp-3 ml-10", children: stripHtml(topic.content) }), /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-text-600 ml-10", children: [ /* @__PURE__ */ jsx(ChatCircleTextIcon, { size: 16 }), /* @__PURE__ */ jsx(Text_default, { size: "xs", children: formatReplyCount(topic.replyCount) }) ] }) ] } ), topic.userInstitutionId === currentUserId && /* @__PURE__ */ jsx( PostActionsMenu, { onEdit: () => handleOpenEditTopic(topic), onDelete: () => setPendingDelete({ type: "topic", id: topic.id }) } ) ] }, topic.id )) }); })(); const topicDetailContent = (() => { if (isLoadingTopic) return /* @__PURE__ */ jsx(TopicDetailSkeleton, {}); if (!selectedTopic) return null; return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 flex-1 min-w-0", children: [ /* @__PURE__ */ jsx( AuthorMeta, { authorName: selectedTopic.authorName, authorPhoto: selectedTopic.authorPhoto, createdAt: selectedTopic.createdAt } ), /* @__PURE__ */ jsx( "div", { className: "text-sm text-text-950 leading-normal ml-10 prose prose-sm max-w-none", dangerouslySetInnerHTML: { __html: sanitizeHtmlForDisplay(selectedTopic.content) } } ), selectedTopic.imageUrl && /* @__PURE__ */ jsx( "img", { src: selectedTopic.imageUrl, alt: "Imagem do post", className: "ml-10 max-w-lg rounded-lg" } ) ] }), selectedTopic.userInstitutionId === currentUserId && /* @__PURE__ */ jsx( PostActionsMenu, { onEdit: () => handleOpenEditTopic(selectedTopic), onDelete: () => setPendingDelete({ type: "topic", id: selectedTopic.id }) } ) ] }), /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [ /* @__PURE__ */ jsx(Text_default, { size: "sm", color: "text-text-600", children: formatReplyCount(selectedTopic.replyCount) }), /* @__PURE__ */ jsx( Button_default, { variant: "solid", action: "primary", size: "medium", onClick: () => setIsReplyModalOpen(true), children: "Responder" } ) ] }), replies.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-col divide-y divide-border-200", children: replies.map((reply) => /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2 py-4", children: [ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 flex-1 min-w-0", children: [ /* @__PURE__ */ jsx( AuthorMeta, { authorName: reply.authorName, authorPhoto: reply.authorPhoto, createdAt: reply.createdAt } ), /* @__PURE__ */ jsx( "div", { className: "text-sm text-text-950 leading-normal ml-10 prose prose-sm max-w-none", dangerouslySetInnerHTML: { __html: sanitizeHtmlForDisplay(reply.content) } } ), reply.imageUrl && /* @__PURE__ */ jsx( "img", { src: reply.imageUrl, alt: "Imagem da resposta", className: "ml-10 max-w-lg rounded-lg" } ), isTeacher && selectedTopic?.countsForGrade && onEvaluateReply && (reply.grade == null ? ( /* Not yet graded — show Avaliar button */ /* @__PURE__ */ jsxs( "button", { type: "button", className: "flex items-center gap-1.5 text-text-600 text-sm hover:text-text-950 transition-colors w-fit ml-10", onClick: () => handleOpenEvaluate(reply), children: [ /* @__PURE__ */ jsx(CheckIcon, { size: 16 }), "Avaliar" ] } ) ) : ( /* Grade already set — teacher sees it with edit pencil */ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 ml-10", children: [ /* @__PURE__ */ jsxs(Text_default, { size: "sm", color: "text-text-600", children: [ "Nota ", reply.grade ] }), /* @__PURE__ */ jsx( "button", { type: "button", className: "text-text-600 hover:text-text-950 transition-colors", onClick: () => handleOpenEditGrade(reply), children: /* @__PURE__ */ jsx(PencilSimpleIcon, { size: 14 }) } ) ] }) )), !isTeacher && reply.grade != null && reply.userInstitutionId === currentUserId && selectedTopic?.countsForGrade && /* @__PURE__ */ jsxs(Text_default, { size: "sm", color: "text-text-600", className: "ml-10", children: [ "Nota ", reply.grade ] }) ] }), reply.userInstitutionId === currentUserId && /* @__PURE__ */ jsx( PostActionsMenu, { onEdit: () => handleOpenEditReply(reply), onDelete: () => setPendingDelete({ type: "reply", id: reply.id }) } ) ] }, reply.id)) }) ] }); })(); return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-4", className), children: [ view === "list" ? /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [ /* @__PURE__ */ jsx(Text_default, { as: "h1", size: "2xl", weight: "bold", color: "text-text-950", children: title }), /* @__PURE__ */ jsx( Button_default, { variant: "solid", action: "primary", size: "medium", onClick: () => setIsCreateModalOpen(true), children: "Criar post" } ) ] }), /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [ /* @__PURE__ */ jsx(Text_default, { as: "h2", size: "lg", weight: "semibold", color: "text-text-950", children: subtitle }), topicListContent ] }) ] }) : ( /* Detail view */ /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsxs( "button", { type: "button", className: "flex items-center gap-2 hover:opacity-80 transition-opacity w-fit", onClick: handleBack, children: [ /* @__PURE__ */ jsx(CaretLeftIcon, { size: 24, className: "text-text-950" }), /* @__PURE__ */ jsx(Text_default, { size: "2xl", weight: "bold", children: "Voltar" }) ] } ), topicDetailContent ] }) ), /* @__PURE__ */ jsx( PostContentModal, { isOpen: isCreateModalOpen, title: "Criar post", submitLabel: "Criar post", content: createContent, imageUrl: createImageUrl, isSubmitting, onContentChange: setCreateContent, onClose: handleCloseCreateModal, onSubmit: handleCreateTopic, onUploadImage, onImageUploaded: setCreateImageUrl, maxLength: 1e4, richText: true, showGradeQuestion: isTeacher, countsForGrade: createCountsForGrade, onCountsForGradeChange: setCreateCountsForGrade } ), /* @__PURE__ */ jsx( PostContentModal, { isOpen: isReplyModalOpen, title: "Responder", submitLabel: "Responder", content: replyContent, imageUrl: replyImageUrl, isSubmitting, onContentChange: setReplyContent, onClose: handleCloseReplyModal, onSubmit: handleCreateReply, onUploadImage, onImageUploaded: setReplyImageUrl, maxLength: 5e3, richText: true } ), /* @__PURE__ */ jsx( PostContentModal, { isOpen: !!editingTopic, title: "Editar", submitLabel: "Salvar", content: editTopicContent, imageUrl: editTopicImageUrl, isSubmitting, onContentChange: setEditTopicContent, onClose: handleCloseEditTopic, onSubmit: handleEditTopic, onUploadImage, onImageUploaded: setEditTopicImageUrl, maxLength: 1e4, richText: true } ), /* @__PURE__ */ jsx( PostContentModal, { isOpen: !!editingReply, title: "Editar", submitLabel: "Salvar", content: editReplyContent, imageUrl: editReplyImageUrl, isSubmitting, onContentChange: setEditReplyContent, onClose: handleCloseEditReply, onSubmit: handleEditReply, onUploadImage, onImageUploaded: setEditReplyImageUrl, maxLength: 5e3, richText: true } ), /* @__PURE__ */ jsx( Modal_default, { isOpen: !!evaluatingReplyId, onClose: handleCloseEvaluateModal, title: isEditingGrade ? "Edite a nota da atividade" : "Defina a nota da atividade", size: "md", footer: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [ /* @__PURE__ */ jsx( Button_default, { variant: "outline", action: "secondary", size: "medium", onClick: handleCloseEvaluateModal, children: "Cancelar" } ), /* @__PURE__ */ jsx( Button_default, { variant: "solid", action: "primary", size: "medium", disabled: !isValidGrade || isSubmitting, onClick: handleSubmitEvaluation, children: isEditingGrade ? "Salvar" : "Avaliar" } ) ] }), children: /* @__PURE__ */ jsx( Input_default, { type: "number", min: 0, max: 10, step: 1, placeholder: "Nota (0-10)", value: gradeValue ?? "", onChange: (e) => { const val = e.target.value; const parsed = Number(val); setGradeValue(val === "" || Number.isNaN(parsed) ? null : parsed); } } ) } ), /* @__PURE__ */ jsx( Modal_default, { isOpen: !!pendingDelete, onClose: () => setPendingDelete(null), title: "Deseja deletar post?", size: "sm", footer: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [ /* @__PURE__ */ jsx( Button_default, { variant: "outline", action: "secondary", size: "medium", onClick: () => setPendingDelete(null), children: "Cancelar" } ), /* @__PURE__ */ jsx( Button_default, { variant: "solid", action: "negative", size: "medium", disabled: isSubmitting, onClick: handleConfirmDelete, children: "Deletar" } ) ] }), children: /* @__PURE__ */ jsx(Text_default, { size: "md", color: "text-text-600", children: "Essa a\xE7\xE3o \xE9 permanente e n\xE3o poder\xE1 ser desfeita." }) } ) ] }); } var Forum_default = Forum; export { Forum, Forum_default }; //# sourceMappingURL=chunk-3EEYRIZY.mjs.map