mirror of
https://github.com/DerTyp7/explainegy-nextjs.git
synced 2025-10-30 13:17:13 +01:00
removed pg
This commit is contained in:
32
app/articles/[categoryName]/[articleName]/ContentTable.tsx
Normal file
32
app/articles/[categoryName]/[articleName]/ContentTable.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import React from "react";
|
||||
import prisma from "../../../../lib/prisma";
|
||||
import styles from "../../../../styles/TutorialContentTable.module.scss";
|
||||
import { Article, ContentTableEntry } from "@prisma/client";
|
||||
|
||||
export default function ContentTable({
|
||||
contentTableEntries,
|
||||
}: {
|
||||
contentTableEntries: ContentTableEntry[];
|
||||
}) {
|
||||
return (
|
||||
<div className={styles.tutorialContentTable}>
|
||||
<div className={styles.stickyContainer}>
|
||||
<div className={styles.list}>
|
||||
<h2>Contents</h2>
|
||||
{contentTableEntries?.map((e, i) => {
|
||||
return (
|
||||
<a key={i} href={"#" + e.anchor}>
|
||||
{e.title}
|
||||
</a>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
{contentTableEntries?.length < 15 ? (
|
||||
<div className={styles.adContainer}>Future advertisement</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
41
app/articles/[categoryName]/[articleName]/LoadMarkdown.tsx
Normal file
41
app/articles/[categoryName]/[articleName]/LoadMarkdown.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
"use client";
|
||||
import React from "react";
|
||||
import { useEffect } from "react";
|
||||
|
||||
import Prism from "prismjs";
|
||||
import "../../../../styles/prism_themes/prism-one-dark.css";
|
||||
//import "../../../styles/prism_themes/prism-one-light.css";
|
||||
|
||||
export default function LoadMarkdown() {
|
||||
useEffect(() => {
|
||||
document.querySelectorAll("pre").forEach((pre) => {
|
||||
if (pre.classList.length < 1) {
|
||||
pre.classList.add("language-");
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelectorAll("code").forEach((c) => {
|
||||
if (c.classList.length < 1) {
|
||||
c.classList.add("language-");
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelectorAll("blockquote").forEach((bq) => {
|
||||
bq.classList.add("blockquote");
|
||||
});
|
||||
|
||||
document.querySelectorAll("li").forEach((li) => {
|
||||
let paragraphText = "";
|
||||
li.querySelectorAll("p").forEach((p) => {
|
||||
paragraphText = p.innerHTML;
|
||||
});
|
||||
|
||||
if (paragraphText != "") {
|
||||
li.innerHTML = paragraphText;
|
||||
}
|
||||
});
|
||||
|
||||
Prism.highlightAll();
|
||||
}, []);
|
||||
return <div></div>;
|
||||
}
|
||||
28
app/articles/[categoryName]/[articleName]/Sidebar.tsx
Normal file
28
app/articles/[categoryName]/[articleName]/Sidebar.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import React from "react";
|
||||
import styles from "../../../../styles/Sidebar.module.scss";
|
||||
export default function Sidebar() {
|
||||
return (
|
||||
<div className={styles.sidebar}>
|
||||
<div className={styles.stickyContainer}>
|
||||
<div className={styles.sidebarContainer}>
|
||||
<h3>Popular</h3>
|
||||
<a href="#"> Set up Docker</a>
|
||||
<a href="#"> Set up Docker</a>
|
||||
<a href="#"> Set up Docker</a>
|
||||
<a href="#"> Set up Docker</a>
|
||||
<a href="#"> Set up Docker</a>
|
||||
</div>
|
||||
|
||||
<div className={styles.sidebarContainer}>
|
||||
<h3>Related</h3>
|
||||
<a href="#"> Set up Docker</a>
|
||||
<a href="#"> Set up Docker</a>
|
||||
<a href="#"> Set up Docker</a>
|
||||
<a href="#"> Set up Docker</a>
|
||||
<a href="#"> Set up Docker</a>
|
||||
</div>
|
||||
<div className={styles.adContainer}>Future advertisement</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
17
app/articles/[categoryName]/[articleName]/head.tsx
Normal file
17
app/articles/[categoryName]/[articleName]/head.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Article } from "@prisma/client";
|
||||
import { GetArticle } from "./page";
|
||||
|
||||
export default async function Head({
|
||||
params,
|
||||
}: {
|
||||
params: { articleName: string; categoryName: 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" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
4
app/articles/[categoryName]/[articleName]/layout.tsx
Normal file
4
app/articles/[categoryName]/[articleName]/layout.tsx
Normal file
@@ -0,0 +1,4 @@
|
||||
import "../../../../styles/markdown.scss";
|
||||
export default function Layout({ children }) {
|
||||
return <div>{children}</div>;
|
||||
}
|
||||
80
app/articles/[categoryName]/[articleName]/page.tsx
Normal file
80
app/articles/[categoryName]/[articleName]/page.tsx
Normal file
@@ -0,0 +1,80 @@
|
||||
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, Category, 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; categoryName: 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();
|
||||
|
||||
async function GetCategory(categoryId: number): Promise<Category> {
|
||||
return await prisma.category.findUnique({ where: { id: categoryId } });
|
||||
}
|
||||
|
||||
return await Promise.all(
|
||||
articles.map(async (article) => ({
|
||||
categoryName: (await GetCategory(article.categoryId)).name ?? "",
|
||||
articleName: article.name ?? "",
|
||||
}))
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user