mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-06-05 00:32:03 +00:00
implement generic markdown input form for content
This commit is contained in:
parent
027bf28e2f
commit
7a805f0988
@ -1,19 +1,17 @@
|
|||||||
import React, { useState, useEffect, useCallback } from 'react';
|
import React, { useState, useEffect, useCallback } from 'react';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { useRouter } from 'next/router';
|
|
||||||
import { InputText } from 'primereact/inputtext';
|
import { InputText } from 'primereact/inputtext';
|
||||||
import { InputTextarea } from 'primereact/inputtextarea';
|
import { InputTextarea } from 'primereact/inputtextarea';
|
||||||
import { InputNumber } from 'primereact/inputnumber';
|
import { InputNumber } from 'primereact/inputnumber';
|
||||||
import { InputSwitch } from 'primereact/inputswitch';
|
import { InputSwitch } from 'primereact/inputswitch';
|
||||||
import GenericButton from '@/components/buttons/GenericButton';
|
import GenericButton from '@/components/buttons/GenericButton';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useRouter } from 'next/router';
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
import dynamic from 'next/dynamic';
|
import { useToast } from '@/hooks/useToast';
|
||||||
import { Tooltip } from 'primereact/tooltip';
|
|
||||||
import 'primeicons/primeicons.css';
|
import 'primeicons/primeicons.css';
|
||||||
|
import { Tooltip } from 'primereact/tooltip';
|
||||||
import 'primereact/resources/primereact.min.css';
|
import 'primereact/resources/primereact.min.css';
|
||||||
|
import MarkdownEditor from '@/components/markdown/MarkdownEditor';
|
||||||
const MDEditor = dynamic(() => import('@uiw/react-md-editor'), { ssr: false });
|
|
||||||
|
|
||||||
const CDN_ENDPOINT = process.env.NEXT_PUBLIC_CDN_ENDPOINT;
|
const CDN_ENDPOINT = process.env.NEXT_PUBLIC_CDN_ENDPOINT;
|
||||||
|
|
||||||
@ -199,9 +197,7 @@ const CombinedResourceForm = () => {
|
|||||||
|
|
||||||
<div className="p-inputgroup flex-1 flex-col mt-4">
|
<div className="p-inputgroup flex-1 flex-col mt-4">
|
||||||
<span>Content</span>
|
<span>Content</span>
|
||||||
<div data-color-mode="dark">
|
<MarkdownEditor value={content} onChange={handleContentChange} height={350} />
|
||||||
<MDEditor value={content} onChange={handleContentChange} height={350} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-8 flex-col w-full">
|
<div className="mt-8 flex-col w-full">
|
||||||
|
@ -1,19 +1,17 @@
|
|||||||
import React, { useState, useEffect, useCallback } from 'react';
|
import React, { useState, useEffect, useCallback } from 'react';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { useRouter } from 'next/router';
|
|
||||||
import { InputText } from 'primereact/inputtext';
|
import { InputText } from 'primereact/inputtext';
|
||||||
import { InputTextarea } from 'primereact/inputtextarea';
|
import { InputTextarea } from 'primereact/inputtextarea';
|
||||||
import { InputNumber } from 'primereact/inputnumber';
|
import { InputNumber } from 'primereact/inputnumber';
|
||||||
import { InputSwitch } from 'primereact/inputswitch';
|
import { InputSwitch } from 'primereact/inputswitch';
|
||||||
import GenericButton from '@/components/buttons/GenericButton';
|
import GenericButton from '@/components/buttons/GenericButton';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useRouter } from 'next/router';
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
import dynamic from 'next/dynamic';
|
import { useToast } from '@/hooks/useToast';
|
||||||
import { Tooltip } from 'primereact/tooltip';
|
|
||||||
import 'primeicons/primeicons.css';
|
import 'primeicons/primeicons.css';
|
||||||
|
import { Tooltip } from 'primereact/tooltip';
|
||||||
import 'primereact/resources/primereact.min.css';
|
import 'primereact/resources/primereact.min.css';
|
||||||
|
import MarkdownEditor from '@/components/markdown/MarkdownEditor';
|
||||||
const MDEditor = dynamic(() => import('@uiw/react-md-editor'), { ssr: false });
|
|
||||||
|
|
||||||
const CDN_ENDPOINT = process.env.NEXT_PUBLIC_CDN_ENDPOINT;
|
const CDN_ENDPOINT = process.env.NEXT_PUBLIC_CDN_ENDPOINT;
|
||||||
|
|
||||||
@ -242,9 +240,7 @@ const EditDraftCombinedResourceForm = ({ draft }) => {
|
|||||||
|
|
||||||
<div className="p-inputgroup flex-1 flex-col mt-4">
|
<div className="p-inputgroup flex-1 flex-col mt-4">
|
||||||
<span>Content</span>
|
<span>Content</span>
|
||||||
<div data-color-mode="dark">
|
<MarkdownEditor value={content} onChange={handleContentChange} height={350} />
|
||||||
<MDEditor value={content} onChange={handleContentChange} height={350} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-8 flex-col w-full">
|
<div className="mt-8 flex-col w-full">
|
||||||
|
@ -1,23 +1,22 @@
|
|||||||
import React, { useState, useEffect, useCallback } from 'react';
|
import React, { useState, useEffect, useCallback } from 'react';
|
||||||
import axios from 'axios';
|
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 { InputText } from 'primereact/inputtext';
|
||||||
import { InputTextarea } from 'primereact/inputtextarea';
|
import { InputTextarea } from 'primereact/inputtextarea';
|
||||||
import { InputNumber } from 'primereact/inputnumber';
|
import { InputNumber } from 'primereact/inputnumber';
|
||||||
import { InputSwitch } from 'primereact/inputswitch';
|
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 { useEncryptContent } from '@/hooks/encryption/useEncryptContent';
|
||||||
import MoreInfo from '@/components/MoreInfo';
|
import MoreInfo from '@/components/MoreInfo';
|
||||||
import dynamic from 'next/dynamic';
|
import 'primeicons/primeicons.css';
|
||||||
|
import { Tooltip } from 'primereact/tooltip';
|
||||||
const MDEditor = dynamic(() => import('@uiw/react-md-editor'), {
|
import 'primereact/resources/primereact.min.css';
|
||||||
ssr: false,
|
import MarkdownEditor from '@/components/markdown/MarkdownEditor';
|
||||||
});
|
|
||||||
|
|
||||||
const EditPublishedCombinedResourceForm = ({ event }) => {
|
const EditPublishedCombinedResourceForm = ({ event }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -220,9 +219,7 @@ const EditPublishedCombinedResourceForm = ({ event }) => {
|
|||||||
|
|
||||||
<div className="p-inputgroup flex-1 flex-col mt-4">
|
<div className="p-inputgroup flex-1 flex-col mt-4">
|
||||||
<span>Video Embed</span>
|
<span>Video Embed</span>
|
||||||
<div data-color-mode="dark">
|
<MarkdownEditor value={videoEmbed} onChange={handleVideoEmbedChange} height={250} />
|
||||||
<MDEditor value={videoEmbed} onChange={handleVideoEmbedChange} height={250} />
|
|
||||||
</div>
|
|
||||||
<small className="text-gray-400 mt-2">
|
<small className="text-gray-400 mt-2">
|
||||||
You can customize your video embed using markdown or HTML. For example, paste iframe
|
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.
|
embeds from YouTube or Vimeo, or use video tags for direct video files.
|
||||||
@ -239,9 +236,7 @@ const EditPublishedCombinedResourceForm = ({ event }) => {
|
|||||||
|
|
||||||
<div className="p-inputgroup flex-1 flex-col mt-4">
|
<div className="p-inputgroup flex-1 flex-col mt-4">
|
||||||
<span>Content</span>
|
<span>Content</span>
|
||||||
<div data-color-mode="dark">
|
<MarkdownEditor value={content} onChange={handleContentChange} height={350} />
|
||||||
<MDEditor value={content} onChange={handleContentChange} height={350} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-8 flex-col w-full">
|
<div className="mt-8 flex-col w-full">
|
||||||
|
@ -1,21 +1,20 @@
|
|||||||
import React, { useState, useEffect, useCallback } from 'react';
|
import React, { useState, useEffect, useCallback } from 'react';
|
||||||
|
import axios from 'axios';
|
||||||
import { InputText } from 'primereact/inputtext';
|
import { InputText } from 'primereact/inputtext';
|
||||||
|
import { InputTextarea } from 'primereact/inputtextarea';
|
||||||
import { InputNumber } from 'primereact/inputnumber';
|
import { InputNumber } from 'primereact/inputnumber';
|
||||||
import { InputSwitch } from 'primereact/inputswitch';
|
import { InputSwitch } from 'primereact/inputswitch';
|
||||||
|
import { Calendar } from 'primereact/calendar';
|
||||||
import GenericButton from '@/components/buttons/GenericButton';
|
import GenericButton from '@/components/buttons/GenericButton';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
import { useNDKContext } from '@/context/NDKContext';
|
import { useNDKContext } from '@/context/NDKContext';
|
||||||
import { NDKEvent } from '@nostr-dev-kit/ndk';
|
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 'primeicons/primeicons.css';
|
||||||
import { Tooltip } from 'primereact/tooltip';
|
|
||||||
import 'primereact/resources/primereact.min.css';
|
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 EmbeddedDocumentForm = ({ draft = null, isPublished = false, onSave, isPaid }) => {
|
||||||
const [title, setTitle] = useState(draft?.title || '');
|
const [title, setTitle] = useState(draft?.title || '');
|
||||||
@ -183,9 +182,7 @@ const EmbeddedDocumentForm = ({ draft = null, isPublished = false, onSave, isPai
|
|||||||
</div>
|
</div>
|
||||||
<div className="p-inputgroup flex-1 flex-col mt-4">
|
<div className="p-inputgroup flex-1 flex-col mt-4">
|
||||||
<span>Content</span>
|
<span>Content</span>
|
||||||
<div data-color-mode="dark">
|
<MarkdownEditor value={content} onChange={handleContentChange} height={350} />
|
||||||
<MDEditor value={content} onChange={handleContentChange} height={350} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-8 flex-col w-full">
|
<div className="mt-8 flex-col w-full">
|
||||||
<span className="pl-1 flex items-center">
|
<span className="pl-1 flex items-center">
|
||||||
@ -219,7 +216,6 @@ const EmbeddedDocumentForm = ({ draft = null, isPublished = false, onSave, isPai
|
|||||||
<div className="w-full flex flex-row items-end justify-end py-2">
|
<div className="w-full flex flex-row items-end justify-end py-2">
|
||||||
<GenericButton icon="pi pi-plus" onClick={addAdditionalLink} />
|
<GenericButton icon="pi pi-plus" onClick={addAdditionalLink} />
|
||||||
</div>
|
</div>
|
||||||
<Tooltip target=".pi-info-circle" />
|
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-8 flex-col w-full">
|
<div className="mt-8 flex-col w-full">
|
||||||
{topics.map((topic, index) => (
|
{topics.map((topic, index) => (
|
||||||
|
@ -8,14 +8,10 @@ import GenericButton from '@/components/buttons/GenericButton';
|
|||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
import dynamic from 'next/dynamic';
|
|
||||||
import 'primeicons/primeicons.css';
|
|
||||||
import { Tooltip } from 'primereact/tooltip';
|
import { Tooltip } from 'primereact/tooltip';
|
||||||
|
import 'primeicons/primeicons.css';
|
||||||
import 'primereact/resources/primereact.min.css';
|
import 'primereact/resources/primereact.min.css';
|
||||||
|
import MarkdownEditor from '@/components/markdown/MarkdownEditor';
|
||||||
const MDEditor = dynamic(() => import('@uiw/react-md-editor'), {
|
|
||||||
ssr: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const DocumentForm = () => {
|
const DocumentForm = () => {
|
||||||
const [title, setTitle] = useState('');
|
const [title, setTitle] = useState('');
|
||||||
@ -149,9 +145,11 @@ const DocumentForm = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="p-inputgroup flex-1 flex-col mt-4">
|
<div className="p-inputgroup flex-1 flex-col mt-4">
|
||||||
<span>Content</span>
|
<span>Content</span>
|
||||||
<div data-color-mode="dark">
|
<MarkdownEditor
|
||||||
<MDEditor value={content} onChange={handleContentChange} height={350} />
|
value={content}
|
||||||
</div>
|
onChange={handleContentChange}
|
||||||
|
height={350}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-8 flex-col w-full">
|
<div className="mt-8 flex-col w-full">
|
||||||
<span className="pl-1 flex items-center">
|
<span className="pl-1 flex items-center">
|
||||||
|
@ -8,10 +8,10 @@ import GenericButton from '@/components/buttons/GenericButton';
|
|||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
import dynamic from 'next/dynamic';
|
import 'primeicons/primeicons.css';
|
||||||
import { Tooltip } from 'primereact/tooltip';
|
import { Tooltip } from 'primereact/tooltip';
|
||||||
|
import 'primereact/resources/primereact.min.css';
|
||||||
const MDEditor = dynamic(() => import('@uiw/react-md-editor'), { ssr: false });
|
import MarkdownEditor from '@/components/markdown/MarkdownEditor';
|
||||||
|
|
||||||
const EditDraftDocumentForm = ({ draft }) => {
|
const EditDraftDocumentForm = ({ draft }) => {
|
||||||
const [title, setTitle] = useState(draft?.title || '');
|
const [title, setTitle] = useState(draft?.title || '');
|
||||||
@ -143,9 +143,7 @@ const EditDraftDocumentForm = ({ draft }) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="p-inputgroup flex-1 flex-col mt-4">
|
<div className="p-inputgroup flex-1 flex-col mt-4">
|
||||||
<span>Content</span>
|
<span>Content</span>
|
||||||
<div data-color-mode="dark">
|
<MarkdownEditor value={content} onChange={handleContentChange} height={350} />
|
||||||
<MDEditor value={content} onChange={handleContentChange} height={350} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-8 flex-col w-full">
|
<div className="mt-8 flex-col w-full">
|
||||||
<span className="pl-1 flex items-center">
|
<span className="pl-1 flex items-center">
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
import React, { useState, useEffect, useCallback } from 'react';
|
import React, { useState, useEffect, useCallback } from 'react';
|
||||||
import axios from 'axios';
|
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 { InputText } from 'primereact/inputtext';
|
||||||
import { InputTextarea } from 'primereact/inputtextarea';
|
import { InputTextarea } from 'primereact/inputtextarea';
|
||||||
import { InputNumber } from 'primereact/inputnumber';
|
import { InputNumber } from 'primereact/inputnumber';
|
||||||
import { InputSwitch } from 'primereact/inputswitch';
|
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 { Tooltip } from 'primereact/tooltip';
|
||||||
import dynamic from 'next/dynamic';
|
import 'primereact/resources/primereact.min.css';
|
||||||
|
import MarkdownEditor from '@/components/markdown/MarkdownEditor';
|
||||||
const MDEditor = dynamic(() => import('@uiw/react-md-editor'), { ssr: false });
|
|
||||||
|
|
||||||
const EditPublishedDocumentForm = ({ event }) => {
|
const EditPublishedDocumentForm = ({ event }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -198,9 +198,7 @@ const EditPublishedDocumentForm = ({ event }) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="p-inputgroup flex-1 flex-col mt-4">
|
<div className="p-inputgroup flex-1 flex-col mt-4">
|
||||||
<span>Content</span>
|
<span>Content</span>
|
||||||
<div data-color-mode="dark">
|
<MarkdownEditor value={content} onChange={handleContentChange} height={350} />
|
||||||
<MDEditor value={content} onChange={handleContentChange} height={350} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-8 flex-col w-full">
|
<div className="mt-8 flex-col w-full">
|
||||||
<span className="pl-1 flex items-center">
|
<span className="pl-1 flex items-center">
|
||||||
|
@ -1,23 +1,22 @@
|
|||||||
import React, { useState, useEffect, useCallback } from 'react';
|
import React, { useState, useEffect, useCallback } from 'react';
|
||||||
import axios from 'axios';
|
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 { InputText } from 'primereact/inputtext';
|
||||||
import { InputTextarea } from 'primereact/inputtextarea';
|
import { InputTextarea } from 'primereact/inputtextarea';
|
||||||
import { InputNumber } from 'primereact/inputnumber';
|
import { InputNumber } from 'primereact/inputnumber';
|
||||||
import { InputSwitch } from 'primereact/inputswitch';
|
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 { useEncryptContent } from '@/hooks/encryption/useEncryptContent';
|
||||||
import MoreInfo from '@/components/MoreInfo';
|
import MoreInfo from '@/components/MoreInfo';
|
||||||
import dynamic from 'next/dynamic';
|
import 'primeicons/primeicons.css';
|
||||||
|
import { Tooltip } from 'primereact/tooltip';
|
||||||
const MDEditor = dynamic(() => import('@uiw/react-md-editor'), {
|
import 'primereact/resources/primereact.min.css';
|
||||||
ssr: false,
|
import MarkdownEditor from '@/components/markdown/MarkdownEditor';
|
||||||
});
|
|
||||||
|
|
||||||
const EditPublishedVideoForm = ({ event }) => {
|
const EditPublishedVideoForm = ({ event }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -190,9 +189,7 @@ const EditPublishedVideoForm = ({ event }) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="p-inputgroup flex-1 flex-col mt-4">
|
<div className="p-inputgroup flex-1 flex-col mt-4">
|
||||||
<span>Video Embed</span>
|
<span>Video Embed</span>
|
||||||
<div data-color-mode="dark">
|
<MarkdownEditor value={videoEmbed} onChange={handleVideoEmbedChange} height={250} />
|
||||||
<MDEditor value={videoEmbed} onChange={handleVideoEmbedChange} height={250} />
|
|
||||||
</div>
|
|
||||||
<small className="text-gray-400 mt-2">
|
<small className="text-gray-400 mt-2">
|
||||||
You can customize your video embed using markdown or HTML. For example, paste iframe
|
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.
|
embeds from YouTube or Vimeo, or use video tags for direct video files.
|
||||||
|
128
src/components/markdown/MarkdownEditor.js
Normal file
128
src/components/markdown/MarkdownEditor.js
Normal file
@ -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 (
|
||||||
|
<div data-color-mode="dark" className={`w-full ${className}`} style={{ colorScheme: 'dark' }}>
|
||||||
|
<MDEditor
|
||||||
|
value={value}
|
||||||
|
onChange={onChange}
|
||||||
|
height={height}
|
||||||
|
preview={preview}
|
||||||
|
className="md-editor-dark"
|
||||||
|
textareaProps={{
|
||||||
|
placeholder,
|
||||||
|
style: { color: "white" }
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
<style jsx global>{`
|
||||||
|
/* Force all text to white in editor */
|
||||||
|
.w-md-editor * {
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset preview text color */
|
||||||
|
.w-md-editor-preview * {
|
||||||
|
color: #c9d1d9 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Editor backgrounds */
|
||||||
|
.md-editor-dark {
|
||||||
|
background-color: #0d1117 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-md-editor-text-input {
|
||||||
|
caret-color: white !important;
|
||||||
|
-webkit-text-fill-color: white !important;
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-md-editor-toolbar {
|
||||||
|
background-color: #161b22 !important;
|
||||||
|
border-bottom: 1px solid #30363d !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Preview styling */
|
||||||
|
.w-md-editor-preview {
|
||||||
|
background-color: #0d1117 !important;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make code blocks maintain their styling */
|
||||||
|
.w-md-editor-preview pre {
|
||||||
|
background-color: #1e1e1e !important;
|
||||||
|
color: #d4d4d4 !important;
|
||||||
|
padding: 1em !important;
|
||||||
|
border-radius: 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-md-editor-preview code {
|
||||||
|
font-family: 'Consolas', 'Monaco', 'Andale Mono', 'Ubuntu Mono', monospace !important;
|
||||||
|
color: #d4d4d4 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Force anything with text-rendering to be white */
|
||||||
|
[style*="text-rendering"] {
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MarkdownEditor;
|
Loading…
x
Reference in New Issue
Block a user