Report-an-ad dialog: site dialog with no default reason (was a native prompt pre-filled with "broken")

Campaign #27 (house AdRevSplit text ad) was reported "broken" with no note while the target framed
and loaded fine; the report dialog was prompt() with 'broken' as the default value, so one stray OK
filed it. Now IAP.ask with an explicit, validated reason and an optional note; common.js tag bumped
on all pages.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-16 10:21:53 -05:00
parent 69d672665c
commit 616f328db5
17 changed files with 27 additions and 21 deletions
+11 -5
View File
@@ -110,12 +110,18 @@ window.IAP = (function () {
}
// Render one served ad into #<elId>. Silent if no inventory.
// report an ad (auto-approved ads need a member-facing flag → admin notified)
function reportAd(campaignId) {
// 2026-09-16: was a native prompt() with 'broken' pre-filled, so a stray tap on OK filed a
// "broken" report with no note (campaign #27). Now the site dialog, no default, reason validated.
const REPORT_REASONS = ['broken', 'inappropriate', 'spam', 'scam', 'other'];
async function reportAd(campaignId) {
if (!campaignId) return;
const reason = (prompt('Report this ad. Reason: broken, inappropriate, spam, scam, or other', 'broken') || '').trim().toLowerCase();
if (!reason) return;
const note = prompt('Anything to add? (optional)') || '';
fetch('/api/report-ad', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ campaignId, reason, note }) })
const raw = await ask({ title: 'Report this ad', text: 'What is wrong with it? Type one: broken, inappropriate, spam, scam, or other.', placeholder: 'e.g. broken', ok: 'Next' });
if (raw === null) return;
const reason = String(raw || '').trim().toLowerCase();
if (!REPORT_REASONS.includes(reason)) { status('Pick one of: broken, inappropriate, spam, scam, or other.', 'bad'); return; }
const note = await ask({ title: 'Report: ' + reason, text: 'Tell the admin what you saw, so it can be fixed. Optional, but it helps.', type: 'textarea', ok: 'Send report' });
if (note === null) return;
fetch('/api/report-ad', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ campaignId, reason, note: String(note || '').slice(0, 500) }) })
.then(() => status('Thanks — this ad was reported to the admin for review.', 'ok'))
.catch(() => status('Could not send the report. Try again.', 'bad'));
}