game system nav context

sse endpoint
This commit is contained in:
Emmaline Autumn 2024-09-08 06:43:39 -06:00
parent 84cbea8ce1
commit a2fde9cc79
12 changed files with 37 additions and 89 deletions

View File

@ -1,23 +0,0 @@
"use server";
import { auth } from "@/auth";
import { prisma } from "@/prisma/prismaClient";
import { isEmailVerified } from "@/util/isEmailVerified";
export const createGameSystem = async (name: string) => {
const session = await auth();
if (!session?.user?.id) return null;
if (!isEmailVerified(session.user.id)) return null;
const { id } = await prisma.gameSystem.create({
data: {
name,
authorId: session.user.id,
},
select: {
id: true,
},
});
return id;
};

View File

@ -1,7 +0,0 @@
"use server";
import { prisma } from "@/prisma/prismaClient";
// DEV TOOL ONLY
export async function deleteAllGameSystems() {
await prisma.gameSystem.deleteMany();
}

View File

@ -1,5 +1,5 @@
"use server"; "use server";
import { signIn, signOut } from "@/auth"; import { auth, signIn, signOut } from "@/auth";
export const signInWithDiscord = async () => { export const signInWithDiscord = async () => {
await signIn("discord"); await signIn("discord");
@ -10,3 +10,5 @@ export const signInWithCreds = async (formData: FormData) => {
}; };
export const signOutOfApp = () => signOut(); export const signOutOfApp = () => signOut();
export const getSession = async () => await auth();

View File

@ -1,3 +1,6 @@
// import { setCurrentGameSystem } from "@/actions/GameSystems/client";
import { setCurrentGameSystem } from "@/actions/GameSystems/client";
import { auth } from "@/auth";
import { prisma } from "@/prisma/prismaClient"; import { prisma } from "@/prisma/prismaClient";
import Link from "next/link"; import Link from "next/link";
@ -32,6 +35,10 @@ export default async function GameSystem({
// }, // },
}); });
const session = await auth();
session?.user?.id && (await setCurrentGameSystem(session.user.id, id));
return ( return (
<> <>
<section className="heading"> <section className="heading">

View File

@ -1,6 +1,6 @@
"use client"; "use client";
import { deleteAllGameSystems } from "@/actions/GameSystems/deleteAll"; import { deleteAllGameSystems } from "@/actions/GameSystems/devactions";
import { DevTool } from "@/components/devtools/DevTool"; import { DevTool } from "@/components/devtools/DevTool";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { FC, PropsWithChildren } from "react"; import { FC, PropsWithChildren } from "react";

View File

@ -1,5 +1,5 @@
"use client"; "use client";
import { createGameSystem } from "@/actions/GameSystems/create"; import { createGameSystem } from "@/actions/GameSystems";
import { useToast } from "@/components/toast"; import { useToast } from "@/components/toast";
import { redirect } from "next/navigation"; import { redirect } from "next/navigation";

View File

@ -2,8 +2,12 @@ import { prisma } from "@/prisma/prismaClient";
import CreateGameSystem from "./create"; import CreateGameSystem from "./create";
import { GameSystemsClient } from "./client"; import { GameSystemsClient } from "./client";
import Link from "next/link"; import Link from "next/link";
import { setCurrentGameSystem } from "@/actions/GameSystems/client";
import { auth } from "@/auth";
export default async function GameSystems() { export default async function GameSystems() {
const session = await auth();
session?.user?.id && (await setCurrentGameSystem(session.user.id));
const existingGameSystems = await prisma.gameSystem.findMany({ const existingGameSystems = await prisma.gameSystem.findMany({
orderBy: { orderBy: {
created: "asc", created: "asc",

View File

@ -1,13 +1,6 @@
import type { Metadata } from "next"; import type { Metadata } from "next";
import { Roboto } from "next/font/google"; import { Roboto } from "next/font/google";
import "./globals.css"; import "./globals.css";
import {
BookOpenIcon,
CircleStackIcon,
Cog8ToothIcon,
PuzzlePieceIcon,
QuestionMarkCircleIcon,
} from "@heroicons/react/24/solid";
import Link from "next/link"; import Link from "next/link";
import { DevToolboxContextProvider } from "@/components/devtools/context"; import { DevToolboxContextProvider } from "@/components/devtools/context";
import { RecoilRootClient } from "@/components/recoilRoot"; import { RecoilRootClient } from "@/components/recoilRoot";
@ -15,6 +8,10 @@ import { JotaiProvider } from "@/components/jotaiProvider";
import { Toaster } from "@/components/toast"; import { Toaster } from "@/components/toast";
import { SessionProvider } from "next-auth/react"; import { SessionProvider } from "next-auth/react";
import { User } from "@/components/user/index"; import { User } from "@/components/user/index";
import { getCurrentGameSystem } from "@/actions/GameSystems";
import { Nav } from "@/components/nav";
import { SSE } from "@/components/sse";
import { auth } from "@/auth";
const roboto = Roboto({ subsets: ["latin"], weight: "400" }); const roboto = Roboto({ subsets: ["latin"], weight: "400" });
@ -23,38 +20,12 @@ export const metadata: Metadata = {
description: "Rules and tools for tabletop games!", description: "Rules and tools for tabletop games!",
}; };
export default function RootLayout({ export default async function RootLayout({
children, children,
}: Readonly<{ }: Readonly<{
children: React.ReactNode; children: React.ReactNode;
}>) { }>) {
const navItems = [ const currentGame = await getCurrentGameSystem();
{
to: "/game-systems",
icon: PuzzlePieceIcon,
text: "Game Systems",
},
{
to: "/schemas",
icon: CircleStackIcon,
text: "Schemas",
},
{
to: "/publications",
icon: BookOpenIcon,
text: "Publications",
},
{
to: "/settings",
icon: Cog8ToothIcon,
text: "Settings",
},
{
to: "/help",
icon: QuestionMarkCircleIcon,
text: "How do?",
},
];
return ( return (
<html lang="en"> <html lang="en">
@ -65,19 +36,7 @@ export default function RootLayout({
<h1 className="text-lg font-bold pb-6 border-b dark:border-dark-500 border-primary-600"> <h1 className="text-lg font-bold pb-6 border-b dark:border-dark-500 border-primary-600">
<Link href="/">Tabletop Commander</Link> <Link href="/">Tabletop Commander</Link>
</h1> </h1>
<ul className="my-6 flex flex-col gap-6"> <Nav game={currentGame ?? undefined} />
{navItems.map((n) => (
<li key={"nav-item" + n.text}>
<Link
href={n.to}
className="flex items-center gap-2 group hover:text-purple-300 transition-colors"
>
<n.icon className="w-6 h-6 group-hover:fill-purple-300 transition-colors" />
{n.text}
</Link>
</li>
))}
</ul>
<div className="mt-auto"> <div className="mt-auto">
<User /> <User />
</div> </div>
@ -96,6 +55,7 @@ export default function RootLayout({
<div id="root-portal"></div> <div id="root-portal"></div>
</body> </body>
</SessionProvider> </SessionProvider>
<SSE />
</html> </html>
); );
} }

View File

@ -26,7 +26,6 @@ const tokenize = (body: string) => {
const rx = new RegExp(token.rx); const rx = new RegExp(token.rx);
let match; let match;
while ((match = rx.exec(body)) !== null) { while ((match = rx.exec(body)) !== null) {
if (type === "p") debugger;
const start = match.index; const start = match.index;
const end = rx.lastIndex; const end = rx.lastIndex;
@ -180,9 +179,9 @@ const contentToChildren = (token: Token) => {
}, },
] ]
: undefined, : undefined,
}) }),
), ),
token.children || [] token.children || [],
).filter((c) => c.children?.length || (c.rendersContentOnly && c.content)); ).filter((c) => c.children?.length || (c.rendersContentOnly && c.content));
}; };

View File

@ -80,7 +80,6 @@ export class TTCQueryResolver {
} }
const [res] = this.parser.search(q, stackItem.value as QueryableObject); const [res] = this.parser.search(q, stackItem.value as QueryableObject);
debugger;
if (Dice.isDice(res)) { if (Dice.isDice(res)) {
const value = new Dice(res); const value = new Dice(res);
return { return {

View File

@ -1,13 +1,17 @@
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
output: "standalone", output: "standalone",
webpack(config) { webpack(config, { isServer }) {
config.module.rules.push({ config.module.rules.push({
test: /\.svg$/i, test: /\.svg$/i,
issuer: /\.[jt]sx?$/, issuer: /\.[jt]sx?$/,
use: ["@svgr/webpack"], use: ["@svgr/webpack"],
}); });
if (isServer) {
import("./polyfills/customevent.js");
}
return config; return config;
}, },
}; };

View File

@ -14,9 +14,10 @@ model GameSystem {
authorId String authorId String
followers GameSystemFollows[] followers GameSystemFollows[]
name String @unique name String @unique
created DateTime @default(now()) created DateTime @default(now())
isPublic Boolean @default(false) isPublic Boolean @default(false)
thingUsers User[] @relation("currentGame")
} }
model Schema { model Schema {
@ -106,6 +107,8 @@ model User {
sessions Session[] sessions Session[]
PublicationRevision PublicationRevision[] PublicationRevision PublicationRevision[]
followedSystems GameSystemFollows[] followedSystems GameSystemFollows[]
currentGameSystem GameSystem? @relation("currentGame", fields: [currentGameSystemId], references: [id])
currentGameSystemId String?
name String? name String?
username String? @unique username String? @unique