@iclips/ui 2.0.2 → 3.0.0
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.
- package/MIGRATION-v3.md +244 -0
- package/README.md +1 -1
- package/dist/alert-theme.css +20 -79
- package/dist/components/ui/charts/donut-chart.cjs +1 -1
- package/dist/components/ui/charts/donut-chart.cjs.map +1 -1
- package/dist/components/ui/charts/donut-chart.js +39 -60
- package/dist/components/ui/charts/donut-chart.js.map +1 -1
- package/dist/components/ui/charts/kpi-card.cjs +1 -1
- package/dist/components/ui/charts/kpi-card.cjs.map +1 -1
- package/dist/components/ui/charts/kpi-card.js +19 -19
- package/dist/components/ui/charts/kpi-card.js.map +1 -1
- package/dist/components/ui/data/comment-system.cjs +1 -1
- package/dist/components/ui/data/comment-system.cjs.map +1 -1
- package/dist/components/ui/data/comment-system.js +67 -67
- package/dist/components/ui/data/comment-system.js.map +1 -1
- package/dist/components/ui/data/data-table.cjs +1 -1
- package/dist/components/ui/data/data-table.cjs.map +1 -1
- package/dist/components/ui/data/data-table.js +112 -101
- package/dist/components/ui/data/data-table.js.map +1 -1
- package/dist/components/ui/data/editorial-calendar.cjs +1 -1
- package/dist/components/ui/data/editorial-calendar.cjs.map +1 -1
- package/dist/components/ui/data/editorial-calendar.js +291 -291
- package/dist/components/ui/data/editorial-calendar.js.map +1 -1
- package/dist/components/ui/data/filter-builder.cjs +1 -1
- package/dist/components/ui/data/filter-builder.cjs.map +1 -1
- package/dist/components/ui/data/filter-builder.js +1 -1
- package/dist/components/ui/data/filter-builder.js.map +1 -1
- package/dist/components/ui/feedback/empty-state.cjs +1 -1
- package/dist/components/ui/feedback/empty-state.cjs.map +1 -1
- package/dist/components/ui/feedback/empty-state.js +14 -14
- package/dist/components/ui/feedback/empty-state.js.map +1 -1
- package/dist/components/ui/feedback/toast.cjs +1 -1
- package/dist/components/ui/feedback/toast.cjs.map +1 -1
- package/dist/components/ui/feedback/toast.js +53 -22
- package/dist/components/ui/feedback/toast.js.map +1 -1
- package/dist/components/ui/forms/calendar.cjs +1 -1
- package/dist/components/ui/forms/calendar.cjs.map +1 -1
- package/dist/components/ui/forms/calendar.js +16 -16
- package/dist/components/ui/forms/calendar.js.map +1 -1
- package/dist/components/ui/forms/combobox.cjs +1 -1
- package/dist/components/ui/forms/combobox.cjs.map +1 -1
- package/dist/components/ui/forms/combobox.js +78 -76
- package/dist/components/ui/forms/combobox.js.map +1 -1
- package/dist/components/ui/forms/file-attachment-list.cjs +1 -1
- package/dist/components/ui/forms/file-attachment-list.cjs.map +1 -1
- package/dist/components/ui/forms/file-attachment-list.js +4 -4
- package/dist/components/ui/forms/file-attachment-list.js.map +1 -1
- package/dist/components/ui/forms/file-upload-zone.cjs +2 -2
- package/dist/components/ui/forms/file-upload-zone.cjs.map +1 -1
- package/dist/components/ui/forms/file-upload-zone.js +55 -49
- package/dist/components/ui/forms/file-upload-zone.js.map +1 -1
- package/dist/components/ui/forms/form.cjs +1 -1
- package/dist/components/ui/forms/form.cjs.map +1 -1
- package/dist/components/ui/forms/form.js +11 -11
- package/dist/components/ui/forms/form.js.map +1 -1
- package/dist/components/ui/forms/input-validation.cjs +1 -1
- package/dist/components/ui/forms/input-validation.cjs.map +1 -1
- package/dist/components/ui/forms/input-validation.js +20 -20
- package/dist/components/ui/forms/input-validation.js.map +1 -1
- package/dist/components/ui/forms/multi-select.cjs +1 -1
- package/dist/components/ui/forms/multi-select.cjs.map +1 -1
- package/dist/components/ui/forms/multi-select.js +69 -67
- package/dist/components/ui/forms/multi-select.js.map +1 -1
- package/dist/components/ui/forms/radio-group.cjs +1 -1
- package/dist/components/ui/forms/radio-group.cjs.map +1 -1
- package/dist/components/ui/forms/radio-group.js +19 -19
- package/dist/components/ui/forms/radio-group.js.map +1 -1
- package/dist/components/ui/forms/social-button.cjs +1 -1
- package/dist/components/ui/forms/social-button.cjs.map +1 -1
- package/dist/components/ui/forms/social-button.js +6 -6
- package/dist/components/ui/forms/social-button.js.map +1 -1
- package/dist/components/ui/forms/toggle.cjs +1 -1
- package/dist/components/ui/forms/toggle.cjs.map +1 -1
- package/dist/components/ui/forms/toggle.js +7 -7
- package/dist/components/ui/forms/toggle.js.map +1 -1
- package/dist/components/ui/navigation/navigation-menu.cjs +1 -1
- package/dist/components/ui/navigation/navigation-menu.cjs.map +1 -1
- package/dist/components/ui/navigation/navigation-menu.js +14 -14
- package/dist/components/ui/navigation/navigation-menu.js.map +1 -1
- package/dist/components/ui/navigation/sidebar.cjs +1 -1
- package/dist/components/ui/navigation/sidebar.cjs.map +1 -1
- package/dist/components/ui/navigation/sidebar.js +44 -44
- package/dist/components/ui/navigation/sidebar.js.map +1 -1
- package/dist/components/ui/overlays/context-menu.cjs +1 -1
- package/dist/components/ui/overlays/context-menu.cjs.map +1 -1
- package/dist/components/ui/overlays/context-menu.js +1 -1
- package/dist/components/ui/overlays/context-menu.js.map +1 -1
- package/dist/components/ui/overlays/dropdown-menu.cjs +1 -1
- package/dist/components/ui/overlays/dropdown-menu.cjs.map +1 -1
- package/dist/components/ui/overlays/dropdown-menu.js +5 -5
- package/dist/components/ui/overlays/dropdown-menu.js.map +1 -1
- package/dist/components/ui/overlays/menubar.cjs +1 -1
- package/dist/components/ui/overlays/menubar.cjs.map +1 -1
- package/dist/components/ui/overlays/menubar.js +29 -29
- package/dist/components/ui/overlays/menubar.js.map +1 -1
- package/dist/components/ui/overlays/tooltip.cjs +1 -1
- package/dist/components/ui/overlays/tooltip.cjs.map +1 -1
- package/dist/components/ui/overlays/tooltip.js +12 -12
- package/dist/components/ui/overlays/tooltip.js.map +1 -1
- package/dist/components/ui/primitives/avatar.cjs +1 -1
- package/dist/components/ui/primitives/avatar.cjs.map +1 -1
- package/dist/components/ui/primitives/avatar.js +20 -27
- package/dist/components/ui/primitives/avatar.js.map +1 -1
- package/dist/components/ui/primitives/badge.cjs +1 -1
- package/dist/components/ui/primitives/badge.cjs.map +1 -1
- package/dist/components/ui/primitives/badge.js +13 -13
- package/dist/components/ui/primitives/badge.js.map +1 -1
- package/dist/components/ui/primitives/button.cjs +1 -1
- package/dist/components/ui/primitives/button.cjs.map +1 -1
- package/dist/components/ui/primitives/button.js +11 -8
- package/dist/components/ui/primitives/button.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +34 -35
- package/dist/index.js.map +1 -1
- package/dist/preset.css +1 -2
- package/dist/toast-theme.css +100 -64
- package/dist/tokens.css +59 -159
- package/package.json +5 -3
- package/scripts/check-colors.mjs +208 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comment-system.js","sources":["../../../../src/components/ui/data/comment-system.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { format } from \"date-fns\";\nimport { ptBR } from \"date-fns/locale\";\nimport { cn } from \"../utils\";\nimport { Avatar, AvatarFallback, AvatarImage } from \"../primitives/avatar\";\nimport { Button } from \"../primitives/button\";\nimport { Badge } from \"../primitives/badge\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../overlays/tooltip\";\nimport { Separator } from \"../primitives/separator\";\nimport { \n Bold, \n Italic, \n Underline as UnderlineIcon, \n List, \n ListOrdered, \n Link as LinkIcon,\n Send,\n Paperclip,\n AlertCircle,\n MoreHorizontal,\n Trash2,\n Type,\n X,\n Smile,\n Plus\n} from \"lucide-react\";\n\n// Tiptap Imports\nimport { useEditor, EditorContent, Editor, ReactRenderer } from '@tiptap/react';\nimport type { Instance as TippyInstance } from 'tippy.js';\nimport StarterKit from '@tiptap/starter-kit';\nimport Underline from '@tiptap/extension-underline';\nimport Link from '@tiptap/extension-link';\nimport TiptapImage from '@tiptap/extension-image';\nimport Mention from '@tiptap/extension-mention';\nimport tippy from 'tippy.js';\nimport { MentionList } from './mention-list';\nimport Picker from 'emoji-picker-react';\nimport { Popover, PopoverContent, PopoverTrigger } from \"../overlays/popover\";\n\n// ==========================================\n// TIPOS\n// ==========================================\n\nexport type UserRole = 'internal' | 'client' | 'freelancer';\n\nexport interface CommentUser {\n id: string;\n name: string;\n avatar?: string;\n role: UserRole;\n}\n\nexport interface CommentReaction {\n emoji: string;\n users: string[]; // Array de IDs de usuários que reagiram\n}\n\nexport interface CommentAttachment {\n id: string;\n url: string;\n name: string;\n type: 'image' | 'file';\n}\n\nexport interface Comment {\n id: string;\n content: string; // Conteúdo HTML\n user: CommentUser;\n createdAt: Date;\n isRevisionRequest?: boolean;\n attachments?: CommentAttachment[];\n reactions?: CommentReaction[];\n}\n\nexport interface CommentSystemProps {\n comments: Comment[];\n currentUser: CommentUser;\n users?: CommentUser[]; // Lista de usuários mencionáveis\n onAddComment: (comment: Omit<Comment, \"id\" | \"createdAt\">) => void;\n onDeleteComment?: (id: string) => void;\n onReact?: (commentId: string, emoji: string) => void;\n className?: string;\n}\n\n// ==========================================\n// COMPONENTES AUXILIARES\n// ==========================================\n\nconst RoleBadge = ({ role }: { role: UserRole }) => {\n const config = {\n internal: { label: \"Equipe iClips\", className: \"bg-primary/10 text-primary hover:bg-primary/20 border-primary/20\" },\n client: { label: \"Cliente\", className: \"bg-info/10 text-info-emphasis hover:bg-info/20 border-info/20\" },\n freelancer: { label: \"Freelancer\", className: \"bg-warning/10 text-warning-emphasis hover:bg-warning/20 border-warning/20\" },\n };\n\n const { label, className } = config[role];\n\n return (\n <Badge variant=\"outline\" className={cn(\"text-[10px] h-5 px-1.5 font-medium border-0\", className)}>\n {label}\n </Badge>\n );\n};\n\n// ==========================================\n// EDITOR TOOLBAR\n// ==========================================\n\nconst EditorToolbar = ({ editor, visible }: { editor: Editor | null, visible: boolean }) => {\n if (!editor) return null;\n\n if (!visible) return null;\n\n return (\n <div className=\"flex items-center gap-1 border-b p-1 bg-muted/20 animate-in slide-in-from-bottom-2 duration-200\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('bold') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().toggleBold().run()}\n title=\"Negrito (Ctrl+B)\"\n aria-label=\"Negrito\"\n >\n <Bold className=\"h-3.5 w-3.5\" />\n </Button>\n \n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('italic') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().toggleItalic().run()}\n title=\"Itálico (Ctrl+I)\"\n aria-label=\"Itálico\"\n >\n <Italic className=\"h-3.5 w-3.5\" />\n </Button>\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('underline') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().toggleUnderline().run()}\n title=\"Sublinhado (Ctrl+U)\"\n aria-label=\"Sublinhado\"\n >\n <UnderlineIcon className=\"h-3.5 w-3.5\" />\n </Button>\n\n <Separator orientation=\"vertical\" className=\"h-4 mx-1\" />\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('bulletList') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().toggleBulletList().run()}\n aria-label=\"Lista com marcadores\"\n >\n <List className=\"h-3.5 w-3.5\" />\n </Button>\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('orderedList') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().toggleOrderedList().run()}\n aria-label=\"Lista numerada\"\n >\n <ListOrdered className=\"h-3.5 w-3.5\" />\n </Button>\n\n <Separator orientation=\"vertical\" className=\"h-4 mx-1\" />\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('link') && \"bg-muted text-primary\")}\n aria-label=\"Inserir link\"\n onClick={() => {\n const previousUrl = editor.getAttributes('link').href;\n const url = window.prompt('URL', previousUrl);\n if (url === null) return;\n if (url === '') {\n editor.chain().focus().extendMarkRange('link').unsetLink().run();\n return;\n }\n editor.chain().focus().extendMarkRange('link').setLink({ href: url }).run();\n }}\n >\n <LinkIcon className=\"h-3.5 w-3.5\" />\n </Button>\n </div>\n );\n};\n\n// ==========================================\n// COMMENT EDITOR AREA\n// ==========================================\n\nconst CommentEditor = ({ \n currentUser, \n onSubmit,\n users = []\n}: { \n currentUser: CommentUser;\n onSubmit: (data: { content: string; isRevisionRequest: boolean; attachments: CommentAttachment[] }) => void;\n users?: CommentUser[];\n}) => {\n const [isRevision, setIsRevision] = React.useState(false);\n const [showToolbar, setShowToolbar] = React.useState(false);\n const [attachments, setAttachments] = React.useState<CommentAttachment[]>([]);\n const [isEditorEmpty, setIsEditorEmpty] = React.useState(true);\n const fileInputRef = React.useRef<HTMLInputElement>(null);\n\n const extensions = React.useMemo(() => [\n StarterKit.configure({\n // @ts-ignore\n link: false,\n // @ts-ignore\n underline: false,\n }),\n Underline,\n Link.configure({\n openOnClick: false,\n }),\n TiptapImage,\n Mention.configure({\n HTMLAttributes: {\n class: 'bg-accent text-accent-foreground rounded-sm px-1 py-0.5 font-medium decoration-clone',\n },\n suggestion: {\n items: ({ query }: { query: string }) => {\n return users\n .filter(item => item.name.toLowerCase().startsWith(query.toLowerCase()))\n .slice(0, 5);\n },\n render: () => {\n // Formato mínimo dos props do ciclo de vida do suggestion do tiptap\n // (o tipo completo `SuggestionProps` vive em `@tiptap/suggestion`, dep\n // transitiva sem entrada direta no package.json).\n type MentionRenderProps = {\n editor: Editor;\n clientRect?: (() => DOMRect | null) | null;\n event?: KeyboardEvent;\n };\n let component: ReactRenderer | null = null;\n let popup: TippyInstance[] | null = null;\n\n return {\n onStart: (props: MentionRenderProps) => {\n component = new ReactRenderer(MentionList, {\n props,\n editor: props.editor,\n });\n\n if (!props.clientRect) {\n return;\n }\n\n popup = tippy('body', {\n // tiptap tipa como `() => DOMRect | null`; tippy exige não-nulo.\n getReferenceClientRect: props.clientRect as () => DOMRect,\n appendTo: () => document.body,\n content: component.element,\n showOnCreate: true,\n interactive: true,\n trigger: 'manual',\n placement: 'bottom-start',\n });\n },\n onUpdate(props: MentionRenderProps) {\n component?.updateProps(props);\n\n if (!props.clientRect) {\n return;\n }\n\n popup?.[0].setProps({\n getReferenceClientRect: props.clientRect as () => DOMRect,\n });\n },\n onKeyDown(props: { event: KeyboardEvent }) {\n if (props.event.key === 'Escape') {\n popup?.[0].hide();\n\n return true;\n }\n\n return Boolean(\n (component?.ref as { onKeyDown?: (p: { event: KeyboardEvent }) => boolean } | undefined)?.onKeyDown?.(props),\n );\n },\n onExit() {\n popup?.[0].destroy();\n component?.destroy();\n },\n };\n },\n },\n }),\n ], [users]);\n\n const editor = useEditor({\n extensions,\n content: '',\n onUpdate: ({ editor }) => {\n setIsEditorEmpty(editor.isEmpty);\n },\n editorProps: {\n attributes: {\n class: 'prose prose-sm dark:prose-invert max-w-none focus:outline-none min-h-[80px] px-3 py-2 text-sm',\n },\n },\n });\n\n const handleAttach = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (e.target.files && e.target.files[0]) {\n const file = e.target.files[0];\n const url = URL.createObjectURL(file);\n \n const newAttachment: CommentAttachment = {\n id: Math.random().toString(36).substr(2, 9),\n name: file.name,\n url,\n type: file.type.startsWith('image/') ? 'image' : 'file'\n };\n \n setAttachments([...attachments, newAttachment]);\n // Reset input\n e.target.value = '';\n }\n };\n\n const removeAttachment = (id: string) => {\n setAttachments(attachments.filter(a => a.id !== id));\n };\n\n const handleSubmit = () => {\n if (!editor || (editor.isEmpty && attachments.length === 0)) return;\n \n onSubmit({\n content: editor.getHTML(),\n isRevisionRequest: isRevision,\n attachments\n });\n\n editor.commands.clearContent();\n setAttachments([]);\n setIsRevision(false);\n // Manually reset empty state since clearContent triggers update but we want to be sure\n setIsEditorEmpty(true);\n };\n\n return (\n <div className=\"flex gap-3 items-start\">\n <Avatar className=\"h-8 w-8 mt-1 border\">\n <AvatarImage src={currentUser.avatar} />\n <AvatarFallback>{currentUser.name.substring(0, 2).toUpperCase()}</AvatarFallback>\n </Avatar>\n\n <div className={cn(\n \"flex-1 rounded-xl border bg-background shadow-sm overflow-hidden transition-colors\",\n isRevision && \"border-destructive/40 ring-1 ring-destructive/20\"\n )}>\n <EditorToolbar editor={editor} visible={showToolbar} />\n \n <EditorContent editor={editor} />\n\n {/* Attachments Preview Area */}\n {attachments.length > 0 && (\n <div className=\"px-3 pb-2 flex flex-wrap gap-2\">\n {attachments.map(att => (\n <div key={att.id} className=\"relative group\">\n {att.type === 'image' ? (\n <div className=\"h-16 w-16 rounded-md border overflow-hidden relative\">\n <img src={att.url} alt={att.name} className=\"h-full w-full object-cover\" />\n </div>\n ) : (\n <div className=\"h-16 w-16 rounded-md border bg-muted flex items-center justify-center\">\n <Paperclip className=\"h-6 w-6 text-muted-foreground\" />\n </div>\n )}\n <button \n onClick={() => removeAttachment(att.id)}\n className=\"absolute -top-1.5 -right-1.5 bg-destructive text-destructive-foreground rounded-full p-0.5 opacity-0 group-hover:opacity-100 transition-opacity shadow-sm\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n </div>\n ))}\n </div>\n )}\n\n <div className=\"flex items-center justify-between p-2 bg-muted/10 border-t\">\n <div className=\"flex items-center gap-2\">\n <Tooltip>\n <TooltipTrigger asChild>\n <Button \n variant=\"ghost\" \n size=\"icon\" \n className={cn(\n \"h-8 w-8 transition-colors\",\n showToolbar ? \"bg-muted text-foreground\" : \"text-muted-foreground hover:text-foreground\"\n )}\n onClick={() => setShowToolbar(!showToolbar)}\n aria-label=\"Opções de formatação\"\n >\n <Type className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Opções de formatação</TooltipContent>\n </Tooltip>\n\n <div className=\"w-px h-4 bg-border mx-1\" />\n\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-muted-foreground hover:text-foreground\"\n aria-label=\"Inserir emoji\"\n >\n <Smile className=\"h-4 w-4\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0 border-none\" align=\"start\" side=\"top\">\n <Picker \n onEmojiClick={(emojiData) => editor?.chain().focus().insertContent(emojiData.emoji).run()}\n width={300}\n height={350}\n />\n </PopoverContent>\n </Popover>\n\n <input \n type=\"file\" \n className=\"hidden\" \n ref={fileInputRef}\n onChange={handleAttach}\n accept=\"image/*,.pdf,.doc,.docx\"\n />\n <Tooltip>\n <TooltipTrigger asChild>\n <Button \n variant=\"ghost\" \n size=\"icon\" \n className=\"h-8 w-8 text-muted-foreground hover:text-foreground\"\n onClick={() => fileInputRef.current?.click()}\n aria-label=\"Anexar arquivo\"\n >\n <Paperclip className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Anexar arquivo</TooltipContent>\n </Tooltip>\n\n <Tooltip>\n <TooltipTrigger asChild>\n <Button \n variant=\"ghost\" \n size=\"sm\" \n className={cn(\n \"h-8 gap-2 px-2 transition-colors\",\n isRevision\n ? \"bg-destructive/10 text-destructive-emphasis hover:bg-destructive/20\"\n : \"text-muted-foreground hover:text-foreground\"\n )}\n onClick={() => setIsRevision(!isRevision)}\n >\n <AlertCircle className=\"h-4 w-4\" />\n <span className=\"text-xs font-medium\">Solicitar Refação</span>\n </Button>\n </TooltipTrigger>\n <TooltipContent>Marca este comentário como um pedido de alteração</TooltipContent>\n </Tooltip>\n </div>\n\n <Button\n size=\"sm\"\n onClick={handleSubmit}\n disabled={isEditorEmpty && attachments.length === 0}\n >\n Enviar <Send className=\"h-3.5 w-3.5 ml-2\" />\n </Button>\n </div>\n </div>\n </div>\n );\n};\n\n// ==========================================\n// SINGLE COMMENT ITEM\n// ==========================================\n\nconst CommentItem = ({ \n comment, \n currentUserId,\n onDelete, \n onReact \n}: { \n comment: Comment; \n currentUserId: string;\n onDelete?: (id: string) => void;\n onReact?: (commentId: string, emoji: string) => void;\n}) => {\n const isRevision = comment.isRevisionRequest;\n\n return (\n <div className={cn(\n \"group flex gap-3 p-4 rounded-lg transition-colors\",\n isRevision ? \"bg-destructive/5 border border-destructive/20\" : \"hover:bg-muted/20\"\n )}>\n <Avatar className=\"h-8 w-8 mt-0.5 border\">\n <AvatarImage src={comment.user.avatar} />\n <AvatarFallback>{comment.user.name.substring(0, 2).toUpperCase()}</AvatarFallback>\n </Avatar>\n\n <div className=\"flex-1 min-w-0\">\n {/* Header */}\n <div className=\"flex items-center justify-between mb-1.5\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <span className=\"font-semibold text-sm text-foreground\">{comment.user.name}</span>\n <RoleBadge role={comment.user.role} />\n <span className=\"text-xs text-foreground/65\">\n {format(comment.createdAt, \"dd MMM 'às' HH:mm\", { locale: ptBR })}\n </span>\n </div>\n \n <div className=\"flex items-center gap-2 opacity-0 group-hover:opacity-100 transition-opacity\">\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6 text-muted-foreground hover:text-foreground\"\n aria-label=\"Reagir com emoji\"\n >\n <Smile className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0 border-none\" align=\"end\">\n <Picker \n onEmojiClick={(emojiData) => onReact?.(comment.id, emojiData.emoji)}\n width={300}\n height={350}\n />\n </PopoverContent>\n </Popover>\n\n {onDelete && (\n <Button \n variant=\"ghost\" \n size=\"icon\" \n className=\"h-6 w-6 text-muted-foreground hover:text-destructive\"\n onClick={() => onDelete(comment.id)}\n aria-label=\"Excluir comentário\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n </Button>\n )}\n </div>\n </div>\n\n {/* Revision Badge */}\n {isRevision && (\n <div className=\"inline-flex items-center gap-1.5 px-2 py-1 rounded-md bg-destructive/10 text-destructive-emphasis text-xs font-medium mb-2\">\n <AlertCircle className=\"h-3.5 w-3.5\" />\n Solicitação de Refação\n </div>\n )}\n\n {/* Content */}\n <div \n className=\"prose prose-sm dark:prose-invert max-w-none text-sm text-foreground/90 leading-relaxed break-words [&_p]:mb-2 [&_p:last-child]:mb-0\"\n dangerouslySetInnerHTML={{ __html: comment.content }}\n />\n\n {/* Attachments Display */}\n {comment.attachments && comment.attachments.length > 0 && (\n <div className=\"mt-3 flex flex-wrap gap-2\">\n {comment.attachments.map(att => (\n <div \n key={att.id} \n className=\"group/att relative rounded-lg border overflow-hidden bg-background hover:shadow-sm transition-all cursor-pointer\"\n onClick={() => window.open(att.url, '_blank')}\n >\n {att.type === 'image' ? (\n <div className=\"h-32 aspect-[4/3]\">\n <img src={att.url} alt={att.name} className=\"h-full w-full object-cover\" />\n <div className=\"absolute inset-0 bg-foreground/0 group-hover/att:bg-foreground/10 transition-colors\" />\n </div>\n ) : (\n <div className=\"h-12 px-3 flex items-center gap-2 bg-muted/30\">\n <Paperclip className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"text-xs font-medium truncate max-w-[150px]\">{att.name}</span>\n </div>\n )}\n </div>\n ))}\n </div>\n )}\n\n {/* Reactions */}\n <div className=\"mt-3 flex flex-wrap gap-2 items-center\">\n {comment.reactions?.map((reaction) => (\n <button\n key={reaction.emoji}\n onClick={() => onReact?.(comment.id, reaction.emoji)}\n className={cn(\n \"inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full text-xs font-medium border transition-colors\",\n reaction.users.includes(currentUserId)\n ? \"bg-accent border-accent text-accent-foreground\"\n : \"bg-muted/30 border-transparent hover:bg-muted/50 text-muted-foreground\"\n )}\n >\n <span>{reaction.emoji}</span>\n <span>{reaction.users.length}</span>\n </button>\n ))}\n \n {onReact && (\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6 rounded-full text-muted-foreground hover:text-foreground hover:bg-muted/50\"\n aria-label=\"Adicionar reação\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0 border-none\" align=\"start\">\n <Picker \n onEmojiClick={(emojiData) => onReact(comment.id, emojiData.emoji)}\n width={300}\n height={350}\n />\n </PopoverContent>\n </Popover>\n )}\n </div>\n </div>\n </div>\n );\n};\n\n// ==========================================\n// MAIN COMPONENT\n// ==========================================\n\nexport const CommentSystem = ({ \n comments, \n currentUser, \n users = [],\n onAddComment, \n onDeleteComment,\n onReact,\n className \n}: CommentSystemProps) => {\n \n const handleSubmit = (data: { content: string; isRevisionRequest: boolean; attachments: CommentAttachment[] }) => {\n onAddComment({\n content: data.content,\n user: currentUser,\n isRevisionRequest: data.isRevisionRequest,\n attachments: data.attachments\n });\n };\n\n return (\n <div className={cn(\"flex flex-col h-full\", className)}>\n {/* Header */}\n <div className=\"px-4 py-3 border-b flex items-center justify-between bg-card\">\n <h3 className=\"font-semibold text-base\">Comentários da Atividade</h3>\n <Badge variant=\"secondary\" className=\"bg-muted text-muted-foreground hover:bg-muted\">\n {comments.length}\n </Badge>\n </div>\n\n {/* Scrollable List */}\n <div className=\"flex-1 overflow-y-auto p-4 space-y-2 bg-muted/5\">\n {comments.length === 0 ? (\n <div className=\"h-full flex flex-col items-center justify-center text-muted-foreground min-h-[200px]\">\n <div className=\"bg-muted rounded-full p-3 mb-3\">\n <MoreHorizontal className=\"h-6 w-6\" aria-hidden=\"true\" />\n </div>\n <p className=\"text-sm font-medium text-foreground/70\">Nenhum comentário ainda</p>\n <p className=\"text-xs\">Inicie a conversa sobre esta tarefa</p>\n </div>\n ) : (\n comments.map((comment) => (\n <CommentItem \n key={comment.id} \n comment={comment} \n currentUserId={currentUser.id}\n onDelete={onDeleteComment} \n onReact={onReact}\n />\n ))\n )}\n </div>\n\n {/* Input Area */}\n <div className=\"p-4 border-t bg-card\">\n <CommentEditor \n currentUser={currentUser} \n onSubmit={handleSubmit}\n users={users}\n />\n </div>\n </div>\n );\n};\n\nexport default CommentSystem;"],"names":["RoleBadge","role","config","label","className","jsx","Badge","cn","EditorToolbar","editor","visible","jsxs","Button","Bold","Italic","UnderlineIcon","Separator","List","ListOrdered","previousUrl","url","LinkIcon","CommentEditor","currentUser","onSubmit","users","isRevision","setIsRevision","React","showToolbar","setShowToolbar","attachments","setAttachments","isEditorEmpty","setIsEditorEmpty","fileInputRef","extensions","StarterKit","Underline","Link","TiptapImage","Mention","query","item","component","popup","props","ReactRenderer","MentionList","tippy","_b","_a","useEditor","handleAttach","e","file","newAttachment","removeAttachment","id","a","handleSubmit","Avatar","AvatarImage","AvatarFallback","EditorContent","att","Paperclip","Tooltip","TooltipTrigger","Type","TooltipContent","Popover","PopoverTrigger","Smile","PopoverContent","Picker","emojiData","AlertCircle","Send","CommentItem","comment","currentUserId","onDelete","onReact","format","ptBR","Trash2","reaction","Plus","CommentSystem","comments","onAddComment","onDeleteComment","data","MoreHorizontal"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAyFA,MAAMA,KAAY,CAAC,EAAE,MAAAC,QAA+B;AAClD,QAAMC,IAAS;AAAA,IACb,UAAU,EAAE,OAAO,iBAAiB,WAAW,mEAAA;AAAA,IAC/C,QAAQ,EAAE,OAAO,WAAW,WAAW,gEAAA;AAAA,IACvC,YAAY,EAAE,OAAO,cAAc,WAAW,4EAAA;AAAA,EAA4E,GAGtH,EAAE,OAAAC,GAAO,WAAAC,MAAcF,EAAOD,CAAI;AAExC,SACE,gBAAAI,EAACC,KAAM,SAAQ,WAAU,WAAWC,EAAG,+CAA+CH,CAAS,GAC5F,UAAAD,EAAA,CACH;AAEJ,GAMMK,KAAgB,CAAC,EAAE,QAAAC,GAAQ,SAAAC,QAC3B,CAACD,KAED,CAACC,IAAgB,OAGnB,gBAAAC,EAAC,OAAA,EAAI,WAAU,mGACb,UAAA;AAAA,EAAA,gBAAAN;AAAA,IAACO;AAAA,IAAA;AAAA,MACC,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,WAAWL,EAAG,WAAWE,EAAO,SAAS,MAAM,KAAK,uBAAuB;AAAA,MAC3E,SAAS,MAAMA,EAAO,MAAA,EAAQ,QAAQ,WAAA,EAAa,IAAA;AAAA,MACnD,OAAM;AAAA,MACN,cAAW;AAAA,MAEX,UAAA,gBAAAJ,EAACQ,GAAA,EAAK,WAAU,cAAA,CAAc;AAAA,IAAA;AAAA,EAAA;AAAA,EAGhC,gBAAAR;AAAA,IAACO;AAAA,IAAA;AAAA,MACC,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,WAAWL,EAAG,WAAWE,EAAO,SAAS,QAAQ,KAAK,uBAAuB;AAAA,MAC7E,SAAS,MAAMA,EAAO,MAAA,EAAQ,QAAQ,aAAA,EAAe,IAAA;AAAA,MACrD,OAAM;AAAA,MACN,cAAW;AAAA,MAEX,UAAA,gBAAAJ,EAACS,GAAA,EAAO,WAAU,cAAA,CAAc;AAAA,IAAA;AAAA,EAAA;AAAA,EAGlC,gBAAAT;AAAA,IAACO;AAAA,IAAA;AAAA,MACC,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,WAAWL,EAAG,WAAWE,EAAO,SAAS,WAAW,KAAK,uBAAuB;AAAA,MAChF,SAAS,MAAMA,EAAO,MAAA,EAAQ,QAAQ,gBAAA,EAAkB,IAAA;AAAA,MACxD,OAAM;AAAA,MACN,cAAW;AAAA,MAEX,UAAA,gBAAAJ,EAACU,GAAA,EAAc,WAAU,cAAA,CAAc;AAAA,IAAA;AAAA,EAAA;AAAA,EAGzC,gBAAAV,EAACW,GAAA,EAAU,aAAY,YAAW,WAAU,YAAW;AAAA,EAEvD,gBAAAX;AAAA,IAACO;AAAA,IAAA;AAAA,MACC,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,WAAWL,EAAG,WAAWE,EAAO,SAAS,YAAY,KAAK,uBAAuB;AAAA,MACjF,SAAS,MAAMA,EAAO,MAAA,EAAQ,QAAQ,iBAAA,EAAmB,IAAA;AAAA,MACzD,cAAW;AAAA,MAEX,UAAA,gBAAAJ,EAACY,GAAA,EAAK,WAAU,cAAA,CAAc;AAAA,IAAA;AAAA,EAAA;AAAA,EAGhC,gBAAAZ;AAAA,IAACO;AAAA,IAAA;AAAA,MACC,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,WAAWL,EAAG,WAAWE,EAAO,SAAS,aAAa,KAAK,uBAAuB;AAAA,MAClF,SAAS,MAAMA,EAAO,MAAA,EAAQ,QAAQ,kBAAA,EAAoB,IAAA;AAAA,MAC1D,cAAW;AAAA,MAEX,UAAA,gBAAAJ,EAACa,IAAA,EAAY,WAAU,cAAA,CAAc;AAAA,IAAA;AAAA,EAAA;AAAA,EAGvC,gBAAAb,EAACW,GAAA,EAAU,aAAY,YAAW,WAAU,YAAW;AAAA,EAEvD,gBAAAX;AAAA,IAACO;AAAA,IAAA;AAAA,MACC,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,WAAWL,EAAG,WAAWE,EAAO,SAAS,MAAM,KAAK,uBAAuB;AAAA,MAC3E,cAAW;AAAA,MACX,SAAS,MAAM;AACb,cAAMU,IAAcV,EAAO,cAAc,MAAM,EAAE,MAC3CW,IAAM,OAAO,OAAO,OAAOD,CAAW;AAC5C,YAAIC,MAAQ,MACZ;AAAA,cAAIA,MAAQ,IAAI;AACd,YAAAX,EAAO,MAAA,EAAQ,MAAA,EAAQ,gBAAgB,MAAM,EAAE,UAAA,EAAY,IAAA;AAC3D;AAAA,UACF;AACA,UAAAA,EAAO,MAAA,EAAQ,MAAA,EAAQ,gBAAgB,MAAM,EAAE,QAAQ,EAAE,MAAMW,EAAA,CAAK,EAAE,IAAA;AAAA;AAAA,MACxE;AAAA,MAEA,UAAA,gBAAAf,EAACgB,IAAA,EAAS,WAAU,cAAA,CAAc;AAAA,IAAA;AAAA,EAAA;AACpC,GACF,GAQEC,KAAgB,CAAC;AAAA,EACrB,aAAAC;AAAA,EACA,UAAAC;AAAA,EACA,OAAAC,IAAQ,CAAA;AACV,MAIM;AACJ,QAAM,CAACC,GAAYC,CAAa,IAAIC,EAAM,SAAS,EAAK,GAClD,CAACC,GAAaC,CAAc,IAAIF,EAAM,SAAS,EAAK,GACpD,CAACG,GAAaC,CAAc,IAAIJ,EAAM,SAA8B,CAAA,CAAE,GACtE,CAACK,GAAeC,CAAgB,IAAIN,EAAM,SAAS,EAAI,GACvDO,IAAeP,EAAM,OAAyB,IAAI,GAElDQ,IAAaR,EAAM,QAAQ,MAAM;AAAA,IACrCS,GAAW,UAAU;AAAA;AAAA,MAEnB,MAAM;AAAA;AAAA,MAEN,WAAW;AAAA,IAAA,CACZ;AAAA,IACDC;AAAA,IACAC,GAAK,UAAU;AAAA,MACb,aAAa;AAAA,IAAA,CACd;AAAA,IACDC;AAAA,IACAC,GAAQ,UAAU;AAAA,MAChB,gBAAgB;AAAA,QACd,OAAO;AAAA,MAAA;AAAA,MAET,YAAY;AAAA,QACV,OAAO,CAAC,EAAE,OAAAC,QACDjB,EACJ,OAAO,CAAAkB,MAAQA,EAAK,KAAK,YAAA,EAAc,WAAWD,EAAM,aAAa,CAAC,EACtE,MAAM,GAAG,CAAC;AAAA,QAEf,QAAQ,MAAM;AASZ,cAAIE,IAAkC,MAClCC,IAAgC;AAEpC,iBAAO;AAAA,YACL,SAAS,CAACC,MAA8B;AAMtC,cALAF,IAAY,IAAIG,GAAcC,IAAa;AAAA,gBACzC,OAAAF;AAAA,gBACA,QAAQA,EAAM;AAAA,cAAA,CACf,GAEIA,EAAM,eAIXD,IAAQI,GAAM,QAAQ;AAAA;AAAA,gBAEpB,wBAAwBH,EAAM;AAAA,gBAC9B,UAAU,MAAM,SAAS;AAAA,gBACzB,SAASF,EAAU;AAAA,gBACnB,cAAc;AAAA,gBACd,aAAa;AAAA,gBACb,SAAS;AAAA,gBACT,WAAW;AAAA,cAAA,CACZ;AAAA,YACH;AAAA,YACA,SAASE,GAA2B;AAGlC,cAFAF,KAAA,QAAAA,EAAW,YAAYE,IAElBA,EAAM,eAIXD,KAAA,QAAAA,EAAQ,GAAG,SAAS;AAAA,gBAClB,wBAAwBC,EAAM;AAAA,cAAA;AAAA,YAElC;AAAA,YACA,UAAUA,GAAiC;;AACzC,qBAAIA,EAAM,MAAM,QAAQ,YACtBD,KAAA,QAAAA,EAAQ,GAAG,QAEJ,MAGF,IACJK,KAAAC,IAAAP,KAAA,gBAAAA,EAAW,QAAX,gBAAAO,EAAyF,cAAzF,QAAAD,EAAA,KAAAC,GAAqGL;AAAA,YAE1G;AAAA,YACA,SAAS;AACP,cAAAD,KAAA,QAAAA,EAAQ,GAAG,WACXD,KAAA,QAAAA,EAAW;AAAA,YACb;AAAA,UAAA;AAAA,QAEJ;AAAA,MAAA;AAAA,IACF,CACD;AAAA,EAAA,GACA,CAACnB,CAAK,CAAC,GAEJhB,IAAS2C,GAAU;AAAA,IACvB,YAAAhB;AAAA,IACA,SAAS;AAAA,IACT,UAAU,CAAC,EAAE,QAAA3B,QAAa;AACxB,MAAAyB,EAAiBzB,EAAO,OAAO;AAAA,IACjC;AAAA,IACA,aAAa;AAAA,MACX,YAAY;AAAA,QACV,OAAO;AAAA,MAAA;AAAA,IACT;AAAA,EACF,CACD,GAEK4C,IAAe,CAACC,MAA2C;AAC/D,QAAIA,EAAE,OAAO,SAASA,EAAE,OAAO,MAAM,CAAC,GAAG;AACvC,YAAMC,IAAOD,EAAE,OAAO,MAAM,CAAC,GACvBlC,IAAM,IAAI,gBAAgBmC,CAAI,GAE9BC,IAAmC;AAAA,QACvC,IAAI,KAAK,SAAS,SAAS,EAAE,EAAE,OAAO,GAAG,CAAC;AAAA,QAC1C,MAAMD,EAAK;AAAA,QACX,KAAAnC;AAAA,QACA,MAAMmC,EAAK,KAAK,WAAW,QAAQ,IAAI,UAAU;AAAA,MAAA;AAGnD,MAAAvB,EAAe,CAAC,GAAGD,GAAayB,CAAa,CAAC,GAE9CF,EAAE,OAAO,QAAQ;AAAA,IACnB;AAAA,EACF,GAEMG,IAAmB,CAACC,MAAe;AACvC,IAAA1B,EAAeD,EAAY,OAAO,CAAA4B,MAAKA,EAAE,OAAOD,CAAE,CAAC;AAAA,EACrD,GAEME,IAAe,MAAM;AACzB,IAAI,CAACnD,KAAWA,EAAO,WAAWsB,EAAY,WAAW,MAEzDP,EAAS;AAAA,MACP,SAASf,EAAO,QAAA;AAAA,MAChB,mBAAmBiB;AAAA,MACnB,aAAAK;AAAA,IAAA,CACD,GAEDtB,EAAO,SAAS,aAAA,GAChBuB,EAAe,CAAA,CAAE,GACjBL,EAAc,EAAK,GAEnBO,EAAiB,EAAI;AAAA,EACvB;AAEA,SACE,gBAAAvB,EAAC,OAAA,EAAI,WAAU,0BACb,UAAA;AAAA,IAAA,gBAAAA,EAACkD,GAAA,EAAO,WAAU,uBAChB,UAAA;AAAA,MAAA,gBAAAxD,EAACyD,GAAA,EAAY,KAAKvC,EAAY,OAAA,CAAQ;AAAA,MACtC,gBAAAlB,EAAC0D,KAAgB,UAAAxC,EAAY,KAAK,UAAU,GAAG,CAAC,EAAE,cAAY,CAAE;AAAA,IAAA,GAClE;AAAA,IAEA,gBAAAZ,EAAC,SAAI,WAAWJ;AAAA,MACd;AAAA,MACAmB,KAAc;AAAA,IAAA,GAEd,UAAA;AAAA,MAAA,gBAAArB,EAACG,IAAA,EAAc,QAAAC,GAAgB,SAASoB,EAAA,CAAa;AAAA,MAErD,gBAAAxB,EAAC2D,MAAc,QAAAvD,GAAgB;AAAA,MAG9BsB,EAAY,SAAS,KACpB,gBAAA1B,EAAC,OAAA,EAAI,WAAU,kCACZ,UAAA0B,EAAY,IAAI,CAAAkC,MACf,gBAAAtD,EAAC,OAAA,EAAiB,WAAU,kBACzB,UAAA;AAAA,QAAAsD,EAAI,SAAS,UACZ,gBAAA5D,EAAC,OAAA,EAAI,WAAU,wDACb,UAAA,gBAAAA,EAAC,OAAA,EAAI,KAAK4D,EAAI,KAAK,KAAKA,EAAI,MAAM,WAAU,6BAAA,CAA6B,EAAA,CAC3E,IAEA,gBAAA5D,EAAC,OAAA,EAAI,WAAU,yEACb,UAAA,gBAAAA,EAAC6D,GAAA,EAAU,WAAU,gCAAA,CAAgC,GACvD;AAAA,QAEF,gBAAA7D;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,MAAMoD,EAAiBQ,EAAI,EAAE;AAAA,YACtC,WAAU;AAAA,YAEV,UAAA,gBAAA5D,EAAC,GAAA,EAAE,WAAU,UAAA,CAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACzB,EAAA,GAfQ4D,EAAI,EAgBd,CACD,GACH;AAAA,MAGF,gBAAAtD,EAAC,OAAA,EAAI,WAAU,8DACb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,UAAA,gBAAAA,EAACwD,GAAA,EACC,UAAA;AAAA,YAAA,gBAAA9D,EAAC+D,GAAA,EAAe,SAAO,IACrB,UAAA,gBAAA/D;AAAA,cAACO;AAAA,cAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,WAAWL;AAAA,kBACT;AAAA,kBACAsB,IAAc,6BAA6B;AAAA,gBAAA;AAAA,gBAE7C,SAAS,MAAMC,EAAe,CAACD,CAAW;AAAA,gBAC1C,cAAW;AAAA,gBAEX,UAAA,gBAAAxB,EAACgE,GAAA,EAAK,WAAU,UAAA,CAAU;AAAA,cAAA;AAAA,YAAA,GAE9B;AAAA,YACA,gBAAAhE,EAACiE,KAAe,UAAA,uBAAA,CAAoB;AAAA,UAAA,GACtC;AAAA,UAEA,gBAAAjE,EAAC,OAAA,EAAI,WAAU,0BAAA,CAA0B;AAAA,4BAExCkE,GAAA,EACC,UAAA;AAAA,YAAA,gBAAAlE,EAACmE,GAAA,EAAe,SAAO,IACrB,UAAA,gBAAAnE;AAAA,cAACO;AAAA,cAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,WAAU;AAAA,gBACV,cAAW;AAAA,gBAEX,UAAA,gBAAAP,EAACoE,GAAA,EAAM,WAAU,UAAA,CAAU;AAAA,cAAA;AAAA,YAAA,GAE/B;AAAA,8BACCC,GAAA,EAAe,WAAU,0BAAyB,OAAM,SAAQ,MAAK,OACnE,UAAA,gBAAArE;AAAA,cAACsE;AAAA,cAAA;AAAA,gBACC,cAAc,CAACC,MAAcnE,KAAA,gBAAAA,EAAQ,QAAQ,QAAQ,cAAcmE,EAAU,OAAO;AAAA,gBACpF,OAAO;AAAA,gBACP,QAAQ;AAAA,cAAA;AAAA,YAAA,EACV,CACH;AAAA,UAAA,GACF;AAAA,UAEA,gBAAAvE;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,KAAK8B;AAAA,cACL,UAAUkB;AAAA,cACV,QAAO;AAAA,YAAA;AAAA,UAAA;AAAA,4BAERc,GAAA,EACC,UAAA;AAAA,YAAA,gBAAA9D,EAAC+D,GAAA,EAAe,SAAO,IACrB,UAAA,gBAAA/D;AAAA,cAACO;AAAA,cAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,WAAU;AAAA,gBACV,SAAS,MAAA;;AAAM,0BAAAuC,IAAAhB,EAAa,YAAb,gBAAAgB,EAAsB;AAAA;AAAA,gBACrC,cAAW;AAAA,gBAEX,UAAA,gBAAA9C,EAAC6D,GAAA,EAAU,WAAU,UAAA,CAAU;AAAA,cAAA;AAAA,YAAA,GAEnC;AAAA,YACA,gBAAA7D,EAACiE,KAAe,UAAA,iBAAA,CAAc;AAAA,UAAA,GAChC;AAAA,4BAECH,GAAA,EACC,UAAA;AAAA,YAAA,gBAAA9D,EAAC+D,GAAA,EAAe,SAAO,IACrB,UAAA,gBAAAzD;AAAA,cAACC;AAAA,cAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,WAAWL;AAAA,kBACT;AAAA,kBACAmB,IACI,wEACA;AAAA,gBAAA;AAAA,gBAEN,SAAS,MAAMC,EAAc,CAACD,CAAU;AAAA,gBAExC,UAAA;AAAA,kBAAA,gBAAArB,EAACwE,GAAA,EAAY,WAAU,UAAA,CAAU;AAAA,kBACjC,gBAAAxE,EAAC,QAAA,EAAK,WAAU,uBAAsB,UAAA,oBAAA,CAAiB;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA,GAE3D;AAAA,YACA,gBAAAA,EAACiE,KAAe,UAAA,oDAAA,CAAiD;AAAA,UAAA,EAAA,CACnE;AAAA,QAAA,GACF;AAAA,QAEA,gBAAA3D;AAAA,UAACC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,SAASgD;AAAA,YACT,UAAU3B,KAAiBF,EAAY,WAAW;AAAA,YACnD,UAAA;AAAA,cAAA;AAAA,cACQ,gBAAA1B,EAACyE,GAAA,EAAK,WAAU,mBAAA,CAAmB;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAC5C,EAAA,CACF;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ,GAMMC,KAAc,CAAC;AAAA,EACnB,SAAAC;AAAA,EACA,eAAAC;AAAA,EACA,UAAAC;AAAA,EACA,SAAAC;AACF,MAKM;;AACJ,QAAMzD,IAAasD,EAAQ;AAE3B,SACE,gBAAArE,EAAC,SAAI,WAAWJ;AAAA,IACd;AAAA,IACAmB,IAAa,kDAAkD;AAAA,EAAA,GAE/D,UAAA;AAAA,IAAA,gBAAAf,EAACkD,GAAA,EAAO,WAAU,yBAChB,UAAA;AAAA,MAAA,gBAAAxD,EAACyD,GAAA,EAAY,KAAKkB,EAAQ,KAAK,QAAQ;AAAA,MACvC,gBAAA3E,EAAC0D,GAAA,EAAgB,UAAAiB,EAAQ,KAAK,KAAK,UAAU,GAAG,CAAC,EAAE,YAAA,EAAY,CAAE;AAAA,IAAA,GACnE;AAAA,IAEA,gBAAArE,EAAC,OAAA,EAAI,WAAU,kBAEb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,4CACb,UAAA;AAAA,QAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,UAAA,gBAAAN,EAAC,QAAA,EAAK,WAAU,yCAAyC,UAAA2E,EAAQ,KAAK,MAAK;AAAA,UAC3E,gBAAA3E,EAACL,IAAA,EAAU,MAAMgF,EAAQ,KAAK,MAAM;AAAA,UACpC,gBAAA3E,EAAC,QAAA,EAAK,WAAU,8BACb,UAAA+E,EAAOJ,EAAQ,WAAW,qBAAqB,EAAE,QAAQK,EAAA,CAAM,EAAA,CAClE;AAAA,QAAA,GACF;AAAA,QAEA,gBAAA1E,EAAC,OAAA,EAAI,WAAU,gFACb,UAAA;AAAA,UAAA,gBAAAA,EAAC4D,GAAA,EACC,UAAA;AAAA,YAAA,gBAAAlE,EAACmE,GAAA,EAAe,SAAO,IACrB,UAAA,gBAAAnE;AAAA,cAACO;AAAA,cAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,WAAU;AAAA,gBACV,cAAW;AAAA,gBAEX,UAAA,gBAAAP,EAACoE,GAAA,EAAM,WAAU,eAAc,eAAY,OAAA,CAAO;AAAA,cAAA;AAAA,YAAA,GAEtD;AAAA,YACA,gBAAApE,EAACqE,GAAA,EAAe,WAAU,0BAAyB,OAAM,OACtD,UAAA,gBAAArE;AAAA,cAACsE;AAAA,cAAA;AAAA,gBACC,cAAc,CAACC,MAAcO,KAAA,gBAAAA,EAAUH,EAAQ,IAAIJ,EAAU;AAAA,gBAC7D,OAAO;AAAA,gBACP,QAAQ;AAAA,cAAA;AAAA,YAAA,EACV,CACH;AAAA,UAAA,GACF;AAAA,UAECM,KACC,gBAAA7E;AAAA,YAACO;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS,MAAMsE,EAASF,EAAQ,EAAE;AAAA,cAClC,cAAW;AAAA,cAEX,UAAA,gBAAA3E,EAACiF,GAAA,EAAO,WAAU,eAAc,eAAY,OAAA,CAAO;AAAA,YAAA;AAAA,UAAA;AAAA,QACrD,EAAA,CAEJ;AAAA,MAAA,GACF;AAAA,MAGC5D,KACC,gBAAAf,EAAC,OAAA,EAAI,WAAU,8HACb,UAAA;AAAA,QAAA,gBAAAN,EAACwE,GAAA,EAAY,WAAU,cAAA,CAAc;AAAA,QAAE;AAAA,MAAA,GAEzC;AAAA,MAIF,gBAAAxE;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,yBAAyB,EAAE,QAAQ2E,EAAQ,QAAA;AAAA,QAAQ;AAAA,MAAA;AAAA,MAIpDA,EAAQ,eAAeA,EAAQ,YAAY,SAAS,KACnD,gBAAA3E,EAAC,OAAA,EAAI,WAAU,6BACZ,UAAA2E,EAAQ,YAAY,IAAI,CAAAf,MACvB,gBAAA5D;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,WAAU;AAAA,UACV,SAAS,MAAM,OAAO,KAAK4D,EAAI,KAAK,QAAQ;AAAA,UAE3C,YAAI,SAAS,UACZ,gBAAAtD,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,YAAA,gBAAAN,EAAC,OAAA,EAAI,KAAK4D,EAAI,KAAK,KAAKA,EAAI,MAAM,WAAU,6BAAA,CAA6B;AAAA,YACzE,gBAAA5D,EAAC,OAAA,EAAI,WAAU,sFAAA,CAAsF;AAAA,UAAA,EAAA,CACvG,IAEA,gBAAAM,EAAC,OAAA,EAAI,WAAU,iDACb,UAAA;AAAA,YAAA,gBAAAN,EAAC6D,GAAA,EAAU,WAAU,gCAAA,CAAgC;AAAA,YACrD,gBAAA7D,EAAC,QAAA,EAAK,WAAU,8CAA8C,YAAI,KAAA,CAAK;AAAA,UAAA,EAAA,CACzE;AAAA,QAAA;AAAA,QAbG4D,EAAI;AAAA,MAAA,CAgBZ,GACH;AAAA,MAIF,gBAAAtD,EAAC,OAAA,EAAI,WAAU,0CACZ,UAAA;AAAA,SAAAwC,IAAA6B,EAAQ,cAAR,gBAAA7B,EAAmB,IAAI,CAACoC,MACvB,gBAAA5E;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,SAAS,MAAMwE,KAAA,gBAAAA,EAAUH,EAAQ,IAAIO,EAAS;AAAA,YAC9C,WAAWhF;AAAA,cACT;AAAA,cACAgF,EAAS,MAAM,SAASN,CAAa,IACjC,mDACA;AAAA,YAAA;AAAA,YAGN,UAAA;AAAA,cAAA,gBAAA5E,EAAC,QAAA,EAAM,YAAS,MAAA,CAAM;AAAA,cACtB,gBAAAA,EAAC,QAAA,EAAM,UAAAkF,EAAS,MAAM,OAAA,CAAO;AAAA,YAAA;AAAA,UAAA;AAAA,UAVxBA,EAAS;AAAA,QAAA;AAAA,QAcjBJ,uBACEZ,GAAA,EACC,UAAA;AAAA,UAAA,gBAAAlE,EAACmE,GAAA,EAAe,SAAO,IACrB,UAAA,gBAAAnE;AAAA,YAACO;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,WAAU;AAAA,cACV,cAAW;AAAA,cAEX,UAAA,gBAAAP,EAACmF,GAAA,EAAK,WAAU,cAAA,CAAc;AAAA,YAAA;AAAA,UAAA,GAElC;AAAA,UACA,gBAAAnF,EAACqE,GAAA,EAAe,WAAU,0BAAyB,OAAM,SACtD,UAAA,gBAAArE;AAAA,YAACsE;AAAA,YAAA;AAAA,cACC,cAAc,CAACC,MAAcO,EAAQH,EAAQ,IAAIJ,EAAU,KAAK;AAAA,cAChE,OAAO;AAAA,cACP,QAAQ;AAAA,YAAA;AAAA,UAAA,EACV,CACH;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,EAAA,CAEJ;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ,GAMaa,KAAgB,CAAC;AAAA,EAC5B,UAAAC;AAAA,EACA,aAAAnE;AAAA,EACA,OAAAE,IAAQ,CAAA;AAAA,EACR,cAAAkE;AAAA,EACA,iBAAAC;AAAA,EACA,SAAAT;AAAA,EACA,WAAA/E;AACF,MAA0B;AAExB,QAAMwD,IAAe,CAACiC,MAA4F;AAChH,IAAAF,EAAa;AAAA,MACX,SAASE,EAAK;AAAA,MACd,MAAMtE;AAAA,MACN,mBAAmBsE,EAAK;AAAA,MACxB,aAAaA,EAAK;AAAA,IAAA,CACnB;AAAA,EACH;AAEA,2BACG,OAAA,EAAI,WAAWtF,EAAG,wBAAwBH,CAAS,GAElD,UAAA;AAAA,IAAA,gBAAAO,EAAC,OAAA,EAAI,WAAU,gEACb,UAAA;AAAA,MAAA,gBAAAN,EAAC,MAAA,EAAG,WAAU,2BAA0B,UAAA,4BAAwB;AAAA,wBAC/DC,GAAA,EAAM,SAAQ,aAAY,WAAU,iDAClC,YAAS,OAAA,CACZ;AAAA,IAAA,GACF;AAAA,IAGA,gBAAAD,EAAC,OAAA,EAAI,WAAU,mDACZ,UAAAqF,EAAS,WAAW,IACnB,gBAAA/E,EAAC,OAAA,EAAI,WAAU,wFACb,UAAA;AAAA,MAAA,gBAAAN,EAAC,OAAA,EAAI,WAAU,kCACb,UAAA,gBAAAA,EAACyF,KAAe,WAAU,WAAU,eAAY,OAAA,CAAO,EAAA,CACzD;AAAA,MACA,gBAAAzF,EAAC,KAAA,EAAE,WAAU,0CAAyC,UAAA,2BAAuB;AAAA,MAC7E,gBAAAA,EAAC,KAAA,EAAE,WAAU,WAAU,UAAA,sCAAA,CAAmC;AAAA,IAAA,EAAA,CAC5D,IAEAqF,EAAS,IAAI,CAACV,MACZ,gBAAA3E;AAAA,MAAC0E;AAAA,MAAA;AAAA,QAEC,SAAAC;AAAA,QACA,eAAezD,EAAY;AAAA,QAC3B,UAAUqE;AAAA,QACV,SAAAT;AAAA,MAAA;AAAA,MAJKH,EAAQ;AAAA,IAAA,CAMhB,GAEL;AAAA,IAGA,gBAAA3E,EAAC,OAAA,EAAI,WAAU,wBACb,UAAA,gBAAAA;AAAA,MAACiB;AAAA,MAAA;AAAA,QACC,aAAAC;AAAA,QACA,UAAUqC;AAAA,QACV,OAAAnC;AAAA,MAAA;AAAA,IAAA,EACF,CACF;AAAA,EAAA,GACF;AAEJ;"}
|
|
1
|
+
{"version":3,"file":"comment-system.js","sources":["../../../../src/components/ui/data/comment-system.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { format } from \"date-fns\";\nimport { ptBR } from \"date-fns/locale\";\nimport { cn } from \"../utils\";\nimport { Avatar, AvatarFallback, AvatarImage } from \"../primitives/avatar\";\nimport { Button } from \"../primitives/button\";\nimport { Badge } from \"../primitives/badge\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../overlays/tooltip\";\nimport { Separator } from \"../primitives/separator\";\nimport { \n Bold, \n Italic, \n Underline as UnderlineIcon, \n List, \n ListOrdered, \n Link as LinkIcon,\n Send,\n Paperclip,\n AlertCircle,\n MoreHorizontal,\n Trash2,\n Type,\n X,\n Smile,\n Plus\n} from \"lucide-react\";\n\n// Tiptap Imports\nimport { useEditor, EditorContent, Editor, ReactRenderer } from '@tiptap/react';\nimport type { Instance as TippyInstance } from 'tippy.js';\nimport StarterKit from '@tiptap/starter-kit';\nimport Underline from '@tiptap/extension-underline';\nimport Link from '@tiptap/extension-link';\nimport TiptapImage from '@tiptap/extension-image';\nimport Mention from '@tiptap/extension-mention';\nimport tippy from 'tippy.js';\nimport { MentionList } from './mention-list';\nimport Picker from 'emoji-picker-react';\nimport { Popover, PopoverContent, PopoverTrigger } from \"../overlays/popover\";\n\n// ==========================================\n// TIPOS\n// ==========================================\n\nexport type UserRole = 'internal' | 'client' | 'freelancer';\n\nexport interface CommentUser {\n id: string;\n name: string;\n avatar?: string;\n role: UserRole;\n}\n\nexport interface CommentReaction {\n emoji: string;\n users: string[]; // Array de IDs de usuários que reagiram\n}\n\nexport interface CommentAttachment {\n id: string;\n url: string;\n name: string;\n type: 'image' | 'file';\n}\n\nexport interface Comment {\n id: string;\n content: string; // Conteúdo HTML\n user: CommentUser;\n createdAt: Date;\n isRevisionRequest?: boolean;\n attachments?: CommentAttachment[];\n reactions?: CommentReaction[];\n}\n\nexport interface CommentSystemProps {\n comments: Comment[];\n currentUser: CommentUser;\n users?: CommentUser[]; // Lista de usuários mencionáveis\n onAddComment: (comment: Omit<Comment, \"id\" | \"createdAt\">) => void;\n onDeleteComment?: (id: string) => void;\n onReact?: (commentId: string, emoji: string) => void;\n className?: string;\n}\n\n// ==========================================\n// COMPONENTES AUXILIARES\n// ==========================================\n\nconst RoleBadge = ({ role }: { role: UserRole }) => {\n const config = {\n internal: { label: \"Equipe iClips\", className: \"bg-primary/10 text-primary border-primary/20\" },\n client: { label: \"Cliente\", className: \"bg-info/10 text-info-emphasis border-info/20\" },\n freelancer: { label: \"Freelancer\", className: \"bg-warning/10 text-warning-emphasis border-warning/20\" },\n };\n\n const { label, className } = config[role];\n\n return (\n <Badge variant=\"outline\" className={cn(\"text-[10px] h-5 px-1.5 font-medium border-0\", className)}>\n {label}\n </Badge>\n );\n};\n\n// ==========================================\n// EDITOR TOOLBAR\n// ==========================================\n\nconst EditorToolbar = ({ editor, visible }: { editor: Editor | null, visible: boolean }) => {\n if (!editor) return null;\n\n if (!visible) return null;\n\n return (\n <div className=\"flex items-center gap-1 border-b p-1 bg-muted/20 animate-in slide-in-from-bottom-2 duration-200\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('bold') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().toggleBold().run()}\n title=\"Negrito (Ctrl+B)\"\n aria-label=\"Negrito\"\n >\n <Bold className=\"h-3.5 w-3.5\" />\n </Button>\n \n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('italic') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().toggleItalic().run()}\n title=\"Itálico (Ctrl+I)\"\n aria-label=\"Itálico\"\n >\n <Italic className=\"h-3.5 w-3.5\" />\n </Button>\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('underline') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().toggleUnderline().run()}\n title=\"Sublinhado (Ctrl+U)\"\n aria-label=\"Sublinhado\"\n >\n <UnderlineIcon className=\"h-3.5 w-3.5\" />\n </Button>\n\n <Separator orientation=\"vertical\" className=\"h-4 mx-1\" />\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('bulletList') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().toggleBulletList().run()}\n aria-label=\"Lista com marcadores\"\n >\n <List className=\"h-3.5 w-3.5\" />\n </Button>\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('orderedList') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().toggleOrderedList().run()}\n aria-label=\"Lista numerada\"\n >\n <ListOrdered className=\"h-3.5 w-3.5\" />\n </Button>\n\n <Separator orientation=\"vertical\" className=\"h-4 mx-1\" />\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('link') && \"bg-muted text-primary\")}\n aria-label=\"Inserir link\"\n onClick={() => {\n const previousUrl = editor.getAttributes('link').href;\n const url = window.prompt('URL', previousUrl);\n if (url === null) return;\n if (url === '') {\n editor.chain().focus().extendMarkRange('link').unsetLink().run();\n return;\n }\n editor.chain().focus().extendMarkRange('link').setLink({ href: url }).run();\n }}\n >\n <LinkIcon className=\"h-3.5 w-3.5\" />\n </Button>\n </div>\n );\n};\n\n// ==========================================\n// COMMENT EDITOR AREA\n// ==========================================\n\nconst CommentEditor = ({ \n currentUser, \n onSubmit,\n users = []\n}: { \n currentUser: CommentUser;\n onSubmit: (data: { content: string; isRevisionRequest: boolean; attachments: CommentAttachment[] }) => void;\n users?: CommentUser[];\n}) => {\n const [isRevision, setIsRevision] = React.useState(false);\n const [showToolbar, setShowToolbar] = React.useState(false);\n const [attachments, setAttachments] = React.useState<CommentAttachment[]>([]);\n const [isEditorEmpty, setIsEditorEmpty] = React.useState(true);\n const fileInputRef = React.useRef<HTMLInputElement>(null);\n\n const extensions = React.useMemo(() => [\n StarterKit.configure({\n // @ts-ignore\n link: false,\n // @ts-ignore\n underline: false,\n }),\n Underline,\n Link.configure({\n openOnClick: false,\n }),\n TiptapImage,\n Mention.configure({\n HTMLAttributes: {\n class: 'bg-secondary text-secondary-foreground rounded-sm px-1 py-0.5 font-medium decoration-clone',\n },\n suggestion: {\n items: ({ query }: { query: string }) => {\n return users\n .filter(item => item.name.toLowerCase().startsWith(query.toLowerCase()))\n .slice(0, 5);\n },\n render: () => {\n // Formato mínimo dos props do ciclo de vida do suggestion do tiptap\n // (o tipo completo `SuggestionProps` vive em `@tiptap/suggestion`, dep\n // transitiva sem entrada direta no package.json).\n type MentionRenderProps = {\n editor: Editor;\n clientRect?: (() => DOMRect | null) | null;\n event?: KeyboardEvent;\n };\n let component: ReactRenderer | null = null;\n let popup: TippyInstance[] | null = null;\n\n return {\n onStart: (props: MentionRenderProps) => {\n component = new ReactRenderer(MentionList, {\n props,\n editor: props.editor,\n });\n\n if (!props.clientRect) {\n return;\n }\n\n popup = tippy('body', {\n // tiptap tipa como `() => DOMRect | null`; tippy exige não-nulo.\n getReferenceClientRect: props.clientRect as () => DOMRect,\n appendTo: () => document.body,\n content: component.element,\n showOnCreate: true,\n interactive: true,\n trigger: 'manual',\n placement: 'bottom-start',\n });\n },\n onUpdate(props: MentionRenderProps) {\n component?.updateProps(props);\n\n if (!props.clientRect) {\n return;\n }\n\n popup?.[0].setProps({\n getReferenceClientRect: props.clientRect as () => DOMRect,\n });\n },\n onKeyDown(props: { event: KeyboardEvent }) {\n if (props.event.key === 'Escape') {\n popup?.[0].hide();\n\n return true;\n }\n\n return Boolean(\n (component?.ref as { onKeyDown?: (p: { event: KeyboardEvent }) => boolean } | undefined)?.onKeyDown?.(props),\n );\n },\n onExit() {\n popup?.[0].destroy();\n component?.destroy();\n },\n };\n },\n },\n }),\n ], [users]);\n\n const editor = useEditor({\n extensions,\n content: '',\n onUpdate: ({ editor }) => {\n setIsEditorEmpty(editor.isEmpty);\n },\n editorProps: {\n attributes: {\n class: 'prose prose-sm dark:prose-invert max-w-none focus:outline-none min-h-[80px] px-3 py-2 text-sm',\n },\n },\n });\n\n const handleAttach = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (e.target.files && e.target.files[0]) {\n const file = e.target.files[0];\n const url = URL.createObjectURL(file);\n \n const newAttachment: CommentAttachment = {\n id: Math.random().toString(36).substr(2, 9),\n name: file.name,\n url,\n type: file.type.startsWith('image/') ? 'image' : 'file'\n };\n \n setAttachments([...attachments, newAttachment]);\n // Reset input\n e.target.value = '';\n }\n };\n\n const removeAttachment = (id: string) => {\n setAttachments(attachments.filter(a => a.id !== id));\n };\n\n const handleSubmit = () => {\n if (!editor || (editor.isEmpty && attachments.length === 0)) return;\n \n onSubmit({\n content: editor.getHTML(),\n isRevisionRequest: isRevision,\n attachments\n });\n\n editor.commands.clearContent();\n setAttachments([]);\n setIsRevision(false);\n // Manually reset empty state since clearContent triggers update but we want to be sure\n setIsEditorEmpty(true);\n };\n\n return (\n <div className=\"flex gap-3 items-start\">\n <Avatar className=\"h-8 w-8 mt-1 border\">\n <AvatarImage src={currentUser.avatar} />\n <AvatarFallback>{currentUser.name.substring(0, 2).toUpperCase()}</AvatarFallback>\n </Avatar>\n\n <div className={cn(\n \"flex-1 rounded-xl border bg-background shadow-sm overflow-hidden transition-colors\",\n isRevision && \"border-destructive/40 ring-1 ring-destructive/20\"\n )}>\n <EditorToolbar editor={editor} visible={showToolbar} />\n \n <EditorContent editor={editor} />\n\n {/* Attachments Preview Area */}\n {attachments.length > 0 && (\n <div className=\"px-3 pb-2 flex flex-wrap gap-2\">\n {attachments.map(att => (\n <div key={att.id} className=\"relative group\">\n {att.type === 'image' ? (\n <div className=\"h-16 w-16 rounded-md border overflow-hidden relative\">\n <img src={att.url} alt={att.name} className=\"h-full w-full object-cover\" />\n </div>\n ) : (\n <div className=\"h-16 w-16 rounded-md border bg-muted flex items-center justify-center\">\n <Paperclip className=\"h-6 w-6 text-muted-foreground\" />\n </div>\n )}\n <button \n onClick={() => removeAttachment(att.id)}\n className=\"absolute -top-1.5 -right-1.5 border bg-background text-destructive-emphasis hover:bg-destructive/10 rounded-full p-0.5 opacity-100 md:opacity-0 md:group-hover:opacity-100 md:group-focus-within:opacity-100 transition-opacity shadow-sm\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n </div>\n ))}\n </div>\n )}\n\n <div className=\"flex items-center justify-between p-2 bg-muted/10 border-t\">\n <div className=\"flex items-center gap-2\">\n <Tooltip>\n <TooltipTrigger asChild>\n <Button \n variant=\"ghost\" \n size=\"icon\" \n className={cn(\n \"h-8 w-8 transition-colors\",\n showToolbar ? \"bg-muted text-foreground\" : \"text-muted-foreground hover:text-foreground\"\n )}\n onClick={() => setShowToolbar(!showToolbar)}\n aria-label=\"Opções de formatação\"\n >\n <Type className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Opções de formatação</TooltipContent>\n </Tooltip>\n\n <div className=\"w-px h-4 bg-border mx-1\" />\n\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-muted-foreground hover:text-foreground\"\n aria-label=\"Inserir emoji\"\n >\n <Smile className=\"h-4 w-4\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0 border-none\" align=\"start\" side=\"top\">\n <Picker \n onEmojiClick={(emojiData) => editor?.chain().focus().insertContent(emojiData.emoji).run()}\n width={300}\n height={350}\n />\n </PopoverContent>\n </Popover>\n\n <input \n type=\"file\" \n className=\"hidden\" \n ref={fileInputRef}\n onChange={handleAttach}\n accept=\"image/*,.pdf,.doc,.docx\"\n />\n <Tooltip>\n <TooltipTrigger asChild>\n <Button \n variant=\"ghost\" \n size=\"icon\" \n className=\"h-8 w-8 text-muted-foreground hover:text-foreground\"\n onClick={() => fileInputRef.current?.click()}\n aria-label=\"Anexar arquivo\"\n >\n <Paperclip className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Anexar arquivo</TooltipContent>\n </Tooltip>\n\n <Tooltip>\n <TooltipTrigger asChild>\n <Button \n variant=\"ghost\" \n size=\"sm\" \n className={cn(\n \"h-8 gap-2 px-2 transition-colors\",\n isRevision\n ? \"bg-destructive/10 text-destructive-emphasis hover:bg-destructive/20\"\n : \"text-muted-foreground hover:text-foreground\"\n )}\n onClick={() => setIsRevision(!isRevision)}\n >\n <AlertCircle className=\"h-4 w-4\" />\n <span className=\"text-xs font-medium\">Solicitar Refação</span>\n </Button>\n </TooltipTrigger>\n <TooltipContent>Marca este comentário como um pedido de alteração</TooltipContent>\n </Tooltip>\n </div>\n\n <Button\n size=\"sm\"\n onClick={handleSubmit}\n disabled={isEditorEmpty && attachments.length === 0}\n >\n Enviar <Send className=\"h-3.5 w-3.5 ml-2\" />\n </Button>\n </div>\n </div>\n </div>\n );\n};\n\n// ==========================================\n// SINGLE COMMENT ITEM\n// ==========================================\n\nconst CommentItem = ({ \n comment, \n currentUserId,\n onDelete, \n onReact \n}: { \n comment: Comment; \n currentUserId: string;\n onDelete?: (id: string) => void;\n onReact?: (commentId: string, emoji: string) => void;\n}) => {\n const isRevision = comment.isRevisionRequest;\n\n return (\n <div className={cn(\n \"group flex gap-3 p-4 rounded-lg transition-colors\",\n isRevision ? \"bg-destructive/5 border border-destructive/20\" : \"hover:bg-muted/20\"\n )}>\n <Avatar className=\"h-8 w-8 mt-0.5 border\">\n <AvatarImage src={comment.user.avatar} />\n <AvatarFallback>{comment.user.name.substring(0, 2).toUpperCase()}</AvatarFallback>\n </Avatar>\n\n <div className=\"flex-1 min-w-0\">\n {/* Header */}\n <div className=\"flex items-center justify-between mb-1.5\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <span className=\"font-semibold text-sm text-foreground\">{comment.user.name}</span>\n <RoleBadge role={comment.user.role} />\n <span className=\"text-xs text-foreground/65\">\n {format(comment.createdAt, \"dd MMM 'às' HH:mm\", { locale: ptBR })}\n </span>\n </div>\n \n <div className=\"flex items-center gap-2 opacity-100 md:opacity-0 md:group-hover:opacity-100 md:group-focus-within:opacity-100 transition-opacity has-[[data-state=open]]:opacity-100\">\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6 relative before:absolute before:-inset-1 before:content-[''] text-muted-foreground hover:text-foreground\"\n aria-label=\"Reagir com emoji\"\n >\n <Smile className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0 border-none\" align=\"end\">\n <Picker \n onEmojiClick={(emojiData) => onReact?.(comment.id, emojiData.emoji)}\n width={300}\n height={350}\n />\n </PopoverContent>\n </Popover>\n\n {onDelete && (\n <Button \n variant=\"ghost\" \n size=\"icon\" \n className=\"h-6 w-6 relative before:absolute before:-inset-1 before:content-[''] text-muted-foreground hover:text-destructive-emphasis\"\n onClick={() => onDelete(comment.id)}\n aria-label=\"Excluir comentário\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n </Button>\n )}\n </div>\n </div>\n\n {/* Revision Badge */}\n {isRevision && (\n <div className=\"inline-flex items-center gap-1.5 px-2 py-1 rounded-md bg-destructive/10 text-destructive-emphasis text-xs font-medium mb-2\">\n <AlertCircle className=\"h-3.5 w-3.5\" />\n Solicitação de Refação\n </div>\n )}\n\n {/* Content */}\n <div \n className=\"prose prose-sm dark:prose-invert max-w-none text-sm text-foreground/90 leading-relaxed break-words [&_p]:mb-2 [&_p:last-child]:mb-0\"\n dangerouslySetInnerHTML={{ __html: comment.content }}\n />\n\n {/* Attachments Display */}\n {comment.attachments && comment.attachments.length > 0 && (\n <div className=\"mt-3 flex flex-wrap gap-2\">\n {comment.attachments.map(att => (\n <div \n key={att.id} \n className=\"group/att relative rounded-lg border overflow-hidden bg-background hover:shadow-sm transition-all cursor-pointer\"\n onClick={() => window.open(att.url, '_blank')}\n >\n {att.type === 'image' ? (\n <div className=\"h-32 aspect-[4/3]\">\n <img src={att.url} alt={att.name} className=\"h-full w-full object-cover\" />\n <div className=\"absolute inset-0 bg-foreground/0 group-hover/att:bg-foreground/10 transition-colors\" />\n </div>\n ) : (\n <div className=\"h-12 px-3 flex items-center gap-2 bg-muted/30\">\n <Paperclip className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"text-xs font-medium truncate max-w-[150px]\">{att.name}</span>\n </div>\n )}\n </div>\n ))}\n </div>\n )}\n\n {/* Reactions */}\n <div className=\"mt-3 flex flex-wrap gap-2 items-center\">\n {comment.reactions?.map((reaction) => (\n <button\n key={reaction.emoji}\n onClick={() => onReact?.(comment.id, reaction.emoji)}\n className={cn(\n \"inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full text-xs font-medium border transition-colors\",\n reaction.users.includes(currentUserId)\n ? \"bg-secondary border-secondary text-secondary-foreground\"\n : \"bg-muted/30 border-transparent hover:bg-muted/50 text-muted-foreground\"\n )}\n >\n <span>{reaction.emoji}</span>\n <span>{reaction.users.length}</span>\n </button>\n ))}\n \n {onReact && (\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6 rounded-full text-muted-foreground hover:text-foreground hover:bg-muted/50\"\n aria-label=\"Adicionar reação\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0 border-none\" align=\"start\">\n <Picker \n onEmojiClick={(emojiData) => onReact(comment.id, emojiData.emoji)}\n width={300}\n height={350}\n />\n </PopoverContent>\n </Popover>\n )}\n </div>\n </div>\n </div>\n );\n};\n\n// ==========================================\n// MAIN COMPONENT\n// ==========================================\n\nexport const CommentSystem = ({ \n comments, \n currentUser, \n users = [],\n onAddComment, \n onDeleteComment,\n onReact,\n className \n}: CommentSystemProps) => {\n \n const handleSubmit = (data: { content: string; isRevisionRequest: boolean; attachments: CommentAttachment[] }) => {\n onAddComment({\n content: data.content,\n user: currentUser,\n isRevisionRequest: data.isRevisionRequest,\n attachments: data.attachments\n });\n };\n\n return (\n <div className={cn(\"flex flex-col h-full\", className)}>\n {/* Header */}\n <div className=\"px-4 py-3 border-b flex items-center justify-between bg-card\">\n <h3 className=\"font-semibold text-base\">Comentários da Atividade</h3>\n <Badge variant=\"secondary\" className=\"bg-muted text-muted-foreground hover:bg-muted\">\n {comments.length}\n </Badge>\n </div>\n\n {/* Scrollable List */}\n <div className=\"flex-1 overflow-y-auto p-4 space-y-2 bg-muted/5\">\n {comments.length === 0 ? (\n <div className=\"h-full flex flex-col items-center justify-center text-muted-foreground min-h-[200px]\">\n <div className=\"bg-muted rounded-full p-3 mb-3\">\n <MoreHorizontal className=\"h-6 w-6\" aria-hidden=\"true\" />\n </div>\n <p className=\"text-sm font-medium text-foreground/70\">Nenhum comentário ainda</p>\n <p className=\"text-xs\">Inicie a conversa sobre esta tarefa</p>\n </div>\n ) : (\n comments.map((comment) => (\n <CommentItem \n key={comment.id} \n comment={comment} \n currentUserId={currentUser.id}\n onDelete={onDeleteComment} \n onReact={onReact}\n />\n ))\n )}\n </div>\n\n {/* Input Area */}\n <div className=\"p-4 border-t bg-card\">\n <CommentEditor \n currentUser={currentUser} \n onSubmit={handleSubmit}\n users={users}\n />\n </div>\n </div>\n );\n};\n\nexport default CommentSystem;"],"names":["RoleBadge","role","config","label","className","jsx","Badge","cn","EditorToolbar","editor","visible","jsxs","Button","Bold","Italic","UnderlineIcon","Separator","List","ListOrdered","previousUrl","url","LinkIcon","CommentEditor","currentUser","onSubmit","users","isRevision","setIsRevision","React","showToolbar","setShowToolbar","attachments","setAttachments","isEditorEmpty","setIsEditorEmpty","fileInputRef","extensions","StarterKit","Underline","Link","TiptapImage","Mention","query","item","component","popup","props","ReactRenderer","MentionList","tippy","_b","_a","useEditor","handleAttach","e","file","newAttachment","removeAttachment","id","a","handleSubmit","Avatar","AvatarImage","AvatarFallback","EditorContent","att","Paperclip","Tooltip","TooltipTrigger","Type","TooltipContent","Popover","PopoverTrigger","Smile","PopoverContent","Picker","emojiData","AlertCircle","Send","CommentItem","comment","currentUserId","onDelete","onReact","format","ptBR","Trash2","reaction","Plus","CommentSystem","comments","onAddComment","onDeleteComment","data","MoreHorizontal"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),b=require("react"),n=require("./table.cjs"),K=require("./table-pagination.cjs"),L=require("../primitives/skeleton.cjs"),V=require("lucide-react"),W=require("../../../hooks/use-data-table.cjs"),X=require("../../../hooks/use-data-table-filters.cjs"),d=require("../utils.cjs"),Y=require("./filter-bar.cjs"),Z=require("./data-table-toolbar.cjs"),f=require("./data-table-empty-state.cjs");function v({data:j,columns:c,searchPlaceholder:P="Buscar...",searchableColumns:y,enableSearch:D=!0,filterFields:S=[],enableFilters:F=!1,initialFilters:q=[],pageSizeOptions:w=[5,10,20,50],initialPageSize:N=10,toolbarActions:z,serverConfig:a,isLoading:A=!1,emptyState:R,emptyMessage:m,className:M}){var u,T;const r=!!a,{data:x,state:i,handlers:o,getSortDirection:h}=W.useDataTable({data:j,initialPageSize:N,initialSort:{column:null,direction:null},serverMode:r,totalItems:a==null?void 0:a.totalItems,serverCurrentPage:a==null?void 0:a.currentPage,serverCurrentPageSize:a==null?void 0:a.currentPageSize}),B=y?y[0]:((u=c.find(e=>e.key==="nome"||e.key==="name"||e.key==="title"||e.key==="titulo"))==null?void 0:u.key)||((T=c[0])==null?void 0:T.key),{searchQuery:k,handleSearchChange:O,advancedFilters:g,setAdvancedFilters:C,filterDialogOpen:I,setFilterDialogOpen:E,activeFilterChips:H,handleApplyFilters:$,handleClearAllFilters:Q,clearSearchAndFilters:U}=X.useDataTableFilters({initialFilters:q,filterFields:S,isServerMode:r,serverConfig:a,handlers:o,defaultSearchColumn:B}),_=b.useCallback(async e=>{if(r&&(a!=null&&a.onSortChange)){const s=i.sort;let l="asc";s.column===e&&(l=s.direction==="asc"?"desc":s.direction==="desc"?null:"asc");const p={column:l?e:null,direction:l};o.onSort(e),await a.onSortChange(p)}else o.onSort(e)},[r,a,i.sort,o]),G=b.useCallback(async e=>{r&&(a!=null&&a.onPageChange)?await a.onPageChange(e,i.pagination.pageSize):i.pagination.onPageChange&&i.pagination.onPageChange(e)},[r,a,i.pagination]),J=b.useCallback(async e=>{r&&(a!=null&&a.onPageChange)?await a.onPageChange(1,e):i.pagination.onPageSizeChange&&i.pagination.onPageSizeChange(e)},[r,a,i.pagination]);return t.jsxs("div",{className:d.cn("space-y-4",M),children:[t.jsx(Z.DataTableToolbar,{enableSearch:D,searchPlaceholder:P,searchQuery:k,onSearchChange:O,enableFilters:F,filterFields:S,advancedFilters:g,onAdvancedFiltersChange:C,filterDialogOpen:I,onFilterDialogOpenChange:E,onApplyFilters:$,toolbarActions:z}),g.length>0&&t.jsx(Y.FilterBar,{activeFilters:H,onClearAll:Q}),t.jsx("div",{className:"rounded-md border overflow-x-auto",children:t.jsxs(n.Table,{children:[t.jsx(n.TableHeader,{children:t.jsx(n.TableRow,{children:c.map(e=>t.jsx(n.TableHead,{className:d.cn(e.sortable&&"select-none p-0",e.sortable&&h(e.key)&&"text-primary",e.headerClassName),style:{width:e.width},"aria-sort":e.sortable?h(e.key)==="asc"?"ascending":h(e.key)==="desc"?"descending":"none":void 0,children:e.sortable?t.jsxs("button",{type:"button",onClick:()=>_(e.key),className:d.cn("flex h-10 w-full items-center gap-2 px-2 text-left font-semibold whitespace-nowrap cursor-pointer hover:bg-muted/50 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset",e.align==="right"&&"justify-end text-right",e.align==="center"&&"justify-center text-center"),children:[e.header,h(e.key)&&t.jsx(V.ArrowUpDown,{className:"h-4 w-4 shrink-0"})]}):e.header},String(e.key)))})}),t.jsx(n.TableBody,{children:A?Array.from({length:Math.min(i.pagination.pageSize,15)}).map((e,s)=>t.jsx(n.TableRow,{children:c.map((l,p)=>t.jsx(n.TableCell,{className:l.className,children:t.jsx(L.Skeleton,{className:"h-4 w-full"})},p))},`skeleton-${s}`)):x.length>0?x.map((e,s)=>t.jsx(n.TableRow,{children:c.map(l=>t.jsx(n.TableCell,{className:d.cn(l.className,l.align?`text-${l.align}`:"text-left",l.onCellClick&&"cursor-pointer hover:text-primary"),onClick:l.onCellClick?()=>l.onCellClick(e[l.key],e,s):void 0,children:l.render?l.render(e[l.key],e,s):e[l.key]},String(l.key)))},s)):t.jsx(n.TableRow,{children:t.jsx(n.TableCell,{colSpan:c.length,className:"h-64",children:t.jsx(f.DataTableEmptyState,{emptyState:R,emptyMessage:m,hasActiveFilters:g.length>0,hasSearch:k.trim().length>0,onClearFilters:U})})})})]})}),t.jsx(K.TablePagination,{currentPage:i.pagination.currentPage,totalPages:Math.ceil(i.pagination.totalItems/i.pagination.pageSize),pageSize:i.pagination.pageSize,totalItems:i.pagination.totalItems,onPageChange:G,onPageSizeChange:J,pageSizeOptions:w})]})}exports.DataTable=v;
|
|
2
2
|
//# sourceMappingURL=data-table.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table.cjs","sources":["../../../../src/components/ui/data/data-table.tsx"],"sourcesContent":["import React, { useCallback } from \"react\";\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"./table\";\nimport { TablePagination } from \"./table-pagination\";\nimport { Skeleton } from \"../primitives/skeleton\";\nimport { ArrowUpDown } from \"lucide-react\";\nimport { useDataTable } from \"../../../hooks/use-data-table\";\nimport { useDataTableFilters } from \"../../../hooks/use-data-table-filters\";\nimport { ColumnDef, SortConfig, ServerSideConfig, EmptyStateConfig } from \"./table-types\";\nimport { cn } from \"../utils\";\nimport { FilterBar } from \"./filter-bar\";\nimport { FilterCondition, FilterField } from \"./filter-builder\";\nimport { DataTableToolbar } from \"./data-table-toolbar\";\nimport { DataTableEmptyState } from \"./data-table-empty-state\";\n\ninterface DataTableProps<T extends object> {\n data: T[];\n columns: ColumnDef<T>[];\n\n // Configuração de busca\n searchPlaceholder?: string;\n searchableColumns?: (keyof T)[]; // Colunas que podem ser pesquisadas\n enableSearch?: boolean;\n\n // Configuração de filtros\n filterFields?: FilterField[]; // Campos de filtro avançado\n enableFilters?: boolean;\n initialFilters?: FilterCondition[]; // Filtros iniciais/externos\n\n // Paginação\n pageSizeOptions?: number[];\n initialPageSize?: number;\n\n // Conteúdo adicional da barra de ferramentas\n toolbarActions?: React.ReactNode;\n\n // Configuração server-side\n serverConfig?: ServerSideConfig<T>;\n\n // Estado de carregamento e vazio\n isLoading?: boolean;\n /**\n * Configuração do empty state.\n * Suporta tanto config completo (EmptyStateConfig) quanto string simples (retrocompatibilidade).\n */\n emptyState?: EmptyStateConfig | string;\n /** @deprecated Use emptyState ao invés de emptyMessage */\n emptyMessage?: string;\n\n className?: string;\n}\n\nexport function DataTable<T extends object>({\n data,\n columns,\n searchPlaceholder = \"Buscar...\",\n searchableColumns,\n enableSearch = true,\n filterFields = [],\n enableFilters = false,\n initialFilters = [],\n pageSizeOptions = [5, 10, 20, 50],\n initialPageSize = 10,\n toolbarActions,\n serverConfig,\n isLoading = false,\n emptyState,\n emptyMessage, // deprecated\n className,\n}: DataTableProps<T>) {\n // Detectar se está em modo server-side\n const isServerMode = !!serverConfig;\n const {\n data: processedData,\n state,\n handlers,\n getSortDirection,\n } = useDataTable({\n data,\n initialPageSize,\n initialSort: { column: null, direction: null },\n serverMode: isServerMode,\n totalItems: serverConfig?.totalItems,\n serverCurrentPage: serverConfig?.currentPage,\n serverCurrentPageSize: serverConfig?.currentPageSize,\n });\n\n // Auto-detect searchable column\n const defaultSearchColumn = searchableColumns\n ? searchableColumns[0]\n : (columns.find(c => c.key === \"nome\" || c.key === \"name\" || c.key === \"title\" || c.key === \"titulo\")?.key || columns[0]?.key);\n\n const {\n searchQuery,\n handleSearchChange,\n advancedFilters,\n setAdvancedFilters,\n filterDialogOpen,\n setFilterDialogOpen,\n activeFilterChips,\n handleApplyFilters,\n handleClearAllFilters,\n clearSearchAndFilters,\n } = useDataTableFilters<T>({\n initialFilters,\n filterFields,\n isServerMode,\n serverConfig,\n handlers,\n defaultSearchColumn,\n });\n\n // Handle sort - server-side aware\n const handleSort = useCallback(async (column: keyof T) => {\n if (isServerMode && serverConfig?.onSortChange) {\n // Calcular novo sortConfig\n const currentSort = state.sort;\n let newDirection: 'asc' | 'desc' | null = 'asc';\n\n if (currentSort.column === column) {\n newDirection = currentSort.direction === 'asc' ? 'desc' :\n currentSort.direction === 'desc' ? null : 'asc';\n }\n\n const newSortConfig: SortConfig<T> = {\n column: newDirection ? column : null,\n direction: newDirection\n };\n\n // Atualizar estado interno primeiro para mostrar indicador visual\n handlers.onSort(column);\n\n // Depois chamar callback do servidor\n await serverConfig.onSortChange(newSortConfig);\n } else {\n // Client-side: usar handler padrão\n handlers.onSort(column);\n }\n }, [isServerMode, serverConfig, state.sort, handlers]);\n\n // Handle page change - server-side aware\n const handlePageChange = useCallback(async (page: number) => {\n if (isServerMode && serverConfig?.onPageChange) {\n await serverConfig.onPageChange(page, state.pagination.pageSize);\n } else {\n // Client-side: usar handler padrão\n if (state.pagination.onPageChange) {\n state.pagination.onPageChange(page);\n }\n }\n }, [isServerMode, serverConfig, state.pagination]);\n\n // Handle page size change - server-side aware\n const handlePageSizeChange = useCallback(async (newSize: number) => {\n if (isServerMode && serverConfig?.onPageChange) {\n await serverConfig.onPageChange(1, newSize); // Reset para página 1\n } else {\n // Client-side: usar handler padrão\n if (state.pagination.onPageSizeChange) {\n state.pagination.onPageSizeChange(newSize);\n }\n }\n }, [isServerMode, serverConfig, state.pagination]);\n\n return (\n <div className={cn(\"space-y-4\", className)}>\n {/* Toolbar — only rendered when there is at least one visible element */}\n <DataTableToolbar\n enableSearch={enableSearch}\n searchPlaceholder={searchPlaceholder}\n searchQuery={searchQuery}\n onSearchChange={handleSearchChange}\n enableFilters={enableFilters}\n filterFields={filterFields}\n advancedFilters={advancedFilters}\n onAdvancedFiltersChange={setAdvancedFilters}\n filterDialogOpen={filterDialogOpen}\n onFilterDialogOpenChange={setFilterDialogOpen}\n onApplyFilters={handleApplyFilters}\n toolbarActions={toolbarActions}\n />\n\n {/* Active Filter Chips */}\n {advancedFilters.length > 0 && (\n <FilterBar\n activeFilters={activeFilterChips}\n onClearAll={handleClearAllFilters}\n />\n )}\n\n {/* Table */}\n <div className=\"rounded-md border overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n {columns.map((column) => (\n <TableHead\n key={String(column.key)}\n className={cn(\n column.headerClassName,\n column.sortable && \"cursor-pointer select-none hover:bg-muted/50 transition-colors\",\n column.sortable && getSortDirection(column.key) && \"text-primary\"\n )}\n style={{ width: column.width }}\n onClick={() => column.sortable && handleSort(column.key)}\n aria-sort={column.sortable ? (getSortDirection(column.key) === \"asc\" ? \"ascending\" : getSortDirection(column.key) === \"desc\" ? \"descending\" : \"none\") : undefined}\n >\n {column.header}\n {column.sortable && getSortDirection(column.key) && (\n <ArrowUpDown className=\"ml-2 h-4 w-4 inline\" />\n )}\n </TableHead>\n ))}\n </TableRow>\n </TableHeader>\n <TableBody>\n {isLoading ? (\n // SKELETON ROWS - limitar a max 15 para performance\n Array.from({ length: Math.min(state.pagination.pageSize, 15) }).map((_, i) => (\n <TableRow key={`skeleton-${i}`}>\n {columns.map((col, j) => (\n <TableCell key={j} className={col.className}>\n <Skeleton className=\"h-4 w-full\" />\n </TableCell>\n ))}\n </TableRow>\n ))\n ) : processedData.length > 0 ? (\n // DADOS NORMAIS\n processedData.map((row, rowIndex) => (\n <TableRow key={rowIndex}>\n {columns.map((column) => (\n <TableCell\n key={String(column.key)}\n className={cn(\n column.className,\n column.align ? `text-${column.align}` : \"text-left\",\n column.onCellClick && \"cursor-pointer hover:text-primary\"\n )}\n onClick={column.onCellClick\n ? () => column.onCellClick!(row[column.key], row, rowIndex)\n : undefined}\n >\n {column.render\n ? column.render(row[column.key], row, rowIndex)\n : (row[column.key] as React.ReactNode)}\n </TableCell>\n ))}\n </TableRow>\n ))\n ) : (\n // EMPTY STATE\n <TableRow>\n <TableCell\n colSpan={columns.length}\n className=\"h-64\"\n >\n <DataTableEmptyState\n emptyState={emptyState}\n emptyMessage={emptyMessage}\n hasActiveFilters={advancedFilters.length > 0}\n hasSearch={searchQuery.trim().length > 0}\n onClearFilters={clearSearchAndFilters}\n />\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n\n {/* Pagination */}\n <TablePagination\n currentPage={state.pagination.currentPage}\n totalPages={Math.ceil(state.pagination.totalItems / state.pagination.pageSize)}\n pageSize={state.pagination.pageSize}\n totalItems={state.pagination.totalItems}\n onPageChange={handlePageChange}\n onPageSizeChange={handlePageSizeChange}\n pageSizeOptions={pageSizeOptions}\n />\n </div>\n );\n}\n"],"names":["DataTable","data","columns","searchPlaceholder","searchableColumns","enableSearch","filterFields","enableFilters","initialFilters","pageSizeOptions","initialPageSize","toolbarActions","serverConfig","isLoading","emptyState","emptyMessage","className","isServerMode","processedData","state","handlers","getSortDirection","useDataTable","defaultSearchColumn","_a","c","_b","searchQuery","handleSearchChange","advancedFilters","setAdvancedFilters","filterDialogOpen","setFilterDialogOpen","activeFilterChips","handleApplyFilters","handleClearAllFilters","clearSearchAndFilters","useDataTableFilters","handleSort","useCallback","column","currentSort","newDirection","newSortConfig","handlePageChange","page","handlePageSizeChange","newSize","cn","jsx","DataTableToolbar","FilterBar","Table","TableHeader","TableRow","jsxs","TableHead","ArrowUpDown","TableBody","_","i","col","j","TableCell","Skeleton","row","rowIndex","DataTableEmptyState","TablePagination"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"data-table.cjs","sources":["../../../../src/components/ui/data/data-table.tsx"],"sourcesContent":["import React, { useCallback } from \"react\";\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"./table\";\nimport { TablePagination } from \"./table-pagination\";\nimport { Skeleton } from \"../primitives/skeleton\";\nimport { ArrowUpDown } from \"lucide-react\";\nimport { useDataTable } from \"../../../hooks/use-data-table\";\nimport { useDataTableFilters } from \"../../../hooks/use-data-table-filters\";\nimport { ColumnDef, SortConfig, ServerSideConfig, EmptyStateConfig } from \"./table-types\";\nimport { cn } from \"../utils\";\nimport { FilterBar } from \"./filter-bar\";\nimport { FilterCondition, FilterField } from \"./filter-builder\";\nimport { DataTableToolbar } from \"./data-table-toolbar\";\nimport { DataTableEmptyState } from \"./data-table-empty-state\";\n\ninterface DataTableProps<T extends object> {\n data: T[];\n columns: ColumnDef<T>[];\n\n // Configuração de busca\n searchPlaceholder?: string;\n searchableColumns?: (keyof T)[]; // Colunas que podem ser pesquisadas\n enableSearch?: boolean;\n\n // Configuração de filtros\n filterFields?: FilterField[]; // Campos de filtro avançado\n enableFilters?: boolean;\n initialFilters?: FilterCondition[]; // Filtros iniciais/externos\n\n // Paginação\n pageSizeOptions?: number[];\n initialPageSize?: number;\n\n // Conteúdo adicional da barra de ferramentas\n toolbarActions?: React.ReactNode;\n\n // Configuração server-side\n serverConfig?: ServerSideConfig<T>;\n\n // Estado de carregamento e vazio\n isLoading?: boolean;\n /**\n * Configuração do empty state.\n * Suporta tanto config completo (EmptyStateConfig) quanto string simples (retrocompatibilidade).\n */\n emptyState?: EmptyStateConfig | string;\n /** @deprecated Use emptyState ao invés de emptyMessage */\n emptyMessage?: string;\n\n className?: string;\n}\n\nexport function DataTable<T extends object>({\n data,\n columns,\n searchPlaceholder = \"Buscar...\",\n searchableColumns,\n enableSearch = true,\n filterFields = [],\n enableFilters = false,\n initialFilters = [],\n pageSizeOptions = [5, 10, 20, 50],\n initialPageSize = 10,\n toolbarActions,\n serverConfig,\n isLoading = false,\n emptyState,\n emptyMessage, // deprecated\n className,\n}: DataTableProps<T>) {\n // Detectar se está em modo server-side\n const isServerMode = !!serverConfig;\n const {\n data: processedData,\n state,\n handlers,\n getSortDirection,\n } = useDataTable({\n data,\n initialPageSize,\n initialSort: { column: null, direction: null },\n serverMode: isServerMode,\n totalItems: serverConfig?.totalItems,\n serverCurrentPage: serverConfig?.currentPage,\n serverCurrentPageSize: serverConfig?.currentPageSize,\n });\n\n // Auto-detect searchable column\n const defaultSearchColumn = searchableColumns\n ? searchableColumns[0]\n : (columns.find(c => c.key === \"nome\" || c.key === \"name\" || c.key === \"title\" || c.key === \"titulo\")?.key || columns[0]?.key);\n\n const {\n searchQuery,\n handleSearchChange,\n advancedFilters,\n setAdvancedFilters,\n filterDialogOpen,\n setFilterDialogOpen,\n activeFilterChips,\n handleApplyFilters,\n handleClearAllFilters,\n clearSearchAndFilters,\n } = useDataTableFilters<T>({\n initialFilters,\n filterFields,\n isServerMode,\n serverConfig,\n handlers,\n defaultSearchColumn,\n });\n\n // Handle sort - server-side aware\n const handleSort = useCallback(async (column: keyof T) => {\n if (isServerMode && serverConfig?.onSortChange) {\n // Calcular novo sortConfig\n const currentSort = state.sort;\n let newDirection: 'asc' | 'desc' | null = 'asc';\n\n if (currentSort.column === column) {\n newDirection = currentSort.direction === 'asc' ? 'desc' :\n currentSort.direction === 'desc' ? null : 'asc';\n }\n\n const newSortConfig: SortConfig<T> = {\n column: newDirection ? column : null,\n direction: newDirection\n };\n\n // Atualizar estado interno primeiro para mostrar indicador visual\n handlers.onSort(column);\n\n // Depois chamar callback do servidor\n await serverConfig.onSortChange(newSortConfig);\n } else {\n // Client-side: usar handler padrão\n handlers.onSort(column);\n }\n }, [isServerMode, serverConfig, state.sort, handlers]);\n\n // Handle page change - server-side aware\n const handlePageChange = useCallback(async (page: number) => {\n if (isServerMode && serverConfig?.onPageChange) {\n await serverConfig.onPageChange(page, state.pagination.pageSize);\n } else {\n // Client-side: usar handler padrão\n if (state.pagination.onPageChange) {\n state.pagination.onPageChange(page);\n }\n }\n }, [isServerMode, serverConfig, state.pagination]);\n\n // Handle page size change - server-side aware\n const handlePageSizeChange = useCallback(async (newSize: number) => {\n if (isServerMode && serverConfig?.onPageChange) {\n await serverConfig.onPageChange(1, newSize); // Reset para página 1\n } else {\n // Client-side: usar handler padrão\n if (state.pagination.onPageSizeChange) {\n state.pagination.onPageSizeChange(newSize);\n }\n }\n }, [isServerMode, serverConfig, state.pagination]);\n\n return (\n <div className={cn(\"space-y-4\", className)}>\n {/* Toolbar — only rendered when there is at least one visible element */}\n <DataTableToolbar\n enableSearch={enableSearch}\n searchPlaceholder={searchPlaceholder}\n searchQuery={searchQuery}\n onSearchChange={handleSearchChange}\n enableFilters={enableFilters}\n filterFields={filterFields}\n advancedFilters={advancedFilters}\n onAdvancedFiltersChange={setAdvancedFilters}\n filterDialogOpen={filterDialogOpen}\n onFilterDialogOpenChange={setFilterDialogOpen}\n onApplyFilters={handleApplyFilters}\n toolbarActions={toolbarActions}\n />\n\n {/* Active Filter Chips */}\n {advancedFilters.length > 0 && (\n <FilterBar\n activeFilters={activeFilterChips}\n onClearAll={handleClearAllFilters}\n />\n )}\n\n {/* Table */}\n <div className=\"rounded-md border overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n {columns.map((column) => (\n <TableHead\n key={String(column.key)}\n className={cn(\n column.sortable && \"select-none p-0\",\n column.sortable && getSortDirection(column.key) && \"text-primary\",\n column.headerClassName\n )}\n style={{ width: column.width }}\n aria-sort={column.sortable ? (getSortDirection(column.key) === \"asc\" ? \"ascending\" : getSortDirection(column.key) === \"desc\" ? \"descending\" : \"none\") : undefined}\n >\n {column.sortable ? (\n <button\n type=\"button\"\n onClick={() => handleSort(column.key)}\n className={cn(\n \"flex h-10 w-full items-center gap-2 px-2 text-left font-semibold whitespace-nowrap cursor-pointer hover:bg-muted/50 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset\",\n column.align === \"right\" && \"justify-end text-right\",\n column.align === \"center\" && \"justify-center text-center\"\n )}\n >\n {column.header}\n {getSortDirection(column.key) && <ArrowUpDown className=\"h-4 w-4 shrink-0\" />}\n </button>\n ) : (\n column.header\n )}\n </TableHead>\n ))}\n </TableRow>\n </TableHeader>\n <TableBody>\n {isLoading ? (\n // SKELETON ROWS - limitar a max 15 para performance\n Array.from({ length: Math.min(state.pagination.pageSize, 15) }).map((_, i) => (\n <TableRow key={`skeleton-${i}`}>\n {columns.map((col, j) => (\n <TableCell key={j} className={col.className}>\n <Skeleton className=\"h-4 w-full\" />\n </TableCell>\n ))}\n </TableRow>\n ))\n ) : processedData.length > 0 ? (\n // DADOS NORMAIS\n processedData.map((row, rowIndex) => (\n <TableRow key={rowIndex}>\n {columns.map((column) => (\n <TableCell\n key={String(column.key)}\n className={cn(\n column.className,\n column.align ? `text-${column.align}` : \"text-left\",\n column.onCellClick && \"cursor-pointer hover:text-primary\"\n )}\n onClick={column.onCellClick\n ? () => column.onCellClick!(row[column.key], row, rowIndex)\n : undefined}\n >\n {column.render\n ? column.render(row[column.key], row, rowIndex)\n : (row[column.key] as React.ReactNode)}\n </TableCell>\n ))}\n </TableRow>\n ))\n ) : (\n // EMPTY STATE\n <TableRow>\n <TableCell\n colSpan={columns.length}\n className=\"h-64\"\n >\n <DataTableEmptyState\n emptyState={emptyState}\n emptyMessage={emptyMessage}\n hasActiveFilters={advancedFilters.length > 0}\n hasSearch={searchQuery.trim().length > 0}\n onClearFilters={clearSearchAndFilters}\n />\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n\n {/* Pagination */}\n <TablePagination\n currentPage={state.pagination.currentPage}\n totalPages={Math.ceil(state.pagination.totalItems / state.pagination.pageSize)}\n pageSize={state.pagination.pageSize}\n totalItems={state.pagination.totalItems}\n onPageChange={handlePageChange}\n onPageSizeChange={handlePageSizeChange}\n pageSizeOptions={pageSizeOptions}\n />\n </div>\n );\n}\n"],"names":["DataTable","data","columns","searchPlaceholder","searchableColumns","enableSearch","filterFields","enableFilters","initialFilters","pageSizeOptions","initialPageSize","toolbarActions","serverConfig","isLoading","emptyState","emptyMessage","className","isServerMode","processedData","state","handlers","getSortDirection","useDataTable","defaultSearchColumn","_a","c","_b","searchQuery","handleSearchChange","advancedFilters","setAdvancedFilters","filterDialogOpen","setFilterDialogOpen","activeFilterChips","handleApplyFilters","handleClearAllFilters","clearSearchAndFilters","useDataTableFilters","handleSort","useCallback","column","currentSort","newDirection","newSortConfig","handlePageChange","page","handlePageSizeChange","newSize","cn","jsx","DataTableToolbar","FilterBar","Table","TableHeader","TableRow","TableHead","jsxs","ArrowUpDown","TableBody","_","i","col","j","TableCell","Skeleton","row","rowIndex","DataTableEmptyState","TablePagination"],"mappings":"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"}
|