Archived
add prisma
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
# Environment variables declared in this file are automatically made available to Prisma.
|
||||
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema
|
||||
|
||||
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
|
||||
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
|
||||
|
||||
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres?schema=explainegy"
|
||||
+6
-5
@@ -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>
|
||||
) : (
|
||||
""
|
||||
@@ -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" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -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 ?? "",
|
||||
}));
|
||||
}
|
||||
@@ -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" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -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,
|
||||
}));
|
||||
}
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
version: "3.9"
|
||||
services:
|
||||
postgres:
|
||||
image: postgres
|
||||
image: postgres:latest
|
||||
container_name: explainegy_postgres
|
||||
volumes:
|
||||
- ./docker_data/postgres:/var/lib/postgresql/data
|
||||
@@ -17,7 +17,7 @@ services:
|
||||
test: "exit 0"
|
||||
|
||||
pgadmin:
|
||||
image: dpage/pgadmin4
|
||||
image: dpage/pgadmin4:latest
|
||||
container_name: explainegy_pgadmin
|
||||
restart: always
|
||||
environment:
|
||||
@@ -26,7 +26,7 @@ services:
|
||||
ports:
|
||||
- "5050:80"
|
||||
volumes:
|
||||
- ./docker/servers.json:/pgadmin4/servers.json # preconfigured servers/connections
|
||||
- ./docker/pgpass:/pgpass # passwords for the connections in this file
|
||||
- ./docker_data/servers.json:/pgadmin4/servers.json # preconfigured servers/connections
|
||||
- ./docker_data/pgpass:/pgpass # passwords for the connections in this file
|
||||
depends_on:
|
||||
- "postgres"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,8 +1,8 @@
|
||||
1
|
||||
/var/lib/postgresql/data
|
||||
1671907198
|
||||
1672100396
|
||||
5432
|
||||
/var/run/postgresql
|
||||
*
|
||||
699789 5
|
||||
699789 0
|
||||
ready
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"Servers": {
|
||||
"1": {
|
||||
"Name": "trading_postgis",
|
||||
"Group": "trading_postgis_group",
|
||||
"Name": "explainegy_postgres",
|
||||
"Group": "explainegy_postgres_group",
|
||||
"Host": "host.docker.internal",
|
||||
"Port": 5432,
|
||||
"MaintenanceDB": "postgres",
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import { getFirestore } from "@firebase/firestore";
|
||||
import { getStorage } from "firebase/storage";
|
||||
import { initializeApp } from "firebase/app";
|
||||
|
||||
const firebaseConfig = {
|
||||
apiKey: "AIzaSyB4U9wobUn7hpqt-gVuNQJPdhfpVdSGPIg",
|
||||
authDomain: "next-tutorials-7e130.firebaseapp.com",
|
||||
projectId: "next-tutorials-7e130",
|
||||
storageBucket: "next-tutorials-7e130.appspot.com",
|
||||
messagingSenderId: "500863392288",
|
||||
appId: "1:500863392288:web:4f2f667fef3a571b1d3a45",
|
||||
};
|
||||
|
||||
const app = initializeApp(firebaseConfig);
|
||||
|
||||
export const db = getFirestore();
|
||||
export const storage = getStorage(app);
|
||||
@@ -0,0 +1,14 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
let prisma: PrismaClient;
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
prisma = new PrismaClient();
|
||||
} else {
|
||||
if (!global.prisma) {
|
||||
global.prisma = new PrismaClient();
|
||||
}
|
||||
prisma = global.prisma;
|
||||
}
|
||||
|
||||
export default prisma;
|
||||
Generated
+1158
-1562
File diff suppressed because it is too large
Load Diff
+11
-5
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "explainegy",
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
@@ -10,25 +10,31 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@next/font": "13.0.7",
|
||||
"@prisma/client": "^4.8.0",
|
||||
"@types/marked": "^4.0.8",
|
||||
"@types/node": "18.11.17",
|
||||
"@types/pg-promise": "^5.4.3",
|
||||
"@types/react": "18.0.26",
|
||||
"@types/react-dom": "18.0.9",
|
||||
"encoding": "^0.1.13",
|
||||
"eslint": "8.30.0",
|
||||
"eslint-config-next": "13.0.7",
|
||||
"firebase": "^9.15.0",
|
||||
"marked": "^4.2.4",
|
||||
"next": "^13.0.8-canary.0",
|
||||
"next": "^13.1.1-canary.1",
|
||||
"node-html-parser": "^6.1.4",
|
||||
"pg": "^8.8.0",
|
||||
"pg-promise": "^10.15.4",
|
||||
"prismjs": "^1.29.0",
|
||||
"react": "18.2.0",
|
||||
"react-code-blocks": "^0.0.9-0",
|
||||
"react-dom": "18.2.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"sass": "^1.57.0",
|
||||
"typeorm": "^0.3.11",
|
||||
"typescript": "4.9.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/prismjs": "^1.26.0"
|
||||
"@types/node": "^18.11.17",
|
||||
"@types/prismjs": "^1.26.0",
|
||||
"prisma": "^4.8.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
model Article {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @unique
|
||||
title String @unique
|
||||
markdown String
|
||||
contentTableEntries ContentTableEntry[]
|
||||
dateCreated DateTime @default(now())
|
||||
dateUpdated DateTime @default(now())
|
||||
}
|
||||
|
||||
model ContentTableEntry {
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
anchor String
|
||||
orderIndex Int
|
||||
articleId Int
|
||||
article Article @relation(fields: [articleId], references: [id])
|
||||
dateCreated DateTime @default(now())
|
||||
dateUpdated DateTime @default(now())
|
||||
}
|
||||
Reference in New Issue
Block a user