From 23d6930bd6ec5d1486390a3580c73dee200cda78 Mon Sep 17 00:00:00 2001 From: Guillaume Dorce Date: Wed, 24 May 2023 22:39:09 +0200 Subject: [PATCH] list pages from pocketbase --- src/components/ReactEditor.tsx | 5 +- src/pages/[slug].tsx | 27 --------- src/pages/test/[slug].tsx | 101 ++++++++++++++++++++++++++++++++ src/pages/{ => test}/editor.tsx | 21 ++++++- src/server/api/routers/pages.ts | 28 ++++++++- src/utils/pb.ts | 14 ++++- 6 files changed, 163 insertions(+), 33 deletions(-) delete mode 100644 src/pages/[slug].tsx create mode 100644 src/pages/test/[slug].tsx rename src/pages/{ => test}/editor.tsx (57%) diff --git a/src/components/ReactEditor.tsx b/src/components/ReactEditor.tsx index b0da394..57258e7 100644 --- a/src/components/ReactEditor.tsx +++ b/src/components/ReactEditor.tsx @@ -1,5 +1,6 @@ import { memo, useEffect, useRef } from "react"; -import EditorJS, { OutputData } from "@editorjs/editorjs"; +import EditorJS from "@editorjs/editorjs"; +import type { OutputData } from "@editorjs/editorjs"; import { EDITOR_JS_TOOLS } from "@/utils/tools"; type Props = { @@ -17,7 +18,7 @@ const EditorBlock = ({ data, onChange, holder }: Props) => { holder: holder, tools: EDITOR_JS_TOOLS, data, - async onChange(api, event) { + async onChange(api) { const data = await api.saver.save(); onChange(data); }, diff --git a/src/pages/[slug].tsx b/src/pages/[slug].tsx deleted file mode 100644 index 4f286f5..0000000 --- a/src/pages/[slug].tsx +++ /dev/null @@ -1,27 +0,0 @@ -import type { PagesRecord } from '@/@types/pocketbase-types'; -import Layout from '@/layouts/Home' -import { getPageBySlug } from '@/utils/pb' - -export default function Page({data}: {slug: string, data: PagesRecord}) { - return ( - -

{data.title}

-
{JSON.stringify(data.content, null, 2)}
-
- ) -} - -export async function getServerSideProps({params}: {params: {slug: string}}) { - const {data, error} = await getPageBySlug(params.slug); - if (error || !data) { - return { - notFound: true, - } - } - - return { - props: { - data: data, - }, - } -} diff --git a/src/pages/test/[slug].tsx b/src/pages/test/[slug].tsx new file mode 100644 index 0000000..6934766 --- /dev/null +++ b/src/pages/test/[slug].tsx @@ -0,0 +1,101 @@ +import type { PagesRecord } from '@/@types/pocketbase-types'; +import Layout from '@/layouts/Home' +import { getPageBySlug } from '@/utils/pb' + +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}

+ } +} + +type ParagraphBlock = { + type: 'paragraph', + data: { + text: string, + }, + id: string, +} + +type HeaderBlock = { + type: 'header', + data: { + text: string, + level: number, + }, + id: string, +} + +type Block = ParagraphBlock | HeaderBlock; + +type Content = { + blocks: Block[], + version: string, + time: number, +} + +export default function Page({data}: {slug: string, 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 + default: + return

Unknown block type:

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

+ } + })} +
+
+
{JSON.stringify(data.content, null, 2)}
+
+ ) +} + +export async function getServerSideProps({params}: {params: {slug: string}}) { + const {data, error} = await getPageBySlug(params.slug); + if (error || !data) { + return { + notFound: true, + } + } + + return { + props: { + data: data, + }, + } +} diff --git a/src/pages/editor.tsx b/src/pages/test/editor.tsx similarity index 57% rename from src/pages/editor.tsx rename to src/pages/test/editor.tsx index 4bb95d6..d0ac6b3 100644 --- a/src/pages/editor.tsx +++ b/src/pages/test/editor.tsx @@ -2,6 +2,7 @@ import dynamic from 'next/dynamic' import Layout from '@/layouts/Home' import { useState } from 'react' import { OutputData } from "@editorjs/editorjs"; +import { api } from '@/utils/api'; const ReactEditorJS = dynamic(() => import('@/components/ReactEditor'), { ssr: false @@ -9,8 +10,26 @@ const ReactEditorJS = dynamic(() => import('@/components/ReactEditor'), { export default function Editor() { const [data, setData] = useState() + const {mutate, isLoading, data: data2, isError} = api.pages.updatePage.useMutation(); + + if (data2) console.log(data2) + + const handleSubmit = () => { + if (!data) return + mutate({ + slug: 'test', + title: 'Test', + content: data + }) + } + return ( - + + + {isLoading &&

Loading...

} + {data2 && !isError &&

Saved!

} + {isError &&

Error!

} +

React EditorJS

EditorJS with React

diff --git a/src/server/api/routers/pages.ts b/src/server/api/routers/pages.ts index a273599..8f6ab53 100644 --- a/src/server/api/routers/pages.ts +++ b/src/server/api/routers/pages.ts @@ -1,13 +1,13 @@ import { z } from "zod"; import { createTRPCRouter, publicProcedure } from "../trpc"; -import { getPage, getPages } from "@/utils/pb"; +import { getPageById, getPages, updatePage, getIdFromSlug } from "@/utils/pb"; export const pagesRouter = createTRPCRouter({ getPage: publicProcedure .input(z.object({ id: z.string() })) .query(({ input }) => { return { - data: getPage(input.id), + data: getPageById(input.id), }; }), getPages: publicProcedure @@ -16,4 +16,28 @@ export const pagesRouter = createTRPCRouter({ data: getPages(), }; }), + updatePage: publicProcedure + .input(z.object({ slug: z.string(), title: z.string().optional(), content: z.any().optional() })) + .mutation(async ({ input }) => { + const id = await getIdFromSlug(input.slug); + if (!id || id.error || !id.data) { + return { + error: { + code: "NOT_FOUND", + message: "Page not found", + }, + }; + } + let data = {}; + if (input.title) { + data = { ...data, title: input.title }; + } + if (input.content) { + data = { ...data, content: input.content }; + } + const res = await updatePage(id.data, data); + return { + data: res, + }; + }), }); diff --git a/src/utils/pb.ts b/src/utils/pb.ts index 0d2b9b3..4772311 100644 --- a/src/utils/pb.ts +++ b/src/utils/pb.ts @@ -56,4 +56,16 @@ async function updatePage(id: string, data: PagesRecord) { } } -export { pb, getPages, getPageById, getPageBySlug, createPage, updatePage }; +async function getIdFromSlug(slug: string) { + try { + const res = await pb + .collection("pages") + .getFirstListItem('slug="' + slug + '"'); + return { data: res.id }; + } catch (error) { + console.log(error); + return { error }; + } +} + +export { pb, getPages, getPageById, getPageBySlug, createPage, updatePage, getIdFromSlug };