You can customize your video embed using markdown or HTML. For example, paste iframe
embeds from YouTube or Vimeo, or use video tags for direct video files.
@@ -239,9 +236,7 @@ const EditPublishedCombinedResourceForm = ({ event }) => {
diff --git a/src/components/forms/course/embedded/EmbeddedDocumentForm.js b/src/components/forms/course/embedded/EmbeddedDocumentForm.js
index ffc6e05..53bbc26 100644
--- a/src/components/forms/course/embedded/EmbeddedDocumentForm.js
+++ b/src/components/forms/course/embedded/EmbeddedDocumentForm.js
@@ -1,21 +1,20 @@
import React, { useState, useEffect, useCallback } from 'react';
+import axios from 'axios';
import { InputText } from 'primereact/inputtext';
+import { InputTextarea } from 'primereact/inputtextarea';
import { InputNumber } from 'primereact/inputnumber';
import { InputSwitch } from 'primereact/inputswitch';
+import { Calendar } from 'primereact/calendar';
import GenericButton from '@/components/buttons/GenericButton';
+import { useRouter } from 'next/router';
import { useSession } from 'next-auth/react';
import { useToast } from '@/hooks/useToast';
import { useNDKContext } from '@/context/NDKContext';
import { NDKEvent } from '@nostr-dev-kit/ndk';
-import dynamic from 'next/dynamic';
-import { useEncryptContent } from '@/hooks/encryption/useEncryptContent';
-
-const MDEditor = dynamic(() => import('@uiw/react-md-editor'), {
- ssr: false,
-});
import 'primeicons/primeicons.css';
-import { Tooltip } from 'primereact/tooltip';
import 'primereact/resources/primereact.min.css';
+import { useEncryptContent } from '@/hooks/encryption/useEncryptContent';
+import MarkdownEditor from '@/components/markdown/MarkdownEditor';
const EmbeddedDocumentForm = ({ draft = null, isPublished = false, onSave, isPaid }) => {
const [title, setTitle] = useState(draft?.title || '');
@@ -183,9 +182,7 @@ const EmbeddedDocumentForm = ({ draft = null, isPublished = false, onSave, isPai
@@ -219,7 +216,6 @@ const EmbeddedDocumentForm = ({ draft = null, isPublished = false, onSave, isPai
-
{topics.map((topic, index) => (
diff --git a/src/components/forms/document/DocumentForm.js b/src/components/forms/document/DocumentForm.js
index 8ffea2e..f48ea41 100644
--- a/src/components/forms/document/DocumentForm.js
+++ b/src/components/forms/document/DocumentForm.js
@@ -8,14 +8,10 @@ import GenericButton from '@/components/buttons/GenericButton';
import { useRouter } from 'next/router';
import { useSession } from 'next-auth/react';
import { useToast } from '@/hooks/useToast';
-import dynamic from 'next/dynamic';
-import 'primeicons/primeicons.css';
import { Tooltip } from 'primereact/tooltip';
+import 'primeicons/primeicons.css';
import 'primereact/resources/primereact.min.css';
-
-const MDEditor = dynamic(() => import('@uiw/react-md-editor'), {
- ssr: false,
-});
+import MarkdownEditor from '@/components/markdown/MarkdownEditor';
const DocumentForm = () => {
const [title, setTitle] = useState('');
@@ -149,9 +145,11 @@ const DocumentForm = () => {
diff --git a/src/components/forms/document/EditDraftDocumentForm.js b/src/components/forms/document/EditDraftDocumentForm.js
index 67de952..bcc1f67 100644
--- a/src/components/forms/document/EditDraftDocumentForm.js
+++ b/src/components/forms/document/EditDraftDocumentForm.js
@@ -8,10 +8,10 @@ import GenericButton from '@/components/buttons/GenericButton';
import { useRouter } from 'next/router';
import { useSession } from 'next-auth/react';
import { useToast } from '@/hooks/useToast';
-import dynamic from 'next/dynamic';
+import 'primeicons/primeicons.css';
import { Tooltip } from 'primereact/tooltip';
-
-const MDEditor = dynamic(() => import('@uiw/react-md-editor'), { ssr: false });
+import 'primereact/resources/primereact.min.css';
+import MarkdownEditor from '@/components/markdown/MarkdownEditor';
const EditDraftDocumentForm = ({ draft }) => {
const [title, setTitle] = useState(draft?.title || '');
@@ -143,9 +143,7 @@ const EditDraftDocumentForm = ({ draft }) => {
diff --git a/src/components/forms/document/EditPublishedDocumentForm.js b/src/components/forms/document/EditPublishedDocumentForm.js
index 7a64b93..46fb0f9 100644
--- a/src/components/forms/document/EditPublishedDocumentForm.js
+++ b/src/components/forms/document/EditPublishedDocumentForm.js
@@ -1,21 +1,21 @@
import React, { useState, useEffect, useCallback } from 'react';
import axios from 'axios';
-import { useRouter } from 'next/router';
-import { useToast } from '@/hooks/useToast';
-import { useSession } from 'next-auth/react';
-import { useNDKContext } from '@/context/NDKContext';
-import { useEncryptContent } from '@/hooks/encryption/useEncryptContent';
-import GenericButton from '@/components/buttons/GenericButton';
-import { NDKEvent } from '@nostr-dev-kit/ndk';
-import { validateEvent } from '@/utils/nostr';
import { InputText } from 'primereact/inputtext';
import { InputTextarea } from 'primereact/inputtextarea';
import { InputNumber } from 'primereact/inputnumber';
import { InputSwitch } from 'primereact/inputswitch';
+import GenericButton from '@/components/buttons/GenericButton';
+import { useRouter } from 'next/router';
+import { useSession } from 'next-auth/react';
+import { useToast } from '@/hooks/useToast';
+import { useNDKContext } from '@/context/NDKContext';
+import { NDKEvent } from '@nostr-dev-kit/ndk';
+import { validateEvent } from '@/utils/nostr';
+import { useEncryptContent } from '@/hooks/encryption/useEncryptContent';
+import 'primeicons/primeicons.css';
import { Tooltip } from 'primereact/tooltip';
-import dynamic from 'next/dynamic';
-
-const MDEditor = dynamic(() => import('@uiw/react-md-editor'), { ssr: false });
+import 'primereact/resources/primereact.min.css';
+import MarkdownEditor from '@/components/markdown/MarkdownEditor';
const EditPublishedDocumentForm = ({ event }) => {
const router = useRouter();
@@ -198,9 +198,7 @@ const EditPublishedDocumentForm = ({ event }) => {
diff --git a/src/components/forms/video/EditPublishedVideoForm.js b/src/components/forms/video/EditPublishedVideoForm.js
index 6eac234..5bbc48c 100644
--- a/src/components/forms/video/EditPublishedVideoForm.js
+++ b/src/components/forms/video/EditPublishedVideoForm.js
@@ -1,23 +1,22 @@
import React, { useState, useEffect, useCallback } from 'react';
import axios from 'axios';
-import { useRouter } from 'next/router';
-import { useToast } from '@/hooks/useToast';
-import { useSession } from 'next-auth/react';
-import { useNDKContext } from '@/context/NDKContext';
-import GenericButton from '@/components/buttons/GenericButton';
-import { NDKEvent } from '@nostr-dev-kit/ndk';
-import { validateEvent } from '@/utils/nostr';
import { InputText } from 'primereact/inputtext';
import { InputTextarea } from 'primereact/inputtextarea';
import { InputNumber } from 'primereact/inputnumber';
import { InputSwitch } from 'primereact/inputswitch';
+import GenericButton from '@/components/buttons/GenericButton';
+import { useRouter } from 'next/router';
+import { useSession } from 'next-auth/react';
+import { useToast } from '@/hooks/useToast';
+import { useNDKContext } from '@/context/NDKContext';
+import { NDKEvent } from '@nostr-dev-kit/ndk';
+import { validateEvent } from '@/utils/nostr';
import { useEncryptContent } from '@/hooks/encryption/useEncryptContent';
import MoreInfo from '@/components/MoreInfo';
-import dynamic from 'next/dynamic';
-
-const MDEditor = dynamic(() => import('@uiw/react-md-editor'), {
- ssr: false,
-});
+import 'primeicons/primeicons.css';
+import { Tooltip } from 'primereact/tooltip';
+import 'primereact/resources/primereact.min.css';
+import MarkdownEditor from '@/components/markdown/MarkdownEditor';
const EditPublishedVideoForm = ({ event }) => {
const router = useRouter();
@@ -190,9 +189,7 @@ const EditPublishedVideoForm = ({ event }) => {
Video Embed
-
-
-
+
You can customize your video embed using markdown or HTML. For example, paste iframe
embeds from YouTube or Vimeo, or use video tags for direct video files.
diff --git a/src/components/markdown/MarkdownEditor.js b/src/components/markdown/MarkdownEditor.js
new file mode 100644
index 0000000..5950860
--- /dev/null
+++ b/src/components/markdown/MarkdownEditor.js
@@ -0,0 +1,128 @@
+import React from 'react';
+import dynamic from 'next/dynamic';
+import '@uiw/react-md-editor/markdown-editor.css';
+import '@uiw/react-markdown-preview/markdown.css';
+import 'github-markdown-css/github-markdown-dark.css';
+
+// Custom theme for MDEditor
+const mdEditorDarkTheme = {
+ markdown: '#fff',
+ markdownH1: '#fff',
+ markdownH2: '#fff',
+ markdownH3: '#fff',
+ markdownH4: '#fff',
+ markdownH5: '#fff',
+ markdownH6: '#fff',
+ markdownParagraph: '#fff',
+ markdownLink: '#58a6ff',
+ markdownCode: '#fff',
+ markdownList: '#fff',
+ markdownBlockquote: '#fff',
+ markdownTable: '#fff',
+};
+
+// Dynamically import MDEditor with custom theming
+const MDEditor = dynamic(() => import('@uiw/react-md-editor').then(mod => {
+ // Override the module's default theme
+ if (mod.default) {
+ mod.default.Markdown = {
+ ...mod.default.Markdown,
+ ...mdEditorDarkTheme
+ };
+ }
+ return mod;
+}), {
+ ssr: false,
+});
+
+/**
+ * A reusable markdown editor component with proper dark mode styling
+ *
+ * @param {Object} props
+ * @param {string} props.value - The markdown content
+ * @param {Function} props.onChange - Callback function when content changes
+ * @param {number} props.height - Height of the editor (default: 300)
+ * @param {string} props.placeholder - Placeholder text for the editor
+ * @param {string} props.preview - Preview mode ('edit', 'preview', 'live') (default: 'edit')
+ * @param {string} props.className - Additional class names
+ * @returns {JSX.Element}
+ */
+const MarkdownEditor = ({
+ value,
+ onChange,
+ height = 300,
+ placeholder = "Write your content here...",
+ preview = "edit",
+ className = "",
+ ...props
+}) => {
+ return (
+
+
+
+
+ );
+};
+
+export default MarkdownEditor;
\ No newline at end of file