This commit is contained in:
Janis
2023-01-29 20:01:56 +01:00
parent d3e5295832
commit bc29de3255
119 changed files with 26881 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
import { Article } from "@prisma/client";
import { FetchManager } from "../../../../manager/fetchManager";
export default async function ArticleHead({ params }: { params: { articleName: string; categoryName: string } }) {
const articleName: string = params.articleName;
const article: Article = await FetchManager.Article.getByName(articleName);
return (
<>
<title>{article?.title}</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</>
);
}

View File

@@ -0,0 +1,3 @@
export default function ArticleLayout({ children }) {
return <div>{children}</div>;
}

View File

@@ -0,0 +1,63 @@
import ContentTable from "../../../../components/ContentTable";
import Sidebar from "../../../../components/Sidebar";
import styles from "../../../../styles/modules/Article.module.scss";
import Image from "next/image";
import Markdown from "../../../../components/Markdown";
import { ArticleWithIncludes, FetchManager } from "../../../../manager/fetchManager";
import { formatTextToUrlName } from "../../../../utils";
//* MAIN
export default async function ArticlePage({ params }: { params: { articleName: string; categoryName: string } }) {
const articleName: string = formatTextToUrlName(params.articleName);
const article: ArticleWithIncludes = await FetchManager.Article.getByName(articleName);
const dateUpdated: Date = new Date(article.dateUpdated);
const dateCreated: Date = new Date(article.dateCreated);
const dateOptions: Intl.DateTimeFormatOptions = { month: "long", day: "numeric", year: "numeric" };
const markdown: string = article?.markdown ?? "";
return (
<div className={styles.article}>
<ContentTable contentTableData={article.contentTable ? article.contentTable : []} />
<div className={styles.tutorialContent}>
<div className={styles.header}>
<p className={`${styles.dates} text-muted`}>
{`Published on ${dateCreated.toLocaleDateString("en-US", dateOptions)}`}
<br />
{dateUpdated > dateCreated ? `Updated on ${dateUpdated.toLocaleDateString("en-US", dateOptions)}` : ""}
</p>
<h1>{article?.title}</h1>
<div className={styles.tags}>
<a href="#">Docker</a> <a href="#">Setup</a> <a href="#">Ubuntu</a>
</div>
<Image
src={article?.image?.url ?? ""}
height={350}
width={750}
alt={article?.image?.alt ?? ""}
quality={100}
placeholder="blur"
blurDataURL="/images/blur.png"
loading="lazy"
/>
<p>{article?.introduction}</p>
</div>
<Markdown value={markdown} />
</div>
<Sidebar />
</div>
);
}
export async function generateStaticParams() {
// Fetchmanager does not work here
const articles: ArticleWithIncludes[] = await FetchManager.Article.list(false);
return await Promise.all(
articles.map(async (article) => ({
categoryName: article.category?.name ?? "",
articleName: article.name ?? "",
}))
);
}

View File

@@ -0,0 +1,97 @@
import styles from "../../../styles/modules/Category.module.scss";
import Link from "next/link";
import { apiUrl } from "../../../global";
import { Article, Category } from "@prisma/client";
import urlJoin from "url-join";
async function GetAllArticles(categoryName: string): Promise<any> {
const result: Response = await fetch(urlJoin(apiUrl, `articles?categoryName=${categoryName}`), {
cache: "force-cache",
next: { revalidate: 3600 },
});
return result.json();
}
async function GetPopularArticles(categoryName: string): Promise<any> {
const result: Response = await fetch(
urlJoin(apiUrl, `articles?categoryName=${categoryName}&limit=6&orderBy=popularity`),
{
cache: "force-cache",
next: { revalidate: 3600 },
}
);
return result.json();
}
async function GetRecentArticles(categoryName: string): Promise<any> {
const result: Response = await fetch(
urlJoin(apiUrl, `articles?categoryName=${categoryName}&limit=6&orderBy=recent`),
{
cache: "force-cache",
next: { revalidate: 3600 },
}
);
return result.json();
}
async function GetCategory(categoryName: string): Promise<any> {
const result: Response = await fetch(urlJoin(apiUrl, `categories/name/${categoryName}`), {
cache: "force-cache",
next: { revalidate: 3600 },
});
return result.json();
}
export default async function CategoryPage({ params }: { params: { categoryName: string } }) {
const categoryName = params.categoryName.toLowerCase().replaceAll("%20", " ");
const category: Category = await GetCategory(categoryName);
const allArticles: Article[] = await GetAllArticles(categoryName);
const popularArticles: Article[] = await GetPopularArticles(categoryName);
const recentArticles: Article[] = await GetRecentArticles(categoryName);
return (
<div className={styles.category}>
<h1>{category?.title}</h1>
<div className={styles.content}>
<div className={`${styles.showcase} ${styles.smallShowcase}`}>
<h2>Most popular articles</h2>
{popularArticles?.map((a, i) => {
{
return (
<Link key={i} href={`/articles/${category.name}/${a.name}`}>
{a.title}
</Link>
);
}
})}
</div>
{/* <div className={`${styles.showcase} ${styles.smallShowcase}`}>
<h2>Most recent articles</h2>
{recentArticles?.map((a, i) => {
{
return (
<Link key={i} href={`/articles/${category.name}/${a.name}`}>
{a.name}
</Link>
);
}
})}
</div> */}
<div className={styles.showcase}>
<h2>All articles</h2>
{allArticles?.map((a, i) => {
{
return (
<Link key={i} href={`/articles/${category.name}/${a.name}`}>
{a.title}
</Link>
);
}
})}
</div>
</div>
</div>
);
}

33
app/articles/page.tsx Normal file
View File

@@ -0,0 +1,33 @@
import styles from "../../styles/modules/CategoryList.module.scss";
import Link from "next/link";
import { FetchManager } from "../../manager/fetchManager";
export default async function CategoryList() {
const categories = await FetchManager.Category.list();
return (
<div className={styles.categoryList}>
<h1>Overview</h1>
<div className={styles.content}>
<div className={styles.grid}>
{categories?.length > 0
? categories.map((cat, i) => {
return (
<div key={i} className={styles.linkContainer}>
<Link href={`/articles/${cat.name.toLowerCase()}`} style={{ backgroundColor: cat.color }}>
<div className={styles.svgContainer}>
<svg xmlns="http://www.w3.org/2000/svg" viewBox={cat?.svg?.viewbox}>
<path d={cat?.svg?.path} />
</svg>
</div>
{cat.title}
</Link>
</div>
);
})
: "We did not find any categories"}
</div>
</div>
</div>
);
}