Added Editor for Markdawn
This commit is contained in:
parent
877dc01586
commit
b736660b06
|
@ -0,0 +1,24 @@
|
||||||
|
import Markdown from "markdown-to-jsx";
|
||||||
|
import SceneBreak from "./SceneBreak";
|
||||||
|
|
||||||
|
type ScenBreakProps = {
|
||||||
|
className?: string;
|
||||||
|
text: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Markdawn(props: ScenBreakProps): JSX.Element {
|
||||||
|
return (
|
||||||
|
<Markdown
|
||||||
|
className={`prose text-black ${props.className}`}
|
||||||
|
options={{
|
||||||
|
overrides: {
|
||||||
|
hr: {
|
||||||
|
component: SceneBreak,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{props.text}
|
||||||
|
</Markdown>
|
||||||
|
);
|
||||||
|
}
|
|
@ -6,7 +6,6 @@ import Button from "components/Button";
|
||||||
import HorizontalLine from "components/HorizontalLine";
|
import HorizontalLine from "components/HorizontalLine";
|
||||||
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
||||||
import Markdown from "markdown-to-jsx";
|
import Markdown from "markdown-to-jsx";
|
||||||
import Script from "next/script";
|
|
||||||
|
|
||||||
type MainPanelProps = {
|
type MainPanelProps = {
|
||||||
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"];
|
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"];
|
||||||
|
@ -21,16 +20,16 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
|
||||||
className="flex flex-col justify-center content-start p-8 gap-y-2 justify-items-center text-center"
|
className="flex flex-col justify-center content-start p-8 gap-y-2 justify-items-center text-center"
|
||||||
>
|
>
|
||||||
<div className="">
|
<div className="">
|
||||||
<div className="grid place-items-center mobile:grid-flow-col">
|
<div className="grid place-items-center">
|
||||||
<Link href="/" passHref>
|
<Link href="/" passHref>
|
||||||
<div className="mobile:w-10 mobile:self-end w-1/2 cursor-pointer transition-[filter] hover:colorize-dark">
|
<div className="w-1/2 cursor-pointer transition-[filter] hover:colorize-dark">
|
||||||
<SVG
|
<SVG
|
||||||
src={"/icons/accords.svg"}
|
src={"/icons/accords.svg"}
|
||||||
alt={"Logo of Accord's Library"}
|
alt={"Logo of Accord's Library"}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
<div className="relative mt-5 mobile:self-start">
|
<div className="relative mt-5">
|
||||||
{router.locale ? (
|
{router.locale ? (
|
||||||
<Button className="absolute right-0 top-[-1.3em] text-xs !py-0.5 !px-2.5">
|
<Button className="absolute right-0 top-[-1.3em] text-xs !py-0.5 !px-2.5">
|
||||||
{router.locale.toUpperCase()}
|
{router.locale.toUpperCase()}
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
import ContentPanel, {
|
||||||
|
ContentPanelWidthSizes,
|
||||||
|
} from "components/Panels/ContentPanel";
|
||||||
|
import { getWebsiteInterface } from "graphql/operations";
|
||||||
|
import { GetStaticProps } from "next";
|
||||||
|
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
||||||
|
import AppLayout from "components/AppLayout";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
import Markdawn from "components/Markdown/Markdawn";
|
||||||
|
import Script from "next/script";
|
||||||
|
|
||||||
|
type EditorProps = {
|
||||||
|
langui: GetWebsiteInterfaceQuery;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Editor(props: EditorProps): JSX.Element {
|
||||||
|
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||||
|
|
||||||
|
const handleInput = useCallback((e) => {
|
||||||
|
setMarkdown(e.target.value);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const [markdown, setMarkdown] = useState("");
|
||||||
|
|
||||||
|
const contentPanel = (
|
||||||
|
<ContentPanel width={ContentPanelWidthSizes.large}>
|
||||||
|
<Script
|
||||||
|
id="autoFitTextArea"
|
||||||
|
strategy="afterInteractive"
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: `
|
||||||
|
const el = document.querySelector("#editorTextArea")
|
||||||
|
el.addEventListener('input', function() {
|
||||||
|
this.style.height = (this.scrollHeight) + 'px';
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-2 gap-4 h-96">
|
||||||
|
<div>
|
||||||
|
<h2>Editor</h2>
|
||||||
|
<textarea
|
||||||
|
id="editorTextArea"
|
||||||
|
onInput={handleInput}
|
||||||
|
onPaste={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
let paste = event.clipboardData.getData("text/html");
|
||||||
|
paste = paste.replaceAll("<html>", "");
|
||||||
|
paste = paste.replaceAll("<body>", "");
|
||||||
|
paste = paste.replaceAll("</body>", "");
|
||||||
|
paste = paste.replaceAll("</html>", "");
|
||||||
|
paste = paste.replaceAll("<!--StartFragment-->", "");
|
||||||
|
paste = paste.replaceAll("<!--EndFragment-->", "");
|
||||||
|
event.target.value = paste;
|
||||||
|
}}
|
||||||
|
className="bg-mid rounded-xl p-8 w-full "
|
||||||
|
value={markdown}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2>Preview</h2>
|
||||||
|
<div className="bg-mid rounded-xl p-8">
|
||||||
|
<Markdawn className="max-w-full" text={markdown} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ContentPanel>
|
||||||
|
);
|
||||||
|
return <AppLayout title="404" langui={langui} contentPanel={contentPanel} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
|
if (context.locale) {
|
||||||
|
const props: EditorProps = {
|
||||||
|
langui: await getWebsiteInterface({
|
||||||
|
language_code: context.locale,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
props: props,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return { props: {} };
|
||||||
|
};
|
|
@ -13,7 +13,7 @@ export default function Home(props: HomeProps): JSX.Element {
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel autoformat={true}>
|
<ContentPanel autoformat={true}>
|
||||||
<div className="grid place-items-center place-content-center w-full gap-5">
|
<div className="grid place-items-center place-content-center w-full gap-5 text-center">
|
||||||
<SVG
|
<SVG
|
||||||
className="w-32 mobile:w-1/2"
|
className="w-32 mobile:w-1/2"
|
||||||
src={"/icons/accords.svg"}
|
src={"/icons/accords.svg"}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import ReturnButton from "components/PanelComponents/ReturnButton";
|
||||||
import SceneBreak from "components/Markdown/SceneBreak";
|
import SceneBreak from "components/Markdown/SceneBreak";
|
||||||
import ThumbnailHeader from "components/Content/ThumbnailHeader";
|
import ThumbnailHeader from "components/Content/ThumbnailHeader";
|
||||||
import AppLayout from "components/AppLayout";
|
import AppLayout from "components/AppLayout";
|
||||||
|
import Markdawn from "components/Markdown/Markdawn";
|
||||||
|
|
||||||
type ContentReadProps = {
|
type ContentReadProps = {
|
||||||
content: GetContentTextQuery;
|
content: GetContentTextQuery;
|
||||||
|
@ -42,12 +43,7 @@ export default function ContentRead(props: ContentReadProps): JSX.Element {
|
||||||
<HorizontalLine />
|
<HorizontalLine />
|
||||||
|
|
||||||
{content.text_set.length > 0 ? (
|
{content.text_set.length > 0 ? (
|
||||||
<Markdown
|
<Markdawn text={content.text_set[0].text} />
|
||||||
className="prose prose-lg text-black pt-12"
|
|
||||||
options={{ overrides: { hr: { component: SceneBreak } } }}
|
|
||||||
>
|
|
||||||
{content.text_set[0].text}
|
|
||||||
</Markdown>
|
|
||||||
) : (
|
) : (
|
||||||
""
|
""
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -51,4 +51,15 @@
|
||||||
*::-webkit-scrollbar-thumb {
|
*::-webkit-scrollbar-thumb {
|
||||||
@apply bg-dark rounded-full border-[3px] border-solid border-light;
|
@apply bg-dark rounded-full border-[3px] border-solid border-light;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* CHANGE PROSE DEFAULTS */
|
||||||
|
|
||||||
|
.prose a {
|
||||||
|
@apply transition-colors underline-offset-2 decoration-dotted underline decoration-dark hover:text-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prose {
|
||||||
|
--tw-prose-bullets: theme("colors.dark") !important;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue