From 2aa9f0462fef7fcc3294efe943c1ff88312d3178 Mon Sep 17 00:00:00 2001 From: Guillaume Dorce Date: Sun, 4 Jun 2023 19:03:10 +0200 Subject: [PATCH] create EditorRender, fix data init in column component, render on home --- src/components/EditorRender.tsx | 111 +++++++++++++++++++++++++++++++ src/components/ReactEditor.tsx | 6 +- src/pages/index.tsx | 23 ++++++- src/pages/test/[slug].tsx | 108 ++---------------------------- src/styles/editor.css | 7 ++ src/utils/editor-tools/column.ts | 9 ++- src/utils/pb.ts | 30 +++++++++ 7 files changed, 184 insertions(+), 110 deletions(-) create mode 100644 src/components/EditorRender.tsx create mode 100644 src/styles/editor.css diff --git a/src/components/EditorRender.tsx b/src/components/EditorRender.tsx new file mode 100644 index 0000000..f935427 --- /dev/null +++ b/src/components/EditorRender.tsx @@ -0,0 +1,111 @@ +import { PagesRecord } from "@/@types/pocketbase-types"; + +function parseBoldText(text: string) { + const parts = text.split(/(.*?<\/b>)/g); + const result = []; + for (let i = 0; i < parts.length; i++) { + if (parts[i]?.startsWith('')) { + result.push({parts[i]?.slice(3, -4)}) + } else { + result.push(parts[i]) + } + } + return result; +} + +function Paragraph({ text }: { text: string }) { + return

{parseBoldText(text)}

+} + +function Heading({ text, level }: { text: string, level: number }) { + switch (level) { + case 1: + return ( + <> +

{text}

+
+ + ) + case 2: + return

{text}

+ case 3: + return

{text}

+ default: + return

{text}

+ } +} + +function Column({ blocksData }: { blocksData: Block[][] }) { + if (blocksData.length === 0) return null; + + return ( +
+ {blocksData.map((blocks, i) => { + return (
{blocks.map(block => { + switch (block.type) { + case 'paragraph': + return + case 'header': + return + default: + return null; + } + })}
) + })} +
+ ) +} + +type ParagraphBlock = { + type: 'paragraph', + data: { + text: string, + }, + id: string, +} + +type HeaderBlock = { + type: 'header', + data: { + text: string, + level: number, + }, + id: string, +} + +type ColumnBlock = { + type: 'column', + data: { + blocksData: Block[][], + }, + id: string, +} + +type Block = ParagraphBlock | HeaderBlock | ColumnBlock; + +export type Content = { + blocks: Block[], + version: string, + time: number, +} + +export default function EditorRender({ data, className }: { data: PagesRecord, className?: string }) { + return ( +
+ {data.content && data.content.blocks.map((block, index): (JSX.Element | null) => { + switch (block.type) { + case 'paragraph': + return + case 'header': + return + case 'column': + return + default: + return

Unknown block type:

{JSON.stringify(block, null, 2)}

+ } + })} +
+ ) +} + +export { EditorRender }; diff --git a/src/components/ReactEditor.tsx b/src/components/ReactEditor.tsx index 42e91d4..48d239a 100644 --- a/src/components/ReactEditor.tsx +++ b/src/components/ReactEditor.tsx @@ -1,5 +1,5 @@ import { memo, useEffect, useRef } from "react"; -import EditorJS from "@editorjs/editorjs"; +import EditorJS, { ToolConstructable } from "@editorjs/editorjs"; import type { OutputData } from "@editorjs/editorjs"; import { EDITOR_JS_TOOLS } from "@/utils/tools"; // @ts-expect-error Undo is not a valid tool @@ -8,6 +8,8 @@ import Undo from "editorjs-undo"; import DragDrop from "editorjs-drag-drop"; import ColumnTool from "@/utils/editor-tools/column"; +import "@/styles/editor.css"; + type Props = { data?: OutputData; onChange(val: OutputData): void; @@ -25,7 +27,7 @@ const EditorBlock = ({ data, onChange, holder, autofocus }: Props) => { tools: { ...EDITOR_JS_TOOLS, column: { - class: ColumnTool, + class: ColumnTool as ToolConstructable, config: { tools: EDITOR_JS_TOOLS, }, diff --git a/src/pages/index.tsx b/src/pages/index.tsx index b413bdc..d6c0dd3 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,7 +1,9 @@ import Image from "next/image"; import Layout from "@/layouts/Home"; +import { PagesRecord } from "@/@types/pocketbase-types"; +import { Content, EditorRender } from "@/components/EditorRender"; -function Home() { +function Home({ data }: { data: PagesRecord}) { return ( +
+ +
); } export default Home; + +export async function getServerSideProps() { + const { getPageBySlug } = await import("@/utils/pb"); + const { data, error } = await getPageBySlug("home"); + if (error || !data) { + return { + notFound: true, + } + } + + return { + props: { + data: data, + }, + } +} diff --git a/src/pages/test/[slug].tsx b/src/pages/test/[slug].tsx index 16c078e..97d02dd 100644 --- a/src/pages/test/[slug].tsx +++ b/src/pages/test/[slug].tsx @@ -1,114 +1,14 @@ import type { PagesRecord } from '@/@types/pocketbase-types'; import Layout from '@/layouts/Home' +import EditorRender from '@/components/EditorRender'; +import type { Content } from '@/components/EditorRender'; -function parseBoldText(text: string) { - const parts = text.split(/(.*?<\/b>)/g); - const result = []; - for (let i = 0; i < parts.length; i++) { - if (parts[i]?.startsWith('')) { - result.push({parts[i]?.slice(3, -4)}) - } else { - result.push(parts[i]) - } - } - return result; -} - -function Paragraph({ text }: { text: string }) { - return

{parseBoldText(text)}

-} - -function Heading({ text, level }: { text: string, level: number }) { - switch (level) { - case 1: - return ( - <> -

{text}

-
- - ) - case 2: - return

{text}

- case 3: - return

{text}

- default: - return

{text}

- } -} - -function Column({ blocksData }: { blocksData: Block[][] }) { - if (blocksData.length === 0) return null; - - return ( -
- {blocksData.map((blocks, i) => { - return (
{blocks.map(block => { - switch (block.type) { - case 'paragraph': - return - case 'header': - return - default: - return null; - } - })}
) - })} -
- ) -} - -type ParagraphBlock = { - type: 'paragraph', - data: { - text: string, - }, - id: string, -} - -type HeaderBlock = { - type: 'header', - data: { - text: string, - level: number, - }, - id: string, -} - -type ColumnBlock = { - type: 'column', - data: { - blocksData: Block[][], - }, - id: string, -} - -type Block = ParagraphBlock | HeaderBlock | ColumnBlock; - -type Content = { - blocks: Block[], - version: string, - time: number, -} - -export default function Page({ data }: { slug: string, data: PagesRecord }) { +export default function Page({ data }: { data: PagesRecord }) { return (

Here is the content rendered:

-
- {data.content && data.content.blocks.map((block, index): (JSX.Element | null) => { - switch (block.type) { - case 'paragraph': - return - case 'header': - return - case 'column': - return - default: - return

Unknown block type:

{JSON.stringify(block, null, 2)}

- } - })} -
+
{JSON.stringify(data.content, null, 2)}
diff --git a/src/styles/editor.css b/src/styles/editor.css new file mode 100644 index 0000000..c6f0e21 --- /dev/null +++ b/src/styles/editor.css @@ -0,0 +1,7 @@ +.ce-block .ce-block__content { + max-width: unset; +} + +.ce-toolbar .ce-toolbar__content { + max-width: unset; +} diff --git a/src/utils/editor-tools/column.ts b/src/utils/editor-tools/column.ts index 41e49f5..5a36fa9 100644 --- a/src/utils/editor-tools/column.ts +++ b/src/utils/editor-tools/column.ts @@ -54,10 +54,14 @@ class ColumnTool { const child = document.createElement("div"); child.classList.add("flex", "flex-row", "w-full", "space-x-4"); - const blocksData: BlockToolData[] = this.data.blocksData; + const blocksData: BlockToolData[] = this.data.blocksData?.length > 0 ? this.data.blocksData : [[]]; for (let i = 0; i < 2; i++) { + if (this.editors[i]) return; + const column = this.createColumn(); + child.appendChild(column); + const editor = new EditorJS({ holder: column, tools: this.tools, @@ -66,10 +70,9 @@ class ColumnTool { blocksData[i] = data.blocks; }, data: { - blocks: this.data.blocksData[i] || [], + blocks: blocksData ? blocksData[i] : [], }, }); - child.appendChild(column); this.editors.push(editor); } this.wrapper.appendChild(child); diff --git a/src/utils/pb.ts b/src/utils/pb.ts index 4772311..979a3c6 100644 --- a/src/utils/pb.ts +++ b/src/utils/pb.ts @@ -68,4 +68,34 @@ async function getIdFromSlug(slug: string) { } } +export async function uploadFile(file: File) { + try { + const res = await pb.collection("files").create(file); + return { data: res }; + } catch (error) { + console.log(error); + return { error }; + } +} + +export async function listFiles() { + try { + const res = await pb.collection("files").getFullList(); + return { data: res }; + } catch (error) { + console.log(error); + return { error }; + } +} + +export async function getFile(id: string) { + try { + const res = await pb.collection("files").getOne(id); + return { data: res }; + } catch (error) { + console.log(error); + return { error }; + } +} + export { pb, getPages, getPageById, getPageBySlug, createPage, updatePage, getIdFromSlug };