diff --git a/src/components/Markdowns/MarkdownContent.css b/src/components/Markdowns/MarkdownContent.css index 9fe26ad..3b5823d 100644 --- a/src/components/Markdowns/MarkdownContent.css +++ b/src/components/Markdowns/MarkdownContent.css @@ -24,3 +24,19 @@ border-radius: 4px; font-size: 0.95em; } +.markdown-content-container-header { + align-items: center; + display: flex; + justify-content: space-between; +} +.markdown-content-container-header h1 { + margin: 0; + font-size: 1.5rem; + line-height: 1.5; +} +.markdown-content-container-header .button { + margin-left: auto; + height: auto; + display: inline-flex; + align-items: center; +} \ No newline at end of file diff --git a/src/components/Markdowns/MarkdownContent.js b/src/components/Markdowns/MarkdownContent.js index c0c6822..c637825 100644 --- a/src/components/Markdowns/MarkdownContent.js +++ b/src/components/Markdowns/MarkdownContent.js @@ -1,16 +1,18 @@ import React, { useEffect, useState } from "react"; -import { useParams } from "react-router-dom"; +import {Link, 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"; +import PermissionGuard from "../PermissionGuard"; const MarkdownContent = () => { const { id } = useParams(); const [content, setContent] = useState(null); const [title, setTitle] = useState(null); const [error, setError] = useState(null); + const [indexTitle, setIndexTitle] = useState(null); useEffect(() => { fetch_(`${config.BACKEND_HOST}/api/markdown/${id}`, {}, { @@ -20,6 +22,14 @@ const MarkdownContent = () => { .then((data) => { setTitle(data.title); setContent(data.content); + if(data.title === "index"){ + fetch_(`${config.BACKEND_HOST}/api/path/${data.path_id}`, {}, { + use_cache: true, + use_token: false + }).then((path_data) => { + setIndexTitle(path_data.id === 1 ? "Home" : path_data.name); + }).catch((err) => setError(error)); + } }) .catch((error) => setError(error)); }, [id]); @@ -34,8 +44,16 @@ const MarkdownContent = () => { return (
-

{title}

- +
+

{title === "index" ? indexTitle : title}

+ + + Edit + + +
+ +
); }; diff --git a/src/components/Markdowns/MarkdownEditor.js b/src/components/Markdowns/MarkdownEditor.js index cad33c5..b86f708 100644 --- a/src/components/Markdowns/MarkdownEditor.js +++ b/src/components/Markdowns/MarkdownEditor.js @@ -15,10 +15,12 @@ const MarkdownEditor = () => { const [title, setTitle] = useState(""); const [content, setContent] = useState(""); const [pathId, setPathId] = useState(1); + const [loading, setLoading] = useState(false); useEffect(() => { if (id) { - fetch_(`/api/markdown/${id}`, {}, { + setLoading(true); + fetch_(`${config.BACKEND_HOST}/api/markdown/${id}`, {}, { use_cache: true, use_token: false }) @@ -29,6 +31,9 @@ const MarkdownEditor = () => { }) .catch((err) => { console.error("Failed to load markdown", err); + }) + .finally(() => { + setLoading(false); }); } }, [id]); @@ -56,7 +61,9 @@ const MarkdownEditor = () => { return
Permission Denied
; } - return ( + return loading ? ( +

loading

+ ) : (

{id ? "Edit Markdown" : "Create Markdown"}

diff --git a/src/components/Markdowns/MarkdownView.js b/src/components/Markdowns/MarkdownView.js index 93e6b7c..2567cdb 100644 --- a/src/components/Markdowns/MarkdownView.js +++ b/src/components/Markdowns/MarkdownView.js @@ -8,7 +8,7 @@ import { okaidia } from "react-syntax-highlighter/dist/esm/styles/prism"; import "katex/dist/katex.min.css"; import "./MarkdownView.css"; -const MarkdownPreview = ({ content, height="auto" }) => { +const MarkdownView = ({ content, height="auto" }) => { return (
{ ); }; -export default MarkdownPreview; \ No newline at end of file +export default MarkdownView; \ No newline at end of file diff --git a/src/components/Navigations/PathNode.js b/src/components/Navigations/PathNode.js index db88c4d..7bd0596 100644 --- a/src/components/Navigations/PathNode.js +++ b/src/components/Navigations/PathNode.js @@ -8,7 +8,7 @@ import { fetch_ } from "../../utils/requestUtils"; const PathNode = ({ path, isRoot = false, onDelete, onSave }) => { const [children, setChildren] = useState([]); const [markdowns, setMarkdowns] = useState([]); - const [isExpanded, setIsExpanded] = useState(isRoot); // Root is always expanded + const [isExpanded, setIsExpanded] = useState(isRoot); const [loading, setLoading] = useState(false); const [isEditing, setIsEditing] = useState(false); const [newName, setNewName] = useState(path.name); @@ -18,13 +18,9 @@ const PathNode = ({ path, isRoot = false, onDelete, onSave }) => { fetch_(`${config.BACKEND_HOST}/api/markdown/get_index/${path.id}`, {}, { use_cache: true, use_token: false - }).then((data) => { - setIndexMarkdownId(data.id); }) - .catch((error) => { - setIndexMarkdownId(null); - console.error(error); - }); + .then((data) => setIndexMarkdownId(data.id)) + .catch((error) => setIndexMarkdownId(null) ); }, [path]); const handleSave = () => { diff --git a/src/components/PathManager.js b/src/components/PathManager.js index ac355f9..3f324bd 100644 --- a/src/components/PathManager.js +++ b/src/components/PathManager.js @@ -5,6 +5,7 @@ import "./PathManager.css"; const PathManager = ({ currentPathId = 1, onPathChange }) => { const [currentPath, setCurrentPath] = useState([{ name: "Root", id: 1 }]); + //const [currentPath, setCurrentPath] = useState(buildPath(currentPathId)); const [currentId, setCurrentId] = useState(currentPathId); const [subPaths, setSubPaths] = useState([]); const [searchTerm, setSearchTerm] = useState(""); @@ -13,13 +14,41 @@ const PathManager = ({ currentPathId = 1, onPathChange }) => { const inputRef = useRef(); + const buildPath = async (path_id) => { + const path = []; + let current_id = path_id; + while (current_id) { + const pathData = await fetch_(`${config.BACKEND_HOST}/api/path/${current_id}`, {},{ + use_cache: true, + use_token: false, + }); + current_id = pathData.parent_id; + path.unshift(pathData); + + } + return path; + } + + useEffect(() => { fetchSubPaths(currentId); }, [currentId]); + useEffect(() => { + const init = async () => { + const pth = await buildPath(currentPathId); + setCurrentPath(pth); + }; + init(); + + }, [currentPathId]); + const fetchSubPaths = (pathId) => { setLoading(true); - fetch_(`${config.BACKEND_HOST}/api/path/parent/${pathId}`, {}, { use_cache: false, use_token: true }) + fetch_(`${config.BACKEND_HOST}/api/path/parent/${pathId}`, {}, { + use_cache: false, + use_token: true + }) .then((data) => setSubPaths(data)) .catch((error) => console.error("Failed to fetch subdirectories:", error)) .finally(() => setLoading(false)); @@ -71,6 +100,7 @@ const PathManager = ({ currentPathId = 1, onPathChange }) => { ); return ( +