This commit is contained in:
Janis
2023-02-08 20:56:22 +01:00
parent 97d8de1a44
commit 730f33879b
17 changed files with 794 additions and 452 deletions

View File

@@ -13,9 +13,13 @@ import { apiUrl } from "@/global";
import Markdown from "@/components/Markdown";
import prisma, { ArticleWithIncludes, CategoryWithIncludes } from "@/lib/prisma";
import { CLIENT_RENEG_LIMIT } from "tls";
import { useSession } from "next-auth/react";
export default function AdminArticlesEditorPage({ article, categories }: { article: ArticleWithIncludes | null; categories: CategoryWithIncludes[] }) {
const router = useRouter();
const { status } = useSession({
required: true,
});
const [title, setTitle] = useState<string>(article?.title ?? "");
const [selectCategoriesOptions, setSelectCategoriesOptions] = useState<{ value: string; label: string }[]>(
@@ -116,132 +120,136 @@ export default function AdminArticlesEditorPage({ article, categories }: { artic
.catch(console.error);
}
return (
<div className={styles.adminArticlesCreate}>
<h1>{article ? "Update article" : "Create new article"}</h1>
<div className={styles.formControl}>
<p className="text-error" ref={errorTextRef}></p>
<button
type="button"
onClick={() => {
if (article) {
updateArticle();
} else {
createArticle();
}
}}
>
{article ? "Update article" : "Create article"}
</button>
</div>
if (status === "authenticated") {
return (
<div className={styles.adminArticlesCreate}>
<h1>{article ? "Update article" : "Create new article"}</h1>
<div className={styles.formControl}>
<p className="text-error" ref={errorTextRef}></p>
<button
type="button"
onClick={() => {
if (article) {
updateArticle();
} else {
createArticle();
}
}}
>
{article ? "Update article" : "Create article"}
</button>
</div>
<div className={styles.form}>
<div className={styles.articleEditor}>
<div className={styles.title}>
<label htmlFor="title">Title</label>
<div className={styles.form}>
<div className={styles.articleEditor}>
<div className={styles.title}>
<label htmlFor="title">Title</label>
<div className={styles.titleInputs}>
<div className={styles.titleInputs}>
<input
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setTitle(e.target.value);
}}
className={!isValidText(title) && title ? "error" : ""}
type="text"
name="title"
placeholder="title"
ref={titleRef}
defaultValue={title}
/>
<input readOnly={true} className={""} type="text" name="name" value={title ? formatTextToUrlName(title) : ""} />
</div>
</div>
<div className={styles.category}>
<label htmlFor="title">Category</label>
<Select
ref={categorySelectRef}
className="react-select-container"
classNamePrefix="react-select"
options={selectCategoriesOptions}
defaultValue={article ? { value: article.category.id, label: article.category.title } : {}}
/>
</div>
<div className={styles.introduction}>
<label htmlFor="title">Introduction</label>
<input
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setTitle(e.target.value);
setIntroduction(e.target.value);
}}
className={!isValidText(title) && title ? "error" : ""}
className={!isValidText(introduction) && introduction ? "error" : ""}
type="text"
name="title"
placeholder="title"
ref={titleRef}
defaultValue={title}
name="introduction"
placeholder="Introduction"
ref={introductionRef}
defaultValue={introduction}
/>
<input readOnly={true} className={""} type="text" name="name" value={title ? formatTextToUrlName(title) : ""} />
</div>
</div>
<div className={styles.category}>
<label htmlFor="title">Category</label>
<Select
ref={categorySelectRef}
className="react-select-container"
classNamePrefix="react-select"
options={selectCategoriesOptions}
defaultValue={article ? { value: article.category.id, label: article.category.title } : {}}
/>
</div>
<div className={styles.introduction}>
<label htmlFor="title">Introduction</label>
<input
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setIntroduction(e.target.value);
}}
className={!isValidText(introduction) && introduction ? "error" : ""}
type="text"
name="introduction"
placeholder="Introduction"
ref={introductionRef}
defaultValue={introduction}
/>
</div>
<div className={styles.markdown}>
<label htmlFor="">Markdown Editor</label>
<div className={styles.markdownEditor}>
<textarea
ref={markdownTextAreaRef}
onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => {
setMarkdown(e.target.value);
}}
defaultValue={markdown}
></textarea>
<Markdown value={markdown} />
</div>
</div>
<div className={styles.contentTable}>
<label htmlFor="">Table of contents</label>
<div className={styles.contentTableEditor}>
<div className={styles.entries}>
{contentTable?.map((entry: IContentTableEntry, i: number) => {
return (
<div key={i}>
<input
onChange={(e) => {
changeContentTableEntryAnchor(i, e.target.value);
}}
type="text"
placeholder={"Anchor"}
defaultValue={entry.anchor}
/>
<input
onChange={(e) => {
changeContentTableEntryTitle(i, e.target.value);
}}
type="text"
placeholder={"Title"}
defaultValue={entry.title}
/>{" "}
<button
onClick={() => {
removeEntry(i);
}}
>
Remove
</button>
</div>
);
})}
<button
onClick={() => {
setContentTable([...contentTable, { title: "", anchor: "" }]);
<div className={styles.markdown}>
<label htmlFor="">Markdown Editor</label>
<div className={styles.markdownEditor}>
<textarea
ref={markdownTextAreaRef}
onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => {
setMarkdown(e.target.value);
}}
>
Add
</button>
defaultValue={markdown}
></textarea>
<Markdown value={markdown} />
</div>
</div>
<div className={styles.contentTable}>
<label htmlFor="">Table of contents</label>
<div className={styles.contentTableEditor}>
<div className={styles.entries}>
{contentTable?.map((entry: IContentTableEntry, i: number) => {
return (
<div key={i}>
<input
onChange={(e) => {
changeContentTableEntryAnchor(i, e.target.value);
}}
type="text"
placeholder={"Anchor"}
defaultValue={entry.anchor}
/>
<input
onChange={(e) => {
changeContentTableEntryTitle(i, e.target.value);
}}
type="text"
placeholder={"Title"}
defaultValue={entry.title}
/>{" "}
<button
onClick={() => {
removeEntry(i);
}}
>
Remove
</button>
</div>
);
})}
<button
onClick={() => {
setContentTable([...contentTable, { title: "", anchor: "" }]);
}}
>
Add
</button>
</div>
<Markdown value={markdown} />
</div>
<Markdown value={markdown} />
</div>
</div>
</div>
</div>
</div>
);
);
} else {
return <></>;
}
}
export async function getServerSideProps(context: any) {

View File

@@ -9,8 +9,13 @@ import { useRouter } from "next/navigation";
import { useEffect } from "react";
import { apiUrl } from "@/global";
import prisma, { CategoryWithIncludes } from "@/lib/prisma";
import { useSession } from "next-auth/react";
export default function AdminCategoriesEditor({ category }: { category: CategoryWithIncludes | null }) {
const { status } = useSession({
required: true,
});
const router = useRouter();
const [title, setTitle] = useState<string>(category?.title ?? "");
const [color, setColor] = useState<string>(category?.color ?? "");
@@ -85,80 +90,84 @@ export default function AdminCategoriesEditor({ category }: { category: Category
.catch(console.error);
}
return (
<div className={styles.categoryEditor}>
<h1>{category ? "Update category" : "Create new category"}</h1>
<div className={styles.formControl}>
<p className="text-error" ref={errorTextRef}></p>
<button
type="button"
onClick={() => {
if (category) {
updateCategory();
} else {
createCategory();
}
}}
>
{category ? "Update category" : "Create category"}
</button>
</div>
<div className={styles.form}>
<div className={styles.title}>
<label htmlFor="title">Title</label>
<div className={styles.titleInputs}>
<input
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setTitle(e.target.value);
}}
className={!isValidText(title) && title ? "error" : ""}
type="text"
name="title"
placeholder="title"
ref={titleRef}
defaultValue={title}
/>
<input readOnly={true} className={""} type="text" name="name" value={title ? formatTextToUrlName(title) : ""} />
</div>
<div className={styles.svg}>
<label>SVG</label>
<div className={styles.svgInputs}>
if (status === "authenticated") {
return (
<div className={styles.categoryEditor}>
<h1>{category ? "Update category" : "Create new category"}</h1>
<div className={styles.formControl}>
<p className="text-error" ref={errorTextRef}></p>
<button
type="button"
onClick={() => {
if (category) {
updateCategory();
} else {
createCategory();
}
}}
>
{category ? "Update category" : "Create category"}
</button>
</div>
<div className={styles.form}>
<div className={styles.title}>
<label htmlFor="title">Title</label>
<div className={styles.titleInputs}>
<input
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setSvgPath(e.target.value);
setTitle(e.target.value);
}}
className={!isValidText(title) && title ? "error" : ""}
type="text"
placeholder="svg path"
ref={svgPathRef}
defaultValue={svgPath}
name="title"
placeholder="title"
ref={titleRef}
defaultValue={title}
/>
<input readOnly={true} className={""} type="text" name="name" value={title ? formatTextToUrlName(title) : ""} />
</div>
<div className={styles.svg}>
<label>SVG</label>
<div className={styles.svgInputs}>
<input
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setSvgPath(e.target.value);
}}
type="text"
placeholder="svg path"
ref={svgPathRef}
defaultValue={svgPath}
/>
<input
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setSvgViewbox(e.target.value);
}}
type="text"
placeholder="0 0 512 512"
ref={svgViewboxRef}
defaultValue={svgViewbox}
/>
</div>
</div>
<div className={styles.color}>
<label>Color</label>
<input
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setSvgViewbox(e.target.value);
setColor(e.target.value);
}}
type="text"
placeholder="0 0 512 512"
ref={svgViewboxRef}
defaultValue={svgViewbox}
type="color"
ref={colorRef}
defaultValue={color}
/>
</div>
</div>
<div className={styles.color}>
<label>Color</label>
<input
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setColor(e.target.value);
}}
type="color"
ref={colorRef}
defaultValue={color}
/>
</div>
</div>
</div>
</div>
);
);
} else {
return <></>;
}
}
export async function getServerSideProps(context: any) {