@@ -274,11 +283,12 @@ export const MediaGridSelector = ({
const selectedDoc = mediaItems.find(m => m.$id === value);
// Si aún no está en la lista (cargando), mostramos loader genérico
if (!selectedDoc && mediaItems.length > 0) return null;
- const fileIdToRender = selectedDoc ? selectedDoc.file_id : value;
- const bucketIdToRender = selectedDoc ? selectedDoc.bucket_id : undefined;
-
- return (
-

+ const isVideo = selectedDoc?.tipo === 'video';
+ const fileUrl = getAppwriteImageUrl(fileIdToRender, bucketIdToRender, 800, 450, isVideo);
+ return isVideo ? (
+
+ ) : (
+

);
})()}
diff --git a/src/components/dashboard/RichTextEditor.tsx b/src/components/dashboard/RichTextEditor.tsx
index b4b6765..750c458 100644
--- a/src/components/dashboard/RichTextEditor.tsx
+++ b/src/components/dashboard/RichTextEditor.tsx
@@ -1,6 +1,7 @@
'use client';
import { useEditor, EditorContent } from '@tiptap/react';
+import { Node, mergeAttributes } from '@tiptap/core';
import StarterKit from '@tiptap/starter-kit';
import Underline from '@tiptap/extension-underline';
import Link from '@tiptap/extension-link';
@@ -26,6 +27,29 @@ interface RichTextEditorProps {
label: string;
}
+const VideoNode = Node.create({
+ name: 'videoNode',
+ group: 'block',
+ selectable: true,
+ draggable: true,
+ atom: true,
+
+ addAttributes() {
+ return {
+ src: { default: null },
+ controls: { default: 'true' },
+ }
+ },
+
+ parseHTML() {
+ return [{ tag: 'video' }]
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return ['video', mergeAttributes(HTMLAttributes, { class: 'w-full aspect-video rounded-xl shadow-lg my-6', controls: 'true', preload: 'metadata' })]
+ },
+});
+
const MenuBar = ({ editor }: { editor: any }) => {
const [isMediaModalOpen, setIsMediaModalOpen] = useState(false);
@@ -49,9 +73,13 @@ const MenuBar = ({ editor }: { editor: any }) => {
}
};
- const handleMediaInsert = (fileId: string, url?: string) => {
+ const handleMediaInsert = (fileId: string, url?: string, tipo?: string) => {
if (url) {
- editor.chain().focus().setImage({ src: url }).run();
+ if (tipo === 'video') {
+ editor.chain().focus().insertContent({ type: 'videoNode', attrs: { src: url } }).run();
+ } else {
+ editor.chain().focus().setImage({ src: url }).run();
+ }
}
setIsMediaModalOpen(false);
};
@@ -232,6 +260,7 @@ export const RichTextEditor = ({ value, onChange, label }: RichTextEditorProps)
class: 'rounded-xl shadow-lg max-w-full h-auto object-cover my-6'
}
}),
+ VideoNode,
Youtube.configure({
controls: true,
HTMLAttributes: {