50 lines
3.6 KiB
JavaScript
50 lines
3.6 KiB
JavaScript
// Minimal Planning Center mock for the Band Lineup module: service types, one
|
||||
|
|
// plan today, its team_members (with person+team includes), People birthdates,
|
|||
|
|
// and avatar bytes. Enough to exercise the whole board build.
|
|||
|
|
const http = require('http');
|
|||
|
|
const PORT = Number(process.argv[2] || 24710);
|
|||
|
|
const JPEG = Buffer.from('/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAP//////////////////////////////////////////////////////////////////////////////////////wAALCAABAAEBAREA/8QAFAABAAAAAAAAAAAAAAAAAAAAAP/EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAD8AfwD/2Q==', 'base64');
|
|||
|
|
const TODAY = new Date();
|
|||
|
|
const iso = (d) => d.toISOString();
|
|||
|
|
// One person's birthday lands in this Wed–Tue week (today is a Wed in the test).
|
|||
|
|
const inWeek = new Date(TODAY.getFullYear(), TODAY.getMonth(), TODAY.getDate() + 2);
|
|||
|
|
const bdayInWeek = `1994-${String(inWeek.getMonth()+1).padStart(2,'0')}-${String(inWeek.getDate()).padStart(2,'0')}`;
|
|||
|
|
|
|||
|
|
const PEOPLE = {
|
|||
|
|
p1: { name: 'Lemuel Maldonado', pos: 'Vox 1', team: 'Vocals', bd: '1990-03-04' },
|
|||
|
|
p2: { name: 'Wes Carter', pos: 'Vox 2', team: 'Vocals', bd: null },
|
|||
|
|
p3: { name: 'Jessica Proulx', pos: 'Vox 3', team: 'Vocals', bd: '1992-11-01' },
|
|||
|
|
p4: { name: 'Jeremy Cruz', pos: 'Guitar / Lead', team: 'Band', bd: null },
|
|||
|
|
p5: { name: 'Alex Gaitan', pos: 'Drums', team: 'Band', bd: bdayInWeek }, // celebrating
|
|||
|
|
p6: { name: 'Rosaliz Gomez', pos: 'Piano', team: 'Band', bd: null },
|
|||
|
|
p7: { name: 'George Acosta', pos: 'MC', team: 'Production', bd: null },
|
|||
|
|
p8: { name: 'Not Shown', pos: 'Camera 2', team: 'Video', bd: null }, // team not allowed → filtered out
|
|||
|
|
};
|
|||
|
|
const TEAMS = { Vocals: 't1', Band: 't2', Production: 't3', Video: 't4' };
|
|||
|
|
|
|||
|
|
function send(res, obj) { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify(obj)); }
|
|||
|
|
|
|||
|
|
const server = http.createServer((req, res) => {
|
|||
|
|
const u = new URL(req.url, 'http://x'); const p = u.pathname;
|
|||
|
|
if (p.startsWith('/avatar/')) { res.writeHead(200, { 'Content-Type': 'image/jpeg' }); return res.end(JPEG); }
|
|||
|
|
if (p === '/services/v2/folders') return send(res, { data: [] });
|
|||
|
|
if (p === '/services/v2/service_types') return send(res, { data: [{ id: '1', type: 'ServiceType', attributes: { name: 'Sunday Service' }, relationships: { parent: { data: null } } }] });
|
|||
|
|
if (/^\/services\/v2\/service_types\/1\/plans$/.test(p)) {
|
|||
|
|
if (u.searchParams.get('filter') === 'past') return send(res, { data: [] });
|
|||
|
|
return send(res, { data: [{ id: '100', type: 'Plan', attributes: { sort_date: iso(TODAY), title: 'Taking Thoughts Captive - Part 4', dates: 'September 20, 2026' } }] });
|
|||
|
|
}
|
|||
|
|
if (/^\/services\/v2\/service_types\/1\/plans\/100\/team_members$/.test(p)) {
|
|||
|
|
const data = []; const included = [];
|
|||
|
|
for (const [id, v] of Object.entries(PEOPLE)) {
|
|||
|
|
data.push({ id: `tm-${id}`, type: 'PlanPerson', attributes: { status: 'C', team_position_name: v.pos }, relationships: { person: { data: { type: 'Person', id } }, team: { data: { type: 'Team', id: TEAMS[v.team] } } } });
|
|||
|
|
included.push({ id, type: 'Person', attributes: { full_name: v.name, photo_url: `http://127.0.0.1:${PORT}/avatar/${id}` } });
|
|||
|
|
}
|
|||
|
|
for (const [name, id] of Object.entries(TEAMS)) included.push({ id, type: 'Team', attributes: { name } });
|
|||
|
|
return send(res, { data, included, links: {} });
|
|||
|
|
}
|
|||
|
|
const person = p.match(/^\/people\/v2\/people\/([^/]+)$/);
|
|||
|
|
if (person) { const v = PEOPLE[person[1]]; return send(res, { data: { id: person[1], type: 'Person', attributes: { birthdate: v ? v.bd : null } } }); }
|
|||
|
|
res.writeHead(404); res.end('{}');
|
|||
|
|
});
|
|||
|
|
server.listen(PORT, '127.0.0.1', () => console.log(`[pco-band-mock] on http://127.0.0.1:${PORT}`));
|