diff --git a/src/App.js b/src/App.js index 8e3f8ca..189c2f5 100644 --- a/src/App.js +++ b/src/App.js @@ -2,7 +2,7 @@ import React from "react"; import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import MainNavigation from "./components/Navigations/MainNavigation"; import SideNavigation from "./components/Navigations/SideNavigation"; -import MarkdownContent from "./components/MarkdownContent"; +import MarkdownContent from "./components/Markdowns/MarkdownContent"; import MarkdownEditor from "./components/Markdowns/MarkdownEditor"; import "./App.css"; import Callback from "./Callback"; diff --git a/src/components/MarkdownContent.css b/src/components/MarkdownContent.css deleted file mode 100644 index e69de29..0000000 diff --git a/src/components/MarkdownContent.js b/src/components/MarkdownContent.js deleted file mode 100644 index ace5ff4..0000000 --- a/src/components/MarkdownContent.js +++ /dev/null @@ -1,37 +0,0 @@ -//src/components/MarkdownContent.js - - -import React, { useEffect, useState } from "react"; -import { useParams } from "react-router-dom"; -import {fetch_} from "../utils/requestUtils"; - -const MarkdownContent = () => { - const { id } = useParams(); - const [content, setContent] = useState(null); - const [error, setError] = useState(null); - - useEffect(() => { - fetch_(`/api/markdown/${id}`, {}, { - use_cache: true, - use_token: false - }) - .then((data) => setContent(data)) - .catch((error) => setError(error)); - }, [id]); - - if (error) { - return
Error: {error}
; - } - - if (!content) { - return
Loading...
; - } - - return ( -
-
{content}
-
- ); -}; - -export default MarkdownContent; \ No newline at end of file diff --git a/src/components/Markdowns/MarkdownContent.css b/src/components/Markdowns/MarkdownContent.css new file mode 100644 index 0000000..9fe26ad --- /dev/null +++ b/src/components/Markdowns/MarkdownContent.css @@ -0,0 +1,26 @@ +.markdown-content-container { + margin: 20px; + padding: 20px; + background: #fff; + border-radius: 8px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); +} + +.markdown-content { + font-family: "Arial", sans-serif; + line-height: 1.6; +} + +.markdown-content pre { + background: #f5f5f5; + padding: 10px; + border-radius: 4px; + overflow-x: auto; +} + +.markdown-content code { + background: #f9f9f9; + padding: 2px 4px; + border-radius: 4px; + font-size: 0.95em; +} diff --git a/src/components/Markdowns/MarkdownContent.js b/src/components/Markdowns/MarkdownContent.js new file mode 100644 index 0000000..c0c6822 --- /dev/null +++ b/src/components/Markdowns/MarkdownContent.js @@ -0,0 +1,43 @@ +import React, { useEffect, useState } from "react"; +import { useParams } from "react-router-dom"; +import "katex/dist/katex.min.css"; +import "./MarkdownContent.css"; +import { fetch_ } from "../../utils/requestUtils"; +import config from "../../config"; +import MarkdownView from "./MarkdownView"; + +const MarkdownContent = () => { + const { id } = useParams(); + const [content, setContent] = useState(null); + const [title, setTitle] = useState(null); + const [error, setError] = useState(null); + + useEffect(() => { + fetch_(`${config.BACKEND_HOST}/api/markdown/${id}`, {}, { + use_cache: true, + use_token: false + }) + .then((data) => { + setTitle(data.title); + setContent(data.content); + }) + .catch((error) => setError(error)); + }, [id]); + + if (error) { + return
Error: {error.message || "Failed to load content"}
; + } + + if (!content) { + return
Loading...
; + } + + return ( +
+

{title}

+ +
+ ); +}; + +export default MarkdownContent; \ No newline at end of file diff --git a/src/components/Markdowns/MarkdownEditor.css b/src/components/Markdowns/MarkdownEditor.css index 947daac..a308847 100644 --- a/src/components/Markdowns/MarkdownEditor.css +++ b/src/components/Markdowns/MarkdownEditor.css @@ -8,15 +8,7 @@ border-radius: 8px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); } -.markdown-preview { - padding: 15px; - border: 1px solid #ddd; - border-radius: 8px; - background-color: #ffffff; - white-space: pre-wrap; - word-wrap: break-word; - overflow-x: auto; -} + .markdown-editor-header { text-align: center; diff --git a/src/components/Markdowns/MarkdownEditor.js b/src/components/Markdowns/MarkdownEditor.js index cb89d3d..cad33c5 100644 --- a/src/components/Markdowns/MarkdownEditor.js +++ b/src/components/Markdowns/MarkdownEditor.js @@ -1,17 +1,12 @@ import React, { useContext, useEffect, useState } from "react"; import { AuthContext } from "../../AuthProvider"; import { useNavigate, useParams } from "react-router-dom"; -import ReactMarkdown from "react-markdown"; -import remarkMath from "remark-math"; -import rehypeKatex from "rehype-katex"; -import rehypeRaw from "rehype-raw"; -import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; -import { okaidia } from "react-syntax-highlighter/dist/esm/styles/prism"; import "katex/dist/katex.min.css"; import "./MarkdownEditor.css"; import config from "../../config"; import { fetch_ } from "../../utils/requestUtils"; import PathManager from "../PathManager"; +import MarkdownView from "./MarkdownView"; const MarkdownEditor = () => { const { roles } = useContext(AuthContext); @@ -123,32 +118,7 @@ const MarkdownEditor = () => { {/* Preview Column */}

Preview

-
- - {String(children).replace(/\n$/, "")} - - ) : ( - - {children} - - ); - }, - }} - /> -
+
diff --git a/src/components/Markdowns/MarkdownView.css b/src/components/Markdowns/MarkdownView.css new file mode 100644 index 0000000..1a7d305 --- /dev/null +++ b/src/components/Markdowns/MarkdownView.css @@ -0,0 +1,49 @@ +.markdown-preview { + padding: 15px; + border: 1px solid #ddd; + border-radius: 8px; + background-color: #ffffff; + white-space: normal; + word-wrap: break-word; + overflow-x: auto; +} + +.katex-display { + margin: 1em 0; + text-align: center; +} +.katex { + font-size: 1.2rem; +} + +code { + font-family: 'Courier New', Courier, monospace; + background-color: #f4f4f4; + padding: 2px 4px; + border-radius: 4px; +} +pre { + background-color: #2d2d2d; + color: #f8f8f2; + padding: 10px; + border-radius: 6px; + overflow-x: auto; +} + +.markdown-preview ul, +.markdown-preview ol { + padding-left: 1.5rem; /* 设置左侧缩进 */ + margin-bottom: 1rem; /* 每个列表的底部间距 */ +} + +.markdown-preview ul { + list-style-type: disc; /* 确保无序列表使用圆点 */ +} + +.markdown-preview ol { + list-style-type: decimal; /* 确保有序列表使用数字 */ +} + +.markdown-preview li { + margin-bottom: 0.5rem; /* 列表项之间的间距 */ +} \ No newline at end of file diff --git a/src/components/Markdowns/MarkdownView.js b/src/components/Markdowns/MarkdownView.js new file mode 100644 index 0000000..93e6b7c --- /dev/null +++ b/src/components/Markdowns/MarkdownView.js @@ -0,0 +1,42 @@ +import React from "react"; +import ReactMarkdown from "react-markdown"; +import remarkMath from "remark-math"; +import rehypeKatex from "rehype-katex"; +import rehypeRaw from "rehype-raw"; +import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; +import { okaidia } from "react-syntax-highlighter/dist/esm/styles/prism"; +import "katex/dist/katex.min.css"; +import "./MarkdownView.css"; + +const MarkdownPreview = ({ content, height="auto" }) => { + return ( +
+ + {String(children).replace(/\n$/, "")} + + ) : ( + + {children} + + ); + }, + }} + /> +
+ ); +}; + +export default MarkdownPreview; \ No newline at end of file