From 4e966d9126b4c3dd8a5e0508fe7a504fe6a82847 Mon Sep 17 00:00:00 2001 From: swve Date: Sun, 13 Nov 2022 19:50:08 +0100 Subject: [PATCH] feat: save element content in DB --- front/components/editor/Editor.tsx | 23 +++++++++--- front/components/editor/EditorWithOptions.tsx | 21 +++++++---- .../[courseid]/element/[elementid]/edit.tsx | 37 +++++++++++++++---- front/services/courses/elements.ts | 32 ++++++++++++++++ 4 files changed, 92 insertions(+), 21 deletions(-) diff --git a/front/components/editor/Editor.tsx b/front/components/editor/Editor.tsx index 2be56686..d501ea25 100644 --- a/front/components/editor/Editor.tsx +++ b/front/components/editor/Editor.tsx @@ -2,11 +2,15 @@ import { default as React, useEffect, useRef } from "react"; import * as Y from "yjs"; import { WebrtcProvider } from "y-webrtc"; import EditorWithOptions from "./EditorWithOptions"; -import { IndexeddbPersistence } from 'y-indexeddb' +import { IndexeddbPersistence } from "y-indexeddb"; +import { updateElement } from "../../services/courses/elements"; -// tools +interface EditorProps { + content: string; + element: any; +} -function Editor() { +function Editor(props: EditorProps) { // A new Y document const ydoc = new Y.Doc(); const [providerState, setProviderState] = React.useState({}); @@ -14,19 +18,26 @@ function Editor() { const [isLoading, setIsLoading] = React.useState(true); function createRTCProvider() { - const provider = new WebrtcProvider("learnhouse-1", ydoc); - + const provider = new WebrtcProvider(props.element.element_id, ydoc); + setYdocState(ydoc); setProviderState(provider); setIsLoading(false); } + async function setContent(content: any) { + let element = props.element; + element.content = content.content; + const res = await updateElement(element, element.element_id); + + } + if (isLoading) { createRTCProvider(); } else { return (
- +
); } diff --git a/front/components/editor/EditorWithOptions.tsx b/front/components/editor/EditorWithOptions.tsx index b79b013c..ca57ec87 100644 --- a/front/components/editor/EditorWithOptions.tsx +++ b/front/components/editor/EditorWithOptions.tsx @@ -5,10 +5,16 @@ import Collaboration from "@tiptap/extension-collaboration"; import CollaborationCursor from "@tiptap/extension-collaboration-cursor"; import { AuthContext } from "../security/AuthProvider"; +interface EditorWithOptionsProps { + content: string; + ydoc: any; + provider: any; + setContent: (content: string) => void; +} -function EditorWithOptions(props: any) { +function EditorWithOptions(props: EditorWithOptionsProps) { const auth: any = React.useContext(AuthContext); - + const MenuBar = ({ editor }: any) => { if (!editor) { return null; @@ -109,12 +115,11 @@ function EditorWithOptions(props: any) { ); }; - const editor = useEditor({ + const editor : any = useEditor({ extensions: [ StarterKit.configure({ // The Collaboration extension comes with its own history handling history: false, - }), // Register the document with Tiptap Collaboration.configure({ @@ -129,14 +134,14 @@ function EditorWithOptions(props: any) { }, }), ], - - content: "

Hello World!

", - }); - + content: props.content, + }); return (
+ File +

diff --git a/front/pages/org/[orgslug]/course/[courseid]/element/[elementid]/edit.tsx b/front/pages/org/[orgslug]/course/[courseid]/element/[elementid]/edit.tsx index 7e1e1ddb..6396d77c 100644 --- a/front/pages/org/[orgslug]/course/[courseid]/element/[elementid]/edit.tsx +++ b/front/pages/org/[orgslug]/course/[courseid]/element/[elementid]/edit.tsx @@ -3,22 +3,45 @@ import { default as React, useEffect, useRef } from "react"; import Layout from "../../../../../../../components/ui/Layout"; import { Title } from "../../../../../../../components/ui/styles/Title"; import dynamic from "next/dynamic"; -import { AuthContext } from "../../../../../../../components/security/AuthProvider"; +import { useRouter } from "next/router"; +import { getElement } from "../../../../../../../services/courses/elements"; -const Editor = dynamic(() => import("../../../../../../../components/editor/editor"), { +// Workarkound (Next.js SSR doesn't support tip tap editor) + +const Editor : any = dynamic(() => import("../../../../../../../components/editor/editor"), { ssr: false, }); -// tools - function EditElement() { - - + const router = useRouter(); + const { elementid } = router.query; + const [element, setElement] = React.useState({}); + const [isLoading, setIsLoading] = React.useState(true); + + async function fetchElementData() { + const element = await getElement("element_" + elementid); + setElement(element); + setIsLoading(false); + } + + React.useEffect(() => { + if (router.isReady) { + fetchElementData(); + } + return () => {}; + }, [router.isReady]); + return ( Edit Page
- + {isLoading ? ( +
Loading...
+ ) : ( +
+ +
+ )}
); } diff --git a/front/services/courses/elements.ts b/front/services/courses/elements.ts index 2974e308..e0228b20 100644 --- a/front/services/courses/elements.ts +++ b/front/services/courses/elements.ts @@ -23,5 +23,37 @@ export async function createElement(data: any, chapter_id: any) { console.log("result", result); + return result; + } + + export async function getElement(element_id: any) { + const requestOptions: any = { + method: "GET", + redirect: "follow", + credentials: "include", + }; + + const result: any = await fetch(`${getAPIUrl()}elements/${element_id}`, requestOptions) + .then((result) => result.json()) + .catch((error) => console.log("error", error)); + + return result; + } + + export async function updateElement(data: any, element_id: any) { + const HeadersConfig = new Headers({ "Content-Type": "application/json" }); + + const requestOptions: any = { + method: "PUT", + headers: HeadersConfig, + redirect: "follow", + credentials: "include", + body: JSON.stringify(data), + }; + + const result: any = await fetch(`${getAPIUrl()}elements/${element_id}`, requestOptions) + .then((result) => result.json()) + .catch((error) => console.log("error", error)); + return result; } \ No newline at end of file