This commit is contained in:
nmcnew
2024-09-14 14:35:02 -06:00
parent 693b204471
commit 7a1700ca71
25 changed files with 1751 additions and 338 deletions

1504
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -27,7 +27,7 @@
"postcss": "^8.4.41",
"prettier": "^3.1.1",
"prettier-plugin-svelte": "^3.1.2",
"prisma": "^5.18.0",
"prisma": "^5.19.0",
"svelte": "^5.0.0-next.1",
"svelte-check": "^3.6.0",
"tailwindcss": "^3.4.10",
@@ -37,5 +37,9 @@
"vite": "^5.0.3",
"vitest": "^2.0.0"
},
"type": "module"
"type": "module",
"dependencies": {
"@prisma/client": "^5.19.0",
"clerk-sveltekit": "^0.4.2"
}
}

View File

@@ -0,0 +1,169 @@
-- CreateEnum
CREATE TYPE "PhaseType" AS ENUM ('DOUBLE_ELIM', 'SINGLE_ELIM', 'ROUND_ROBIN');
-- CreateTable
CREATE TABLE "User" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"created" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "UserRole" (
"userId" TEXT NOT NULL,
"roleId" INTEGER NOT NULL,
CONSTRAINT "UserRole_pkey" PRIMARY KEY ("userId","roleId")
);
-- CreateTable
CREATE TABLE "Role" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
CONSTRAINT "Role_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Tournament" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"slug" TEXT,
"creatorUserId" TEXT NOT NULL,
"created" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Tournament_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Event" (
"id" TEXT NOT NULL,
"gameId" INTEGER NOT NULL,
"title" TEXT NOT NULL,
"tournamentId" TEXT NOT NULL,
"created" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Event_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Phase" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"type" "PhaseType" NOT NULL,
"bracketCount" INTEGER NOT NULL,
"phaseWinnerCount" INTEGER NOT NULL,
"eventId" TEXT NOT NULL,
"created" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Phase_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Bracket" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"created" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"phaseId" TEXT,
CONSTRAINT "Bracket_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Player" (
"id" SERIAL NOT NULL,
"name" TEXT,
"userId" TEXT NOT NULL,
"created" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"userConfirmed" BOOLEAN NOT NULL DEFAULT false,
CONSTRAINT "Player_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "EventPlayer" (
"eventId" TEXT NOT NULL,
"playerId" INTEGER NOT NULL,
"seed" INTEGER NOT NULL,
"manuallySeeded" BOOLEAN NOT NULL DEFAULT false,
CONSTRAINT "EventPlayer_pkey" PRIMARY KEY ("eventId","playerId")
);
-- CreateTable
CREATE TABLE "Game" (
"id" SERIAL NOT NULL,
"title" TEXT NOT NULL,
"slug" TEXT,
"created" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Game_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "_admins" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL
);
-- CreateTable
CREATE TABLE "_moderators" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL
);
-- CreateIndex
CREATE UNIQUE INDEX "_admins_AB_unique" ON "_admins"("A", "B");
-- CreateIndex
CREATE INDEX "_admins_B_index" ON "_admins"("B");
-- CreateIndex
CREATE UNIQUE INDEX "_moderators_AB_unique" ON "_moderators"("A", "B");
-- CreateIndex
CREATE INDEX "_moderators_B_index" ON "_moderators"("B");
-- AddForeignKey
ALTER TABLE "UserRole" ADD CONSTRAINT "UserRole_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "UserRole" ADD CONSTRAINT "UserRole_roleId_fkey" FOREIGN KEY ("roleId") REFERENCES "Role"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Tournament" ADD CONSTRAINT "Tournament_creatorUserId_fkey" FOREIGN KEY ("creatorUserId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Event" ADD CONSTRAINT "Event_gameId_fkey" FOREIGN KEY ("gameId") REFERENCES "Game"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Event" ADD CONSTRAINT "Event_tournamentId_fkey" FOREIGN KEY ("tournamentId") REFERENCES "Tournament"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Phase" ADD CONSTRAINT "Phase_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Bracket" ADD CONSTRAINT "Bracket_phaseId_fkey" FOREIGN KEY ("phaseId") REFERENCES "Phase"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Player" ADD CONSTRAINT "Player_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "EventPlayer" ADD CONSTRAINT "EventPlayer_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "EventPlayer" ADD CONSTRAINT "EventPlayer_playerId_fkey" FOREIGN KEY ("playerId") REFERENCES "Player"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_admins" ADD CONSTRAINT "_admins_A_fkey" FOREIGN KEY ("A") REFERENCES "Tournament"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_admins" ADD CONSTRAINT "_admins_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_moderators" ADD CONSTRAINT "_moderators_A_fkey" FOREIGN KEY ("A") REFERENCES "Tournament"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_moderators" ADD CONSTRAINT "_moderators_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"

View File

@@ -11,92 +11,121 @@ datasource db {
}
model User {
id String @id @default(uuid(7))
name String
created DateTime @default(now())
id String @id @default(uuid(7))
name String
created DateTime @default(now())
userRoles UserRole[]
auth UserAuth[]
tournamntsAdministrating Tournament[] @relation("admins")
tournamentsModerating Tournament[] @relation("moderators")
Tournament Tournament[]
Player Player[]
}
model UserAuth {
id Int @id @default(autoincrement())
user User @relation(fields: [userId], references: [id])
userId String
provider AuthProvider @relation(fields: [providerId], references: [id])
providerId Int
value String
}
model AuthProvider {
id Int @id @default(autoincrement())
name String
providerValue String
userAuth UserAuth[]
}
model UserRole {
user User @relation(fields: [userId], references: [id])
userId String
role Role @relation(fields: [roleId], references: [id])
roleId Int
@@id([userId, roleId])
user User @relation(fields: [userId], references: [id])
userId String
role Role @relation(fields: [roleId], references: [id])
roleId Int
@@id([userId, roleId])
}
model Role {
id Int @id @default(autoincrement())
name String
id Int @id @default(autoincrement())
name String
userRoles UserRole[]
}
model Tournament {
id String @id @default(uuid(7))
name String
slug String?
creator User @relation(fields: [creatorUserId], references: [id])
creatorUserId String
created DateTime @default(now())
admins User[]
moderators User[]
events Event[]
id String @id @default(uuid(7))
name String
slug String?
creator User @relation(fields: [creatorUserId], references: [id])
creatorUserId String
created DateTime @default(now())
admins User[] @relation("admins")
moderators User[] @relation("moderators")
events Event[]
}
model Event {
id String @id @default(uuid(7))
game Game @relation(fields: [gameId], references: [id])
gameId Int
entrants EventPlayer[]
title String
phases Phase[]
tournament Tournament @relation(fields: [tournamentId], references: [id])
tournamentId String
created DateTime @default(now())
id String @id @default(uuid(7))
game Game @relation(fields: [gameId], references: [id])
gameId Int
entrants EventPlayer[]
title String
phases Phase[]
tournament Tournament @relation(fields: [tournamentId], references: [id])
tournamentId String
created DateTime @default(now())
}
enum PhaseType {
DOUBLE_ELIM
SINGLE_ELIM
ROUND_ROBIN
DOUBLE_ELIM
SINGLE_ELIM
ROUND_ROBIN
}
}
model Phase {
id String @id @default(uuid(7))
name String
type PhaseType
bracketCount Int
phaseWinnerCount Int
event Event @relation(fields: [eventId], references: [id])
eventId String
created DateTime @default(now())
brackets Bracket[]
id String @id @default(uuid(7))
name String
type PhaseType
bracketCount Int
phaseWinnerCount Int
event Event @relation(fields: [eventId], references: [id])
eventId String
created DateTime @default(now())
brackets Bracket[]
}
model Bracket {
id Int @id @default(autoincrement())
name String
created DateTime @default(now())
id Int @id @default(autoincrement())
name String
created DateTime @default(now())
Phase Phase? @relation(fields: [phaseId], references: [id])
phaseId String?
}
model Player {
id Int @id @default(autoincrement())
name String?
user User? @relation(fields: [userId], references: [id])
userId String
created DateTime @default(now())
userConfirmed Boolean @default(false)
id Int @id @default(autoincrement())
name String?
user User? @relation(fields: [userId], references: [id])
userId String
created DateTime @default(now())
userConfirmed Boolean @default(false)
EventPlayer EventPlayer[]
}
model EventPlayer {
event Event @relation(fields: [eventId], references: [id])
eventId String
player Player @relation(fields: [playerId], references: [id])
playerId Int
seed Int
manuallySeeded Boolean @default(false)
@@id ([eventId, playerId])
event Event @relation(fields: [eventId], references: [id])
eventId String
player Player @relation(fields: [playerId], references: [id])
playerId Int
seed Int
manuallySeeded Boolean @default(false)
@@id([eventId, playerId])
}
model Game {
id Int @id @default(autoincrement())
title String
slug String?
created DateTime @default(now())
id Int @id @default(autoincrement())
title String
slug String?
created DateTime @default(now())
Event Event[]
}

14
src/hooks.client.ts Normal file
View File

@@ -0,0 +1,14 @@
import type { HandleClientError } from '@sveltejs/kit'
import { initializeClerkClient } from 'clerk-sveltekit/client'
import { PUBLIC_CLERK_PUBLISHABLE_KEY } from '$env/static/public'
initializeClerkClient(PUBLIC_CLERK_PUBLISHABLE_KEY, {
afterSignInUrl: '/admin/',
afterSignUpUrl: '/admin/',
signInUrl: '/sign-in',
signUpUrl: '/sign-up',
})
export const handleError: HandleClientError = async ({ error, event }) => {
console.error(error, event)
}

22
src/hooks.server.ts Normal file
View File

@@ -0,0 +1,22 @@
import type { Handle } from '@sveltejs/kit'
import { sequence } from '@sveltejs/kit/hooks'
import { handleClerk } from 'clerk-sveltekit/server'
import { CLERK_SECRET_KEY } from '$env/static/private'
import prisma from '$lib/prisma';
const newUserHandle: Handle = async function({event, resolve}) {
prisma.user.findUnique(
const result = await resolve(event);
console.log(result);
return result;
};
export const handle: Handle = sequence(
handleClerk(CLERK_SECRET_KEY, {
debug: true,
protectedPaths: ['/admin'],
signInUrl: '/sign-in',
}),
newUserHandle
)

View File

@@ -1,6 +0,0 @@
<script lang="ts">
</script>
<div>
<slot />
</div>

View File

@@ -1,27 +0,0 @@
<script lang="ts">
import { OneOnOneBracket } from "$lib/match";
export let bracket: OneOnOneBracket;
</script>
<div>
Bracket: {bracket.id}
<div>
Configuration:
<div>
Type: {bracket.config.bracketType}
</div>
<div>
Games Per Set: {bracket.config.gamesPerSet}
</div>
</div>
<div>
{#each bracket.setLookup as round, i }
<div>
Round {i}
{#each round as set }
{/each}
</div>
{/each}
</div>
</div>

View File

@@ -1,13 +0,0 @@
<script lang="ts">
import type { OneOnOneSet } from "$lib/match";
let set: OneOnOneSet;
</script>
<div>
<div>
{set.p1.name}
</div>
<div>
{set.p2.name}
</div>
</div>

View File

@@ -1,81 +0,0 @@
export class User {
id?: string;
name: string;
sponsor?: string;
roles: Array<string>;
profile: UserProfile;
constructor(name: string) {
this.name = name;
this.roles = new Array<string>();
this.profile = {};
}
}
export class UserProfile {
}
export interface Tournament {
id: string;
title: string;
slug?: string;
tournamentCreator: User;
tournamentAdmins: Array<User>;
events: Array<Event>;
}
export interface Event {
}
export enum PhaseType {
DOUBLE_ELIM = "Double Elimination",
SINGLE_ELIM = "Single Elimination",
ROUND_ROBIN = "Round Robin",
LADDER = "Ladder",
SWISS = "Swiss",
}
export interface Phase {
id: string;
brackets: Array<Bracket>;
config: PhaseConfig;
}
export interface Bracket {
}
export class PhaseConfig {
phaseType: PhaseType;
winningSetCount: number;
numPhaseWinners: number;
constructor(phaseType?: PhaseType, winningSetCount?: number, numPhaseWinners?: number) {
if(phaseType)
this.phaseType = phaseType;
else
this.phaseType = PhaseType.DOUBLE_ELIM;
if(winningSetCount)
this.winningSetCount = winningSetCount;
else
this.winningSetCount = 2;
if(numPhaseWinners)
this.numPhaseWinners = numPhaseWinners;
else
this.numPhaseWinners = 1;
}
}
export interface MatchIdentity {
name: string;
}
export interface Player extends MatchIdentity {
id: string;
}
export interface PlayerGroup extends MatchIdentity {
groupId: string;
players: Array<Player>;
}

6
src/lib/prisma.ts Normal file
View File

@@ -0,0 +1,6 @@
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
export default prisma;

View File

@@ -1,5 +1,32 @@
<script lang="ts">
import "../app.css";
import UserButton from 'clerk-sveltekit/client/UserButton.svelte'
import SignedIn from 'clerk-sveltekit/client/SignedIn.svelte'
import SignedOut from 'clerk-sveltekit/client/SignedOut.svelte'
</script>
<slot />
<nav class="fixed bg-slate-600 w-64 left-0 p-3 text-white h-screen z-20 flex flex-col">
<ul>
<li>Home</li>
<li>Events</li>
<li>Communities</li>
<li>Leagues</li>
<li class="relative end-0">
</li>
</ul>
<div class="mb-0">
<SignedIn>
<UserButton afterSignOutUrl="/" />
</SignedIn>
<SignedOut>
<a href="/sign-in">Sign in</a> <span>|</span> <a href="/sign-up">Sign up</a>
<!-- You could also use <SignInButton mode="modal" /> and <SignUpButton mode="modal" /> here -->
</SignedOut>
</div>
</nav>
<div class="ml-64 p-1">
<div class="container mx-auto">
<slot/>
</div>
</div>

View File

@@ -0,0 +1,9 @@
import prisma from '$lib/prisma';
import type { PageServerLoad } from './$types';
export const load = (async () => {
const response = await prisma.event.count();
return { eventCount: response };
}) satisfies PageServerLoad;

View File

@@ -1,2 +1,8 @@
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
<script lang="ts">
import type { PageData } from "./$types";
export let data: PageData;
</script>
Event Count: {data.eventCount}

View File

@@ -0,0 +1 @@
<p>Site Admin Dashboard</p>

View File

@@ -1,3 +0,0 @@
<script lang="ts">
</script>

View File

@@ -0,0 +1,7 @@
<script lang="ts">
import SignIn from 'clerk-sveltekit/client/SignIn.svelte'
</script>
<div>
<SignIn redirectUrl="/admin" />
</div>

View File

@@ -0,0 +1,7 @@
<script lang="ts">
import SignUp from 'clerk-sveltekit/client/SignUp.svelte'
</script>
<div>
<SignUp redirectUrl="/admin" />
</div>

View File

@@ -0,0 +1,7 @@
<script lang="ts">
</script>
<form action="POST">
</form>

View File

@@ -0,0 +1,12 @@
<script lang="ts">
import UserProfile from "clerk-sveltekit/client/UserProfile.svelte";
</script>
<div class="w-full">
<div class="mx-auto">
<UserProfile/>
</div>
</div>