mirror of
				https://github.com/DerTyp7/explainegy-nextjs.git
				synced 2025-10-30 21:27:12 +01:00 
			
		
		
		
	add api
This commit is contained in:
		| @@ -1,32 +1,23 @@ | ||||
| import React from "react"; | ||||
| import prisma from "../../../../lib/prisma"; | ||||
| import styles from "../../../../styles/modules/TutorialContentTable.module.scss"; | ||||
| import styles from "../../../../styles/modules/ArticleContentTable.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> | ||||
| 	); | ||||
| export default function ContentTable({ contentTableEntries }: { contentTableEntries: ContentTableEntry[] }) { | ||||
|   return ( | ||||
|     <div className={styles.articleContentTable}> | ||||
|       <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> | ||||
|   ); | ||||
| } | ||||
|   | ||||
| @@ -1,82 +1,93 @@ | ||||
| import { marked } from "marked"; | ||||
| import ContentTable from "./ContentTable"; | ||||
| import Sidebar from "./Sidebar"; | ||||
| import styles from "../../../../styles/modules/Tutorial.module.scss"; | ||||
| import styles from "../../../../styles/modules/Article.module.scss"; | ||||
| import LoadMarkdown from "./LoadMarkdown"; | ||||
| import prisma from "../../../../lib/prisma"; | ||||
| import { Article, Category, ContentTableEntry } from "@prisma/client"; | ||||
| import Image from "next/image"; | ||||
| import urlJoin from "url-join"; | ||||
| import { apiUrl } from "../../../global"; | ||||
| import { Prisma } from "@prisma/client"; | ||||
|  | ||||
| export async function GetContentTableEntries( | ||||
| 	article: Article | ||||
| ): Promise<ContentTableEntry[]> { | ||||
| 	const entries = await prisma.contentTableEntry.findMany({ | ||||
| 		where: { articleId: article?.id ?? 1 }, | ||||
| 		orderBy: { orderIndex: "asc" }, | ||||
| 	}); | ||||
| type ArticleWithContentTableEntries = Prisma.ArticleGetPayload<{ include: { contentTableEntries: true } }>; | ||||
| type ArticleWithCategory = Prisma.ArticleGetPayload<{ include: { category: true } }>; | ||||
|  | ||||
| 	return entries; | ||||
| } | ||||
| // export async function GetContentTableEntries(article: Article): Promise<ContentTableEntry[]> { | ||||
| //   const entries = await prisma.contentTableEntry.findMany({ | ||||
| //     where: { articleId: article?.id ?? 1 }, | ||||
| //     orderBy: { orderIndex: "asc" }, | ||||
| //   }); | ||||
|  | ||||
| export async function GetArticle(articleName: string) { | ||||
| 	const article = await prisma.article.findUnique({ | ||||
| 		where: { name: articleName.toLowerCase() ?? "" }, | ||||
| 	}); | ||||
| //   return entries; | ||||
| // } | ||||
|  | ||||
| 	return article; | ||||
| export async function GetArticle(articleName: string): Promise<any> { | ||||
|   const result: Response = await fetch(urlJoin(apiUrl, `articles/${articleName ?? ""}`), { | ||||
|     cache: "force-cache", | ||||
|     next: { revalidate: 60 * 10 }, | ||||
|   }); | ||||
|  | ||||
|   return result.json(); | ||||
| } | ||||
|  | ||||
| function ParseMarkdown(markdown: string): string { | ||||
| 	let result = marked.parse(markdown); | ||||
|  | ||||
| 	return result; | ||||
|   let result = marked.parse(markdown); | ||||
|   return result; | ||||
| } | ||||
|  | ||||
| //* MAIN | ||||
| export default async function ArticlePage({ | ||||
| 	params, | ||||
| }: { | ||||
| 	params: { articleName: string; categoryName: string }; | ||||
| }) { | ||||
| 	const articleName: string = params.articleName | ||||
| 		.toLowerCase() | ||||
| 		.replaceAll("%20", " "); | ||||
| 	const article: Article = await GetArticle(articleName); | ||||
| 	const markdown: string = article?.markdown ?? ""; | ||||
| 	const contentTableEntries: ContentTableEntry[] = await GetContentTableEntries( | ||||
| 		article | ||||
| 	); | ||||
| export default async function ArticlePage({ params }: { params: { articleName: string; categoryName: string } }) { | ||||
|   const articleName: string = params.articleName.toLowerCase().replaceAll("%20", " "); | ||||
|   const article: ArticleWithContentTableEntries = await GetArticle(articleName); | ||||
|   const markdown: string = article?.markdown ?? ""; | ||||
|  | ||||
| 	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> | ||||
| 	); | ||||
|   return ( | ||||
|     <div className={styles.article}> | ||||
|       <ContentTable contentTableEntries={article.contentTableEntries} /> | ||||
|       <div className={styles.tutorialContent}> | ||||
|         <div className={styles.header}> | ||||
|           <p className="text-muted">Published on January 13, 2022</p> | ||||
|  | ||||
|           <h1>{article?.title}</h1> | ||||
|           <div className={styles.tags}> | ||||
|             <a href="#">Docker</a> <a href="#">Setup</a> <a href="#">Ubuntu</a> | ||||
|           </div> | ||||
|           <Image | ||||
|             src={"/images/test.jpg"} | ||||
|             height={350} | ||||
|             width={750} | ||||
|             alt="Image" | ||||
|             quality={100} | ||||
|             placeholder="blur" | ||||
|             blurDataURL="/images/blur.png" | ||||
|             loading="lazy" | ||||
|           /> | ||||
|         </div> | ||||
|         <div | ||||
|           className="markdown" | ||||
|           dangerouslySetInnerHTML={{ | ||||
|             __html: ParseMarkdown(markdown), | ||||
|           }} | ||||
|         ></div> | ||||
|         <LoadMarkdown /> | ||||
|       </div> | ||||
|       <Sidebar /> | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
|  | ||||
| export async function generateStaticParams() { | ||||
| 	const articles = await prisma.article.findMany(); | ||||
|   const articles: ArticleWithCategory[] = await ( | ||||
|     await fetch(urlJoin(apiUrl, `articles/`), { | ||||
|       cache: "force-cache", | ||||
|       next: { revalidate: 60 * 10 }, | ||||
|     }) | ||||
|   ).json(); | ||||
|  | ||||
| 	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 ?? "", | ||||
| 		})) | ||||
| 	); | ||||
|   return await Promise.all( | ||||
|     articles.map(async (article) => ({ | ||||
|       categoryName: article.category?.name ?? "", | ||||
|       articleName: article.name ?? "", | ||||
|     })) | ||||
|   ); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Janis
					Janis