add markdown viewer

This commit is contained in:
Janis
2023-01-15 02:48:17 +01:00
parent 9617dc2ef3
commit a0598484b4
11 changed files with 1263 additions and 122 deletions

View File

@@ -3,9 +3,11 @@ import PropTypes from "prop-types";
import ReactMarkdown from "react-markdown";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import oneDark from "react-syntax-highlighter/dist/esm/styles/prism/one-dark";
import LoadMarkdown from "./articles/[categoryName]/[articleName]/LoadMarkdown";
export default function Markdown({ value }: { value: any }) {
return (
<div>
<ReactMarkdown
// eslint-disable-next-line react/no-children-prop
children={value}
@@ -29,6 +31,8 @@ export default function Markdown({ value }: { value: any }) {
},
}}
/>
<LoadMarkdown />
</div>
);
}

View File

@@ -84,6 +84,7 @@ export default function Nav({ categories }: { categories: Category[] }) {
<div className={styles.dropDownContainer}>
<div className={styles.content}>
<Link href={"/articles"}>All</Link>
{categories?.map((cat, i) => {
{
return (

View File

@@ -6,23 +6,33 @@ import { useState, useRef } from "react";
import styles from "../../../../styles/modules/AdminArticlesCreate.module.scss";
import { PostArticle } from "../../../../types/postData";
import Markdown from "../../../Markdown";
import { Category } from "@prisma/client";
import "../../../../styles/inputs.scss";
import Select, { GroupBase, OptionsOrGroups } from "react-select";
import { apiUrl } from "../../../global";
import urlJoin from "url-join";
export default function AdminArticlesCreate() {
const [formData, setFormData] = useState<PostArticle>(null);
const [markdown, setMarkdown] = useState<string>("");
const [selectedCategory, setSelectedCategory] = useState<string>();
const titleRef = useRef<HTMLInputElement>(null);
const markdownTextAreaRef = useRef<HTMLTextAreaElement>(null);
function handleFormChange({ newMarkdownText = markdown }) {
const selectCategoriesOptions: any = [
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" },
];
function handleFormChange() {
setMarkdown(markdownTextAreaRef.current.value);
setFormData({
name: titleRef.current.value.replaceAll(" ", "%20"),
title: titleRef.current.value,
introduction: "test intro",
markdown: markdown,
categoryId: 1,
categoryId: 2,
});
setMarkdown(newMarkdownText);
}
async function postData() {
@@ -49,22 +59,31 @@ export default function AdminArticlesCreate() {
send
</button>
<div className={styles.form}>
<div className={styles.ContentTable}>contenttable</div>
<div className={styles.contentTableEditor}>contenttable</div>
<div className={styles.content}>
<div className={styles.articleEditor}>
<Select
className="react-select-container"
classNamePrefix="react-select"
value={selectedCategory}
onChange={handleFormChange}
options={selectCategoriesOptions}
/>
<input
onChange={() => {
handleFormChange({});
}}
onChange={handleFormChange}
className={""}
type="text"
name="title"
placeholder="title"
ref={titleRef}
/>
<textarea></textarea>
<div className={styles.markdown}>
<textarea ref={markdownTextAreaRef} onChange={handleFormChange}></textarea>
<Markdown value={markdown} />
</div>
</div>
</div>
</div>
);
}

View File

@@ -65,7 +65,7 @@ export default async function ArticlePage({ params }: { params: { articleName: s
<p>{article?.introduction}</p>
</div>
<Markdown value={markdown} />
<LoadMarkdown />
{/* <div
className="markdown"
dangerouslySetInnerHTML={{

1119
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -28,6 +28,7 @@
"react-code-blocks": "^0.0.9-0",
"react-dom": "18.2.0",
"react-markdown": "^8.0.4",
"react-select": "^5.7.0",
"react-syntax-highlighter": "^15.5.0",
"reflect-metadata": "^0.1.13",
"sass": "^1.57.0",

View File

@@ -12,18 +12,12 @@ export default async function handler(req: Request, res: Response) {
if (result !== null) {
res.end(JSON.stringify(result));
} else {
const error: ResponseError = {
code: "404",
message: "No categories found!",
};
res.status(404).send(JSON.stringify(error));
console.log("No categories found");
res.end(JSON.stringify([]));
}
})
.catch((err) => {
const error: ResponseError = {
code: "500",
message: err,
};
res.status(500).send(JSON.stringify(error));
console.log(err);
res.end(JSON.stringify([]));
});
}

73
styles/inputs.scss Normal file
View File

@@ -0,0 +1,73 @@
@import "variables_colors.scss";
@import "variables.scss";
input {
border: 2px solid rgba(95, 95, 95, 0.5);
background-color: transparent;
height: 30px;
padding: 5px 5px 5px 5px;
color: var(--color-font);
border-radius: 3px;
outline: none;
transition: all 50ms linear;
&::placeholder {
font-weight: bold;
}
&:hover {
border-color: rgba(177, 177, 177, 0.608);
}
&:focus {
border-color: var(--color-accent);
}
&.error {
border-color: var(--color-error);
}
&.success {
border-color: var(--color-success);
}
&.warning {
border-color: var(--color-warning);
}
&.info {
border-color: var(--color-info);
}
}
.react-select-container {
.react-select__control {
background-color: var(--color-background-secondary);
border-color: rgba(95, 95, 95, 0.5);
transition: none;
&:hover {
border-color: rgba(95, 95, 95, 0.5);
}
}
.react-select__menu {
background-color: var(--color-background-secondary);
border: 1px solid rgba(95, 95, 95, 0.5);
}
.react-select__option {
background-color: var(--color-background-secondary);
&:hover {
background-color: var(--bg-primary);
}
}
.react-select__indicator-separator {
background-color: rgba(95, 95, 95, 0.5);
}
.react-select__placeholder,
.react-select__single-value {
color: var(--font-color);
}
}

View File

@@ -9,14 +9,26 @@
max-width: 1800px;
padding: 0px 24px;
.content {
.articleEditor {
display: flex;
flex-direction: column;
.markdown {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px 10px;
textarea {
color: var(--font-color);
background-color: rgba(16, 16, 16, 0.234);
width: 100%;
min-height: 500px;
border: 2px solid rgba(59, 59, 59, 0.434);
background-color: transparent;
min-height: 700px;
resize: none;
display: block;
border-radius: 0px;
outline: 0;
resize: vertical;
font-family: inherit;
font-size: inherit;
}
}
}
}

View File

@@ -6,10 +6,16 @@
/*! By default colors are in DARK mode */
/* Colors: General */
--color-background-body: #181a1b;
--color-background-secondary: #2c3032;
--color-font: #ffffff;
--color-font-muted: #929292;
--color-shadow-nav: #00000033;
--color-error: #cf000f;
--color-success: #009944;
--color-info: #63c0df;
--color-warning: #f0541e;
--color-overlay-mix: var(--color-font);
--color-background-nav: transparent;
--color-svg-nav: #bfbfbf;