feat(hunt): add public flag to hunts and implement hunt creation page

- Add 'public' boolean column to Hunt model with default true
- Update hunt admin UI to toggle 'public' flag
- Implement new hunt creation page with form supporting all hunt properties
- Add sidebar navigation item for hunt creation for authorized users
- Adjust home API to filter hunts by public flag only
This commit is contained in:
2026-07-30 23:33:34 +02:00
parent aa4632cab8
commit 77becc453e
11 changed files with 320 additions and 16 deletions
@@ -29,6 +29,7 @@ export default defineEventHandler(async (event) => {
description_de: true,
description_en: true,
virtual: true,
public: true,
start: true,
end: true,
allowJoin: true,
+3 -2
View File
@@ -21,8 +21,9 @@ export default defineEventHandler(async (event) => {
description_de: z.string().min(1).max(1000).trim(),
description_en: z.string().min(1).max(1000).trim(),
virtual: z.boolean(),
start: z.iso.datetime(),
end: z.iso.datetime(),
public: z.boolean(),
start: z.iso.datetime().nullable(),
end: z.iso.datetime().nullable(),
allowJoin: z.boolean(),
revealQuests: z.boolean(),
revealAnswers: z.boolean()
+47
View File
@@ -0,0 +1,47 @@
import { useValidatedBody, z } from 'h3-zod';
import prisma from '~~/lib/prisma';
export default defineEventHandler(async (event) => {
const user = await requireUserSession(event);
if (user.user.role !== 'CREATOR' && user.user.role !== 'ADMIN') {
throw createError({
statusCode: 403,
statusMessage: 'Not allowed!'
});
}
const body = await useValidatedBody(
event,
z.object({
name_de: z.string().min(1).max(256).trim(),
name_en: z.string().min(1).max(256).trim(),
description_de: z.string().max(1000).trim().default(''),
description_en: z.string().max(1000).trim().default(''),
virtual: z.boolean().default(false),
start: z.iso.datetime().nullish(),
end: z.iso.datetime().nullish(),
allowJoin: z.boolean().default(false),
revealQuests: z.boolean().default(false),
revealAnswers: z.boolean().default(false),
public: z.boolean().default(true)
})
);
return await prisma.hunt.create({
data: {
...body,
creatorId: user.user.id,
members: {
create: {
memberId: user.user.id
}
}
},
select: {
id: true,
name_de: true,
name_en: true
}
});
});