diff --git a/src/app/@modal/default.tsx b/src/app/@modal/default.tsx
new file mode 100644
index 0000000..b6a09e7
--- /dev/null
+++ b/src/app/@modal/default.tsx
@@ -0,0 +1,4 @@
+export default function Default() {
+ return null
+}
+
diff --git a/src/app/_components/AdminWrap.tsx b/src/app/_components/AdminWrap.tsx
new file mode 100644
index 0000000..0851daf
--- /dev/null
+++ b/src/app/_components/AdminWrap.tsx
@@ -0,0 +1,9 @@
+import { isAdmin } from "../actions"
+
+export default async function AdminWrap({children,}: Readonly<{ children: React.ReactNode }>) {
+ if (await isAdmin()) {
+ return <>{children}>
+ }
+ return (<>>)
+}
+
diff --git a/src/app/_components/TopNav.tsx b/src/app/_components/TopNav.tsx
new file mode 100644
index 0000000..2d8226e
--- /dev/null
+++ b/src/app/_components/TopNav.tsx
@@ -0,0 +1,25 @@
+import Link from "next/link"
+import AdminWrap from "./AdminWrap"
+import { SignedIn, SignedOut, SignUpButton, UserButton } from "@clerk/nextjs"
+
+export default function TopNav() {
+ return (
+
+ )
+}
+
diff --git a/src/app/actions.ts b/src/app/actions.ts
new file mode 100644
index 0000000..92a89b0
--- /dev/null
+++ b/src/app/actions.ts
@@ -0,0 +1,8 @@
+'use server'
+import { auth } from "@clerk/nextjs/server"
+import { env } from "~/env"
+
+export async function isAdmin() {
+ const userid = (await auth()).userId
+ return (userid == env.ADMIN_USER_CLERK_ID)
+}
diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx
index cd044d9..96958b5 100644
--- a/src/app/admin/page.tsx
+++ b/src/app/admin/page.tsx
@@ -1,6 +1,6 @@
import { SignedIn } from "@clerk/nextjs";
-const AdminPage = async () => {
+export default function AdminPage() {
return (
@@ -11,5 +11,3 @@ const AdminPage = async () => {
)
}
-
-export default AdminPage;
diff --git a/src/app/blog/layout.tsx b/src/app/blog/layout.tsx
new file mode 100644
index 0000000..edef18a
--- /dev/null
+++ b/src/app/blog/layout.tsx
@@ -0,0 +1,10 @@
+'use client'
+export default function RootLayout({
+ children,
+}: Readonly<{ children: React.ReactNode}>) {
+ return (
+ <>
+ {children}
+ >
+ )
+}
diff --git a/src/app/cv/layout.tsx b/src/app/cv/layout.tsx
new file mode 100644
index 0000000..edef18a
--- /dev/null
+++ b/src/app/cv/layout.tsx
@@ -0,0 +1,10 @@
+'use client'
+export default function RootLayout({
+ children,
+}: Readonly<{ children: React.ReactNode}>) {
+ return (
+ <>
+ {children}
+ >
+ )
+}
diff --git a/src/app/cv/page.tsx b/src/app/cv/page.tsx
new file mode 100644
index 0000000..4b97bf0
--- /dev/null
+++ b/src/app/cv/page.tsx
@@ -0,0 +1,18 @@
+import { getCvCategories } from "~/server/db/query"
+
+export default async function CvPage() {
+ const cvCategories = await getCvCategories();
+ return (
+
+ {cvCategories.map((category) => {
+ return (
+
+ )
+ })}
+
+ )
+}
diff --git a/src/app/fun/layout.tsx b/src/app/fun/layout.tsx
new file mode 100644
index 0000000..edef18a
--- /dev/null
+++ b/src/app/fun/layout.tsx
@@ -0,0 +1,10 @@
+'use client'
+export default function RootLayout({
+ children,
+}: Readonly<{ children: React.ReactNode}>) {
+ return (
+ <>
+ {children}
+ >
+ )
+}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 8b613d2..4b5f604 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,11 +1,9 @@
import "~/styles/globals.css";
-
-import Link from "next/link";
import type { Metadata } from "next";
import { Geist } from "next/font/google";
-import { ClerkProvider, SignedIn, SignedOut, SignUpButton, UserButton } from "@clerk/nextjs";
-import { auth } from "@clerk/nextjs/server";
-import { env } from "~/env";
+import { ClerkProvider } from "@clerk/nextjs";
+
+import TopNav from "./_components/TopNav";
export const metadata: Metadata = {
title: "Gregor Lohaus",
description: "My Personal Website",
@@ -17,45 +15,18 @@ const geist = Geist({
variable: "--font-geist-sans",
});
-const AdminWrap = async ({children,}: Readonly<{ children: React.ReactNode }>) => {
- const userid = (await auth()).userId
- const isAdmin = (userid == env.ADMIN_USER_CLERK_ID)
- if (isAdmin) {
- return <>{children}>
- }
- return (<>>)
-}
-
-const TopNav = async () => {
- return (
-
- )
-}
export default function RootLayout({
children,
-}: Readonly<{ children: React.ReactNode }>) {
+ modal
+}: Readonly<{ children: React.ReactNode, modal: React.ReactNode }>) {
return (
{children}
+ {modal}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 69efec8..ad1658e 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,6 +1,4 @@
-export const dynamic = "force-dynamic"
-
-export default async function HomePage() {
+export default function HomePage() {
return (
diff --git a/src/app/projects/layout.tsx b/src/app/projects/layout.tsx
new file mode 100644
index 0000000..edef18a
--- /dev/null
+++ b/src/app/projects/layout.tsx
@@ -0,0 +1,10 @@
+'use client'
+export default function RootLayout({
+ children,
+}: Readonly<{ children: React.ReactNode}>) {
+ return (
+ <>
+ {children}
+ >
+ )
+}
diff --git a/src/env.js b/src/env.js
index 5be4346..29c5a1c 100644
--- a/src/env.js
+++ b/src/env.js
@@ -8,6 +8,24 @@ export const env = createEnv({
*/
server: {
DATABASE_URL: z.string().url(),
+ DATABASE_URL_UNPOOLED: z.string().url(),
+
+ PGHOST: z.string(),
+ PGHOST_UNPOOLED: z.string(),
+ PGUSER: z.string(),
+ PGDATABASE: z.string(),
+ PGPASSWORD: z.string(),
+
+ POSTGRES_URL: z.string().url(),
+ POSTGRES_URL_NON_POOLING: z.string().url(),
+ POSTGRES_USER: z.string(),
+ POSTGRES_HOST: z.string(),
+ POSTGRES_PASSWORD: z.string(),
+ POSTGRES_DATABASE: z.string(),
+ POSTGRES_URL_NO_SSL: z.string().url(),
+ POSTGRES_PRISMA_URL: z.string().url(),
+
+ CLERK_SECRET_KEY: z.string(),
ADMIN_USER_CLERK_ID: z.string(),
NODE_ENV: z
.enum(["development", "test", "production"])
@@ -20,6 +38,7 @@ export const env = createEnv({
* `NEXT_PUBLIC_`.
*/
client: {
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string()
// NEXT_PUBLIC_CLIENTVAR: z.string(),
},
@@ -29,9 +48,24 @@ export const env = createEnv({
*/
runtimeEnv: {
DATABASE_URL: process.env.DATABASE_URL,
+ DATABASE_URL_UNPOOLED: process.env.DATABASE_URL,
+ PGHOST: process.env.PGHOST,
+ PGHOST_UNPOOLED: process.env.PGHOST_UNPOOLED,
+ PGUSER: process.env.PGUSER,
+ PGDATABASE: process.env.PGDATABASE,
+ PGPASSWORD: process.env.PGPASSWORD,
+ POSTGRES_URL: process.env.POSTGRES_URL,
+ POSTGRES_URL_NON_POOLING: process.env.POSTGRES_URL_NON_POOLING,
+ POSTGRES_USER: process.env.POSTGRES_USER,
+ POSTGRES_HOST: process.env.POSTGRES_HOST,
+ POSTGRES_PASSWORD: process.env.POSTGRES_PASSWORD,
+ POSTGRES_DATABASE: process.env.POSTGRES_DATABASE,
+ POSTGRES_URL_NO_SSL: process.env.POSTGRES_URL_NO_SSL,
+ POSTGRES_PRISMA_URL: process.env.POSTGRES_PRISMA_URL,
ADMIN_USER_CLERK_ID: process.env.ADMIN_USER_CLERK_ID,
+ CLERK_SECRET_KEY: process.env.CLERK_SECRET_KEY,
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,
NODE_ENV: process.env.NODE_ENV,
- // NEXT_PUBLIC_CLIENTVAR: process.env.NEXT_PUBLIC_CLIENTVAR,
},
/**
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially
diff --git a/src/server/db/query.ts b/src/server/db/query.ts
index 76d36d7..f889ad5 100644
--- a/src/server/db/query.ts
+++ b/src/server/db/query.ts
@@ -1 +1,9 @@
import "server-only"
+import { db } from "."
+
+export async function getCvCategories() {
+ const categories = await db.query.cvCategory.findMany({
+ orderBy: (model, {desc} ) => desc(model.name)
+ })
+ return categories;
+}