add: markdown permission setting

improve: template
This commit is contained in:
h z
2025-04-25 00:39:01 +01:00
parent c20cb168ff
commit 9ea44385ee
17 changed files with 893 additions and 372 deletions

View File

@@ -0,0 +1,62 @@
import React, { useState } from "react";
import { useMarkdownTemplates } from "../../../utils/queries/markdown-template-queries";
import PermissionGuard from "../../PermissionGuard";
import { useNavigate } from "react-router-dom";
const TemplateTab = () => {
const { data: templates, isLoading, error } = useMarkdownTemplates();
const [keyword, setKeyword] = useState("");
const navigate = useNavigate();
const filteredTemplates = templates?.filter(template =>
template.title.toLowerCase().includes(keyword.toLowerCase())
);
const handleTemplateClick = (templateId) => {
navigate(`/template/edit/${templateId}`);
};
if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error loading templates</p>;
return (
<aside className="menu">
<div className="control is-expanded">
<input
className="input is-small"
type="text"
placeholder="Search templates..."
onChange={(e) => setKeyword(e.target.value)}
/>
</div>
<PermissionGuard rolesRequired={["admin", "creator"]}>
<a
href="/template/create"
className="button is-primary is-small is-fullwidth"
style={{ marginBottom: "10px" }}
>
Create New Template
</a>
</PermissionGuard>
{!filteredTemplates || filteredTemplates.length === 0 ? (
<p>No templates found</p>
) : (
<div className="template-list">
{filteredTemplates.map(template => (
<button
key={template.id}
className="button is-light is-fullwidth template-button"
onClick={() => handleTemplateClick(template.id)}
style={{ marginBottom: "5px", textAlign: "left", justifyContent: "flex-start" }}
>
{template.title}
</button>
))}
</div>
)}
</aside>
);
};
export default TemplateTab;

View File

@@ -0,0 +1,88 @@
import PermissionGuard from "../../PermissionGuard";
import PathNode from "../PathNode";
import React from "react";
import {useTree} from "../../../utils/queries/tree-queries";
import {useDeletePath, useUpdatePath} from "../../../utils/queries/path-queries";
const TreeTab = () => {
const {data: tree, isLoading, error} = useTree();
const deletePath = useDeletePath();
const updatePath = useUpdatePath();
const [keyword, setKeyword] = React.useState("");
const handleDelete = (id) => {
if (window.confirm("Are you sure you want to delete this path?")){
deletePath.mutate(id, {
onError: (err) => {
alert("Failed to delete path");
},
});
}
};
const filterTree = (t, k) => {
if(t === undefined)
return undefined;
if (t.type === "path") {
if (t.name.includes(k)) {
return { ...t };
}
const filteredChildren = (t.children || [])
.map(c => filterTree(c, k))
.filter(Boolean);
if (filteredChildren.length > 0) {
return { ...t, children: filteredChildren };
}
} else if (t.type === "markdown") {
if (t.title.includes(k)) {
return { ...t };
}
}
return undefined;
};
const filteredTree = filterTree(tree, keyword);
const handleSave = (id, newName) => {
updatePath.mutate({ id, data: {name: newName }} , {
onError: (err) => {
alert("Failed to update path");
}
});
};
if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error loading tree</p>;
return (
<aside className="menu">
<div className="control is-expanded">
<input
className="input is-small"
type="text"
placeholder="Search..."
onChange={(e) => setKeyword(e.target.value)}
/>
</div>
<PermissionGuard rolesRequired={["admin", "creator"]}>
<a
href="/markdown/create"
className="button is-primary is-small"
>
Create New Markdown
</a>
</PermissionGuard>
{!filteredTree || filteredTree.length === 0 ?
<p>No Result</p> :
<PathNode
key={1}
path={filteredTree}
isRoot={true}
onSave={handleSave}
onDelete={handleDelete}
/>
}
</aside>
);
};
export default TreeTab;