Add editable option approval flow

This commit is contained in:
TopherMayor
2026-04-30 22:39:51 -07:00
parent 1674930435
commit 1e36d45976
3 changed files with 82 additions and 8 deletions

View File

@@ -704,7 +704,20 @@ function buildRealtimeSnapshot() {
};
}
function createUserOption({ categoryId, name, desc, url, voterName, lat, lng, approved }) {
function normalizeDetails(details) {
if (Array.isArray(details)) {
return details.map((item) => String(item || '').trim()).filter(Boolean);
}
if (typeof details === 'string') {
return details
.split(/\n+/)
.map((item) => item.trim())
.filter(Boolean);
}
return [];
}
function createUserOption({ categoryId, name, desc, url, voterName, lat, lng, approved, details }) {
return {
id: uuidv4(),
seedKey: null,
@@ -718,7 +731,7 @@ function createUserOption({ categoryId, name, desc, url, voterName, lat, lng, ap
addedBy: voterName,
approved,
votes: [],
details: [],
details: normalizeDetails(details),
categoryColor: CATEGORY_META[categoryId]?.color || '#888',
};
}
@@ -877,7 +890,7 @@ app.delete('/api/vote/:optionId', (req, res) => {
});
app.post('/api/options', (req, res) => {
const { categoryId, name, desc, url, lat, lng } = req.body;
const { categoryId, name, desc, url, lat, lng, details } = req.body;
const guest = requireGuestAuth(req, res, req.body);
if (!categoryId || !name) {
@@ -896,6 +909,7 @@ app.post('/api/options', (req, res) => {
voterName: guest.name,
lat,
lng,
details,
approved: false,
});
@@ -915,6 +929,25 @@ app.post('/api/options/:id/approve', (req, res) => {
res.json({ success: true });
});
app.patch('/api/options/:id', (req, res) => {
const option = data.options.find((candidate) => candidate.id === req.params.id);
if (!option) return res.status(404).json({ error: 'Not found' });
const { categoryId, name, desc, url, lat, lng, details, approved } = req.body;
if (categoryId !== undefined) option.categoryId = categoryId;
if (name !== undefined) option.name = String(name || '').trim();
if (desc !== undefined) option.desc = String(desc || '').trim();
if (url !== undefined) option.url = String(url || '').trim() || null;
if (lat !== undefined) option.lat = Number.isFinite(Number(lat)) ? Number(lat) : null;
if (lng !== undefined) option.lng = Number.isFinite(Number(lng)) ? Number(lng) : null;
if (details !== undefined) option.details = normalizeDetails(details);
if (approved !== undefined) option.approved = Boolean(approved);
saveData(data);
broadcast({ type: 'option_updated', option });
res.json({ success: true, option });
});
app.delete('/api/options/:id', (req, res) => {
const optionIndex = data.options.findIndex((candidate) => candidate.id === req.params.id);
if (optionIndex === -1) return res.status(404).json({ error: 'Not found' });