120 lines
4.1 KiB
JavaScript
120 lines
4.1 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.campaignPublicRouter = void 0;
|
|
const express_1 = require("express");
|
|
const campaigns_service_1 = require("./campaigns.service");
|
|
const database_1 = require("../../../config/database");
|
|
const redis_1 = require("../../../config/redis");
|
|
const router = (0, express_1.Router)();
|
|
exports.campaignPublicRouter = router;
|
|
// GET /api/campaigns/public — list all active campaigns (public)
|
|
router.get('/public', async (_req, res, next) => {
|
|
try {
|
|
const campaigns = await campaigns_service_1.campaignsService.findActiveCampaigns();
|
|
res.json(campaigns);
|
|
}
|
|
catch (err) {
|
|
next(err);
|
|
}
|
|
});
|
|
// GET /api/campaigns/:slug/details — public campaign data (ACTIVE only)
|
|
router.get('/:slug/details', async (req, res, next) => {
|
|
try {
|
|
const slug = req.params.slug;
|
|
const campaign = await campaigns_service_1.campaignsService.findBySlugPublic(slug);
|
|
res.json(campaign);
|
|
}
|
|
catch (err) {
|
|
next(err);
|
|
}
|
|
});
|
|
// GET /api/campaigns/:slug/related — related campaigns + upcoming shifts
|
|
router.get('/:slug/related', async (req, res, next) => {
|
|
try {
|
|
const slug = req.params.slug;
|
|
const cacheKey = `campaign:related:${slug}`;
|
|
// Check cache
|
|
try {
|
|
const cached = await redis_1.redis.get(cacheKey);
|
|
if (cached) {
|
|
res.json(JSON.parse(cached));
|
|
return;
|
|
}
|
|
}
|
|
catch { /* cache miss */ }
|
|
// Find current campaign
|
|
const campaign = await database_1.prisma.campaign.findFirst({
|
|
where: { slug, status: 'ACTIVE' },
|
|
select: { id: true, targetGovernmentLevels: true },
|
|
});
|
|
if (!campaign) {
|
|
res.json({ campaigns: [], shifts: [] });
|
|
return;
|
|
}
|
|
// Related campaigns: same gov levels, exclude current, limit 3
|
|
const relatedCampaigns = await database_1.prisma.campaign.findMany({
|
|
where: {
|
|
status: 'ACTIVE',
|
|
id: { not: campaign.id },
|
|
...(campaign.targetGovernmentLevels.length > 0 && {
|
|
targetGovernmentLevels: { hasSome: campaign.targetGovernmentLevels },
|
|
}),
|
|
},
|
|
select: {
|
|
id: true,
|
|
slug: true,
|
|
title: true,
|
|
description: true,
|
|
_count: { select: { emails: true } },
|
|
},
|
|
orderBy: { createdAt: 'desc' },
|
|
take: 3,
|
|
});
|
|
// Related shifts: upcoming, limit 3
|
|
const today = new Date();
|
|
today.setHours(0, 0, 0, 0);
|
|
const relatedShifts = await database_1.prisma.shift.findMany({
|
|
where: {
|
|
date: { gte: today },
|
|
status: 'OPEN',
|
|
},
|
|
select: {
|
|
id: true,
|
|
title: true,
|
|
date: true,
|
|
startTime: true,
|
|
location: true,
|
|
maxVolunteers: true,
|
|
_count: { select: { signups: true } },
|
|
},
|
|
orderBy: { date: 'asc' },
|
|
take: 3,
|
|
});
|
|
const result = {
|
|
campaigns: relatedCampaigns.map(c => ({
|
|
id: c.id,
|
|
slug: c.slug,
|
|
title: c.title,
|
|
description: c.description?.slice(0, 150) ?? null,
|
|
emailCount: c._count.emails,
|
|
})),
|
|
shifts: relatedShifts.map(s => ({
|
|
id: s.id,
|
|
title: s.title,
|
|
startTime: `${s.date.toISOString().split('T')[0]}T${s.startTime}:00`,
|
|
location: s.location,
|
|
currentVolunteers: s._count.signups,
|
|
maxVolunteers: s.maxVolunteers,
|
|
})),
|
|
};
|
|
try {
|
|
await redis_1.redis.setex(cacheKey, 300, JSON.stringify(result));
|
|
}
|
|
catch { /* non-critical */ }
|
|
res.json(result);
|
|
}
|
|
catch (err) {
|
|
next(err);
|
|
}
|
|
});
|
|
//# sourceMappingURL=campaigns-public.routes.js.map
|