Add team creation, team join and debug login screen

This commit is contained in:
2025-08-03 18:58:17 +02:00
parent facb07de5b
commit 36e8ef41bf
15 changed files with 735 additions and 11 deletions
+11
View File
@@ -0,0 +1,11 @@
import prisma from '~~/lib/prisma';
export default defineEventHandler(() => {
return prisma.user.findMany({
select: {
id: true,
name: true,
email: true
}
});
});
+95
View File
@@ -0,0 +1,95 @@
import prisma from '~~/lib/prisma';
async function getOwnHunts(userId: number | undefined) {
if (!userId) {
return null;
}
return prisma.hunt.findMany({
select: {
id: true,
name: true,
description: true,
createdAt: true,
start: true,
end: true,
_count: {
select: {
teams: true,
quests: true
}
},
creator: {
select: {
name: true,
id: true
}
}
},
where: {
deletedAt: null,
teams: {
some: {
OR: [
{
ownerId: userId
},
{
members: {
some: {
memberId: userId
}
}
}
]
}
}
}
});
}
export default defineEventHandler(async (event) => {
const user = await getUserSession(event);
const userId = user.user?.id;
const own = await getOwnHunts(userId);
const others = await prisma.hunt.findMany({
select: {
id: true,
name: true,
description: true,
createdAt: true,
start: true,
end: true,
_count: {
select: {
teams: true,
quests: true
}
},
creator: {
select: {
name: true,
id: true
}
}
},
where: {
deletedAt: null,
OR: [
{
start: {
gt: new Date()
}
},
{
start: null
}
],
allowJoin: true,
id: {
notIn: own?.map((h) => h.id) ?? []
}
}
});
return { own, others };
});
+4 -2
View File
@@ -51,7 +51,8 @@ export default defineEventHandler(async (event) => {
teams: {
select: {
id: true,
name: true
name: true,
password: true
},
where: {
OR: [
@@ -140,7 +141,7 @@ export default defineEventHandler(async (event) => {
const { teams, members, quests, ...hunt } = _hunt;
const isMember = hunt.creator.id === userId || members.length > 0;
const ownTeam = teams.length > 0 ? teams[0].id : null;
const ownTeam = teams.length > 0 ? teams[0] : null;
const mappedQuests = quests.map(({ answers, ...q }) => ({
...q,
@@ -156,6 +157,7 @@ export default defineEventHandler(async (event) => {
return {
isMember,
ownTeam,
loggedIn: !!user.user,
totalScore: ownTeam !== null ? totalScore : undefined,
quests: mappedQuests,
...hunt
+71
View File
@@ -0,0 +1,71 @@
import { requireUserSession } from '#imports';
import { useValidatedBody, useValidatedParams, z, zh } from 'h3-zod';
import prisma from '~~/lib/prisma';
export default defineEventHandler(async (event) => {
const { huntId } = await useValidatedParams(
event,
z.object({
huntId: zh.numAsString
})
);
const user = await requireUserSession(event);
const userId = user.user.id;
const existingTeam = await prisma.huntTeam.findFirst({
select: {
id: true
},
where: {
huntId,
OR: [
{
ownerId: userId
},
{
members: {
some: {
memberId: userId
}
}
}
]
}
});
if (existingTeam) {
throw createError({ status: 409, statusText: 'You already have a team!' });
}
const { team: teamId, password } = await useValidatedBody(
event,
z.object({
team: z.number().min(1),
password: z.string().max(256)
})
);
const team = await prisma.huntTeam.findUnique({
where: {
huntId,
id: teamId,
password
},
select: { id: true }
});
if (!team) {
throw createError({
status: 404,
statusText: 'Team not found or invalid password!'
});
}
await prisma.teamMember.create({
data: {
memberId: userId,
teamId
}
});
return { success: true };
});
+63
View File
@@ -0,0 +1,63 @@
import { useValidatedBody, useValidatedParams, z, zh } from 'h3-zod';
import prisma from '~~/lib/prisma';
import { randomBytes } from 'node:crypto';
export default defineEventHandler(async (event) => {
const { huntId } = await useValidatedParams(
event,
z.object({
huntId: zh.numAsString
})
);
const user = await requireUserSession(event);
const userId = user.user.id;
console.log(user);
const existingTeam = await prisma.huntTeam.findFirst({
select: {
id: true
},
where: {
huntId,
OR: [
{
ownerId: userId
},
{
members: {
some: {
memberId: userId
}
}
}
]
}
});
if (existingTeam) {
throw createError({ status: 409, statusText: 'You already have a team!' });
}
const { name, description } = await useValidatedBody(
event,
z.object({
name: z.string().max(256).min(3).trim(),
description: z.string().max(256).trim().optional()
})
);
const password = randomBytes(3).toString('hex');
const team = await prisma.huntTeam.create({
data: {
name,
description,
ownerId: userId,
password,
huntId
}
});
return { team };
});
+34
View File
@@ -0,0 +1,34 @@
import { useValidatedParams, z, zh } from 'h3-zod';
import prisma from '~~/lib/prisma';
export default defineEventHandler(async (event) => {
const { huntId } = await useValidatedParams(
event,
z.object({
huntId: zh.numAsString
})
);
return prisma.huntTeam.findMany({
where: {
huntId
},
select: {
id: true,
name: true,
description: true,
owner: {
select: {
name: true
}
},
_count: {
select: {
members: true
}
}
},
orderBy: {
name: 'asc'
}
});
});