From 2f563e1bfbbbf41041d7eb80e224f23005a1a86d Mon Sep 17 00:00:00 2001 From: enes Date: Thu, 7 Nov 2024 18:05:19 +0100 Subject: [PATCH] feat(blog): initial editing --- src/components/Inputs.tsx | 2 +- src/pages/write/index.tsx | 75 +++++++++++++++++++++++++++++---------- 2 files changed, 57 insertions(+), 20 deletions(-) diff --git a/src/components/Inputs.tsx b/src/components/Inputs.tsx index 036e538..38d48af 100644 --- a/src/components/Inputs.tsx +++ b/src/components/Inputs.tsx @@ -167,7 +167,7 @@ type MenuBarProps = { editor: Editor } -const MenuBar = ({ editor }: MenuBarProps) => { +export const MenuBar = ({ editor }: MenuBarProps) => { const setLink = () => { // Prompt the user to enter a URL let url = prompt('URL') diff --git a/src/pages/write/index.tsx b/src/pages/write/index.tsx index a525509..0cb1ebd 100644 --- a/src/pages/write/index.tsx +++ b/src/pages/write/index.tsx @@ -1,28 +1,57 @@ import { useState } from 'react' -import { Form, useActionData, useNavigation } from 'react-router-dom' +import { + Form, + useActionData, + useLoaderData, + useNavigation +} from 'react-router-dom' import { CheckboxFieldUncontrolled, - InputField, - InputFieldUncontrolled + InputError, + InputFieldUncontrolled, + MenuBar } from '../../components/Inputs' import { ProfileSection } from '../../components/ProfileSection' import { useAppSelector } from '../../hooks' -import { BlogFormErrors } from 'types' +import { BlogFormErrors, BlogPageLoaderResult } from 'types' import '../../styles/innerPage.css' import '../../styles/styles.css' import '../../styles/write.css' import { LoadingSpinner } from 'components/LoadingSpinner' +import { marked } from 'marked' +import DOMPurify from 'dompurify' +import { EditorContent, useEditor } from '@tiptap/react' +import StarterKit from '@tiptap/starter-kit' +import Link from '@tiptap/extension-link' +import Image from '@tiptap/extension-image' export const WritePage = () => { const userState = useAppSelector((state) => state.user) + const data = useLoaderData() as BlogPageLoaderResult const formErrors = useActionData() as BlogFormErrors const navigation = useNavigation() - const title = 'Submit a blog post' - const [content, setContent] = useState('') - const handleContentChange = (_: string, value: string) => { - setContent(value) - } + const blog = data?.blog + const title = data?.blog ? 'Edit blog post' : 'Submit a blog post' + const html = marked.parse(blog?.content || '', { async: false }) + const sanitized = DOMPurify.sanitize(html) + const [content, setContent] = useState(sanitized) + const editor = useEditor({ + content: content, + extensions: [ + StarterKit, + Link, + Image.configure({ + inline: true, + HTMLAttributes: { + class: 'IBMSMSMBSSPostImg' + } + }) + ], + onUpdate: ({ editor }) => { + setContent(editor.getHTML()) + } + }) return (
@@ -43,28 +72,34 @@ export const WritePage = () => { - - + {editor && ( +
+ +
+ + +
+ {typeof formErrors?.content !== 'undefined' && ( + + )} + +
+ )} { description='Separate each tag with a comma. (Example: tag1, tag2, tag3)' placeholder='Tags' name='tags' + defaultValue={blog?.tTags?.join(', ')} error={formErrors?.tags} />