tractatus/scripts/fix-admin-event-handlers.js
TheFlow 2298d36bed fix(submissions): restructure Economist package and fix article display
- Create Economist SubmissionTracking package correctly:
  * mainArticle = full blog post content
  * coverLetter = 216-word SIR— letter
  * Links to blog post via blogPostId
- Archive 'Letter to The Economist' from blog posts (it's the cover letter)
- Fix date display on article cards (use published_at)
- Target publication already displaying via blue badge

Database changes:
- Make blogPostId optional in SubmissionTracking model
- Economist package ID: 68fa85ae49d4900e7f2ecd83
- Le Monde package ID: 68fa2abd2e6acd5691932150

Next: Enhanced modal with tabs, validation, export

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 08:47:42 +13:00

71 lines
2.2 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
/**
* Fix inline event handlers in admin JS files
* Replace with data attributes and event delegation
*/
const fs = require('fs');
const path = require('path');
const files = [
'public/js/admin/audit-analytics.js',
'public/js/admin/claude-md-migrator.js',
'public/js/admin/dashboard.js',
'public/js/admin/project-editor.js',
'public/js/admin/project-manager.js',
'public/js/admin/rule-editor.js',
'public/js/admin/rule-manager.js'
];
let totalFixed = 0;
files.forEach(file => {
const filePath = path.join(__dirname, '..', file);
let content = fs.readFileSync(filePath, 'utf8');
let fileFixed = 0;
// Pattern 1: onclick="this.parentElement.remove()"
const pattern1 = /\s*onclick="this\.parentElement\.remove\(\)"/g;
const matches1 = (content.match(pattern1) || []).length;
content = content.replace(pattern1, ' data-action="remove-parent"');
fileFixed += matches1;
// Pattern 2: onclick="functionName('arg')" or onclick="functionName('arg', 'arg2')"
const pattern2 = /onclick="([a-zA-Z.]+)\(([^)]+)\)"/g;
content = content.replace(pattern2, (match, funcName, args) => {
fileFixed++;
// Extract arguments
const argList = args.split(',').map(a => a.trim().replace(/['"]/g, ''));
// Create data attributes
let dataAttrs = `data-action="${funcName.replace('window.', '').replace('projectEditor.', '')}"`;
argList.forEach((arg, i) => {
if (arg.startsWith('${')) {
// Template literal - keep as is
dataAttrs += ` data-arg${i}="${arg}"`;
} else {
// Plain value
dataAttrs += ` data-arg${i}="${arg}"`;
}
});
return dataAttrs;
});
// Pattern 3: onchange="functionName(...)"
const pattern3 = /onchange="([a-zA-Z.]+)\(([^)]+)\)"/g;
content = content.replace(pattern3, (match, funcName, args) => {
fileFixed++;
return `data-change-action="${funcName}" data-change-args="${args}"`;
});
if (fileFixed > 0) {
fs.writeFileSync(filePath, content);
console.log(`${file}: Fixed ${fileFixed} event handler(s)`);
totalFixed += fileFixed;
}
});
console.log(`\n✅ Total event handlers fixed: ${totalFixed}`);
console.log('\n⚠ Next: Add event delegation listeners to each file\n');