allow for a starting date and hidden hunt if it hasnt started
All checks were successful
Build Images and Deploy / Update-PROD-Stack (push) Successful in 31s

This commit is contained in:
2026-03-19 14:39:06 -04:00
parent 79c0b883f7
commit 34b3a4cbd0
12 changed files with 107 additions and 30 deletions

View File

@@ -36,7 +36,7 @@ router.get('/hunts/new', (req, res) => {
// Create hunt
router.post('/hunts', (req, res) => {
const { name, short_name, description, package_count, expiry_date } = req.body;
const { name, short_name, description, package_count, expiry_date, start_date, hidden_until_start } = req.body;
// Validation
if (!name || !short_name || !package_count) {
@@ -70,7 +70,7 @@ router.post('/hunts', (req, res) => {
}
try {
const huntId = Hunts.create(name, shortName, description, count, expiry_date, req.session.userId);
const huntId = Hunts.create(name, shortName, description, count, expiry_date, req.session.userId, start_date, hidden_until_start);
req.session.flash = { type: 'success', message: `Hunt "${name}" created with ${count} packages.` };
res.redirect(`/admin/hunts/${huntId}`);
} catch (err) {
@@ -102,12 +102,12 @@ router.get('/hunts/:id/edit', requireHuntAccess, (req, res) => {
router.post('/hunts/:id/edit', requireHuntAccess, (req, res) => {
const hunt = req.hunt;
const { name, description, expiry_date } = req.body;
const { name, description, expiry_date, start_date, hidden_until_start } = req.body;
if (!name || !name.trim()) {
return res.render('admin/edit-hunt', { title: `Edit: ${hunt.name}`, hunt: { ...hunt, ...req.body }, error: 'Hunt name is required.' });
}
Hunts.update(hunt.id, name.trim(), (description || '').trim(), expiry_date);
Hunts.update(hunt.id, name.trim(), (description || '').trim(), expiry_date, start_date, hidden_until_start);
req.session.flash = { type: 'success', message: 'Hunt updated successfully.' };
res.redirect(`/admin/hunts/${hunt.id}`);
});

View File

@@ -10,10 +10,16 @@ router.get('/hunt/:shortName', (req, res) => {
return res.status(404).render('error', { title: 'Not Found', message: 'Hunt not found.' });
}
// Block access if hidden and not started (unless admin/organizer)
if (Hunts.isHidden(hunt) && !(req.session && (req.session.isAdmin || req.session.isOrganizer))) {
return res.status(404).render('error', { title: 'Not Found', message: 'Hunt not found.' });
}
const packages = Packages.getByHunt(hunt.id);
const isExpired = Hunts.isExpired(hunt);
const hasStarted = Hunts.hasStarted(hunt);
res.render('hunt/profile', { title: hunt.name, hunt, packages, isExpired });
res.render('hunt/profile', { title: hunt.name, hunt, packages, isExpired, hasStarted });
});
// ─── Hunt leaderboard ─────────────────────────────────────
@@ -23,6 +29,10 @@ router.get('/hunt/:shortName/leaderboard', (req, res) => {
return res.status(404).render('error', { title: 'Not Found', message: 'Hunt not found.' });
}
if (Hunts.isHidden(hunt) && !(req.session && (req.session.isAdmin || req.session.isOrganizer))) {
return res.status(404).render('error', { title: 'Not Found', message: 'Hunt not found.' });
}
const perPage = 25;
const page = Math.max(1, parseInt(req.query.page) || 1);
const totalCount = Hunts.getLeaderboardCount(hunt.id);
@@ -128,7 +138,8 @@ router.post('/player/:username/password', requireAuth, (req, res) => {
// ─── Browse all hunts ─────────────────────────────────────
router.get('/hunts', (req, res) => {
const hunts = Hunts.getAll();
const allHunts = Hunts.getAll();
const hunts = allHunts.filter(h => !Hunts.isHidden(h));
res.render('hunt/list', { title: 'All Hunts', hunts });
});