save button

This commit is contained in:
gom-by
2025-02-19 19:34:35 +01:00
parent a473e4b863
commit 5c86b67870
3 changed files with 127 additions and 74 deletions

View File

@@ -0,0 +1,120 @@
"use client";
import { useState } from "react";
import {
MDXEditor,
toolbarPlugin,
headingsPlugin,
listsPlugin,
quotePlugin,
thematicBreakPlugin,
markdownShortcutPlugin,
BoldItalicUnderlineToggles,
ListsToggle,
BoldItalicUnderlineTogglesProps,
MDXEditorProps,
UndoRedo,
InsertImage,
CreateLink
} from "@mdxeditor/editor";
import DOMPurify from "isomorphic-dompurify";
import { Button } from "@/components/ui/button";
import useApiMutation from "@/hooks/use-api";
export default function Editor() {
const [blogContent, setBlogContent] = useState("");
const [cursor, setCursor] = useState<{ line: number; column: number }>({
line: 0,
column: 0,
});
const getCursorPosition = (newText: string) => {
const cursorPos = newText.length;
const lines = newText.substring(0, cursorPos).split("\n");
const line = lines.length; // Current line number
const column = lines[lines.length - 1].length + 1; // Current column number
setCursor({ line, column });
};
const sanitized = DOMPurify.sanitize(blogContent);
const propsa: BoldItalicUnderlineTogglesProps = { options: ["Bold", "Italic", "Underline"] }
const mdxEditorProps: MDXEditorProps = {}
const {
trigger,
isMutating: loading,
isSuccess,
} = useApiMutation(
"/blog/new",
undefined,
"POST",
false,
true,
);
return (
<section className="m-10">
<div className="flex">
<div className="flex-1">
<MDXEditor
plugins={[
headingsPlugin(),
listsPlugin(),
quotePlugin(),
thematicBreakPlugin(),
markdownShortcutPlugin(),
toolbarPlugin({
toolbarContents: () => (
<div className="flex flex-row">
<UndoRedo />
<BoldItalicUnderlineToggles {...propsa} />
<InsertImage />
<CreateLink />
<ListsToggle />
</div>
),
}),
]}
onChange={setBlogContent}
onBlur={() => getCursorPosition(blogContent)}
markdown="ok"
/>
<div>
Line: {cursor.line}; Column: {cursor.column}
</div>
</div>
<div
className="mt-4 w-1/2 p-2 bg-gray-100 border rounded-md text-sm text-black"
dangerouslySetInnerHTML={{
__html: sanitized,
}}
/>
</div>
<Button className="text-black bg-white" onClick={async () => {
try {
const res = await trigger({
label: "This is my label",
summary: "A summary",
image: "none",
href: "none",
blogID: "id",
slug: "myslug",
content: blogContent,
published: "",
});
if (!res) throw new Error("The server hasn't responded.");
if (res.status === "Error") throw new Error(res.message);
if (res.data) console.log(res.data);
return res;
} catch (error: any) {
throw new Error(error.message);
}
}}>Sauvegarder</Button>
</section >
);
}

View File

@@ -1,77 +1,9 @@
"use client";
import { useEffect, useState, useRef } from "react";
import { Button } from "@/components/ui/button";
import { Bold, Italic, Strikethrough, Underline } from "lucide-react";
import { MDXEditor } from "@mdxeditor/editor"; // Assuming react-mdx-editor or similar
import DOMPurify from "isomorphic-dompurify";
import Editor from "./editor"
export default function NewBlog() {
const [text, setText] = useState("");
const [cursor, setCursor] = useState<{ line: number; column: number }>({
line: 0,
column: 0,
});
// Function to update the cursor position
const getCursorPosition = (newText: string) => {
const cursorPos = newText.length;
const lines = newText.substring(0, cursorPos).split("\n");
const line = lines.length; // Current line number
const column = lines[lines.length - 1].length + 1; // Current column number
setCursor({ line, column });
};
const execCommand = (command: string) => {
const pre = text.slice(0, cursor.column);
const post = text.slice(cursor.column);
setText(pre + command + post);
getCursorPosition(pre + command + post); // Update cursor position after change
};
// Sanitize the MDX text before rendering
const sanitized = DOMPurify.sanitize(text);
return (
<section className="flex m-5">
<div className="flex-1">
<div className="flex gap-2 mb-2 border-b pb-2">
<Button variant="outline" size="icon" onClick={() => execCommand("**")}>
<Bold size={16} />
</Button>
<Button variant="outline" size="icon" onClick={() => execCommand("*")}>
<Italic size={16} />
</Button>
<Button variant="outline" size="icon" onClick={() => execCommand("__")}>
<Underline size={16} />
</Button>
<Button variant="outline" size="icon" onClick={() => execCommand("~~")}>
<Strikethrough size={16} />
</Button>
</div>
{/* Using MDXEditor instead of a basic Textarea */}
<MDXEditor
onChange={setText}
onBlur={() => getCursorPosition(text)}
markdown="ok"
/>
<div>
Line: {cursor.line}; Column: {cursor.column}
</div>
</div>
<div
className="mt-4 p-2 bg-gray-100 border rounded-md text-sm text-black"
dangerouslySetInnerHTML={{
__html: sanitized,
}}
/>
</section>
);
return (
<>
<Editor />
</>
)
}