add prisma

This commit is contained in:
Janis
2022-12-27 01:57:49 +01:00
parent df3942bcbd
commit ff723b2402
91 changed files with 1323 additions and 1704 deletions

View File

@@ -1,18 +1,19 @@
import React from "react";
import { TutorialMeta } from "./page";
import prisma from "../../../lib/prisma";
import styles from "../../../styles/TutorialContentTable.module.scss";
import { Article, ContentTableEntry } from "@prisma/client";
export default function ContentTable({
tutorialMeta,
contentTableEntries,
}: {
tutorialMeta: TutorialMeta;
contentTableEntries: ContentTableEntry[];
}) {
return (
<div className={styles.tutorialContentTable}>
<div className={styles.stickyContainer}>
<div className={styles.list}>
<h2>Contents</h2>
{tutorialMeta?.contentTable?.map((e, i) => {
{contentTableEntries?.map((e, i) => {
return (
<a key={i} href={"#" + e.anchor}>
{e.title}
@@ -20,7 +21,7 @@ export default function ContentTable({
);
})}
</div>
{tutorialMeta?.contentTable?.length < 15 ? (
{contentTableEntries?.length < 15 ? (
<div className={styles.adContainer}>Future advertisement</div>
) : (
""

View File

@@ -0,0 +1,17 @@
import { Article } from "@prisma/client";
import { GetArticle } from "./page";
export default async function Head({
params,
}: {
params: { articleName: string };
}) {
const articleName: string = params.articleName;
const article: Article = await GetArticle(articleName);
return (
<>
<title>{article.title}</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</>
);
}

View File

@@ -0,0 +1,73 @@
import { marked } from "marked";
import ContentTable from "./ContentTable";
import Sidebar from "./Sidebar";
import styles from "../../../styles/Tutorial.module.scss";
import LoadMarkdown from "./LoadMarkdown";
import prisma from "../../../lib/prisma";
import { Article, ContentTableEntry } from "@prisma/client";
export async function GetContentTableEntries(
article: Article
): Promise<ContentTableEntry[]> {
const entries = await prisma.contentTableEntry.findMany({
where: { article: article },
orderBy: { orderIndex: "asc" },
});
return entries;
}
export async function GetArticle(articleName: string) {
const article = await prisma.article.findUnique({
where: { name: articleName.toLowerCase() },
});
return article;
}
function ParseMarkdown(markdown: string): string {
let result = marked.parse(markdown);
return result;
}
//* MAIN
export default async function Tutorial({
params,
}: {
params: { articleName: string };
}) {
const articleName: string = params.articleName;
const article: Article = await GetArticle(articleName);
const markdown: string = article.markdown;
const contentTableEntries: ContentTableEntry[] = await GetContentTableEntries(
article
);
return (
<div className={styles.tutorial}>
<ContentTable contentTableEntries={contentTableEntries} />
<div className={styles.tutorialContent}>
<div className={styles.head}>
<h1>{article.title}</h1>
</div>
<div
className="markdown"
dangerouslySetInnerHTML={{
__html: ParseMarkdown(markdown),
}}
></div>
<LoadMarkdown />
</div>
<Sidebar />
</div>
);
}
export async function generateStaticParams() {
const articles = await prisma.article.findMany();
return articles.map((article) => ({
articleName: article.name ?? "",
}));
}

View File

@@ -1,15 +0,0 @@
import { GetTutorialMeta, TutorialMeta } from "./page";
export default async function Head({
params,
}: {
params: { tutorialId: string };
}) {
const tutorialId: string = params.tutorialId;
const tutorialMeta: TutorialMeta = await GetTutorialMeta(tutorialId);
return (
<>
<title>{tutorialMeta.title}</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</>
);
}

View File

@@ -1,92 +0,0 @@
import { marked } from "marked";
import { db, storage } from "../../../firebase-config";
import { collection, doc, getDoc, getDocs } from "firebase/firestore";
import { getDownloadURL, ref } from "firebase/storage";
import ContentTable from "./ContentTable";
import Sidebar from "./Sidebar";
import styles from "../../../styles/Tutorial.module.scss";
import LoadMarkdown from "./LoadMarkdown";
import Head from "next/head";
export type ContentTable = {
anchor: string;
title: string;
};
export type TutorialMeta = {
id: string;
title: string;
contentTable: ContentTable[];
};
export async function GetTutorialMeta(
tutorialId: string
): Promise<TutorialMeta> {
const firebaseData = await getDoc(doc(db, "tutorials", tutorialId));
const firebaseJsonData = firebaseData.data();
const tutorial: TutorialMeta = {
id: tutorialId,
title: firebaseJsonData?.title ?? "Tutorial not found!",
contentTable: firebaseJsonData?.contentTable ?? [],
};
return tutorial;
}
async function FetchTutorialMarkdown(tutorialId: string) {
try {
const url = await getDownloadURL(
ref(storage, `markdowns/${tutorialId}.md`)
);
const data = await fetch(url, {
next: { revalidate: 30 * 60 },
});
return await data.text();
} catch {
return "";
}
}
function ParseMarkdown(markdown: string): string {
let result = marked.parse(markdown);
return result;
}
//* MAIN
export default async function Tutorial({
params,
}: {
params: { tutorialId: string };
}) {
const tutorialId: string = params.tutorialId;
const tutorialMeta: TutorialMeta = await GetTutorialMeta(tutorialId);
const markdown: string = await FetchTutorialMarkdown(tutorialId);
return (
<div className={styles.tutorial}>
<ContentTable tutorialMeta={tutorialMeta} />
<div className={styles.tutorialContent}>
<div className={styles.head}>
<h1>{tutorialMeta.title}</h1>
</div>
<div
className="markdown"
dangerouslySetInnerHTML={{
__html: ParseMarkdown(markdown),
}}
></div>
<LoadMarkdown />
</div>
<Sidebar />
</div>
);
}
export async function generateStaticParams() {
const data = await getDocs(collection(db, "tutorials"));
return data.docs.map((doc) => ({
tutorialId: doc.id,
}));
}